diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..7ba64b0 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "external/Catch2"] + path = external/Catch2 + url = https://github.com/catchorg/Catch2.git +[submodule "external/MAMAP"] + path = external/MAMAP + url = https://github.com/JoshuaSBrown/MAMAP.git diff --git a/.travis.yml b/.travis.yml index 7b97a17..fddda62 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ dist: xenial addons: apt: update: true + packages: libeigen3-dev language: cpp @@ -17,6 +18,7 @@ jobs: compiler: gcc script: ./scripts/deploy.bash apt: + packages: libeigen3-dev packages: gcov packages: lcov diff --git a/CMakeLists.txt b/CMakeLists.txt index c998559..d71359a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,120 +1,132 @@ -cmake_minimum_required (VERSION 2.8) -project (calc_J) +cmake_minimum_required (VERSION 3.14) +project (catnip VERSION 2.0.0) ############################################################################## # Defining options ############################################################################## -option(DOWNLOAD_TUTORIAL_FILES "Download tutorial files" OFF) -option(ENABLE_INTEGRATION_TESTS "Enable integration tests" OFF) -option(ENABLE_TESTS "Enable tests" OFF) +option(ENABLE_TESTS "Enable testing" OFF) +option(DOWNLOAD_TUTORIAL_FILES "Download tutorial files" ${ENABLE_TESTS}) +option(ENABLE_INTEGRATION_TESTING "Enable integration tests" ${ENABLE_TESTS}) +option(ENABLE_UNIT_TESTING "Enable unit tests" ${ENABLE_TESTS}) +option(ENABLE_PROFILING "Enable profiling" OFF) option(CODE_COVERAGE "Enable coverage reporting" OFF) +############################################################################## +# Override default options +############################################################################## +set(DOWNLOAD_TUTORIAL_FILES ${ENABLE_TESTS} CACHE STRING "Download tutorial files" FORCE) +set(ENABLE_INTEGRATION_TESTING ${ENABLE_TESTS} CACHE STRING "Enable integration tests" FORCE) +set(ENABLE_UNIT_TESTING ${ENABLE_TESTS} CACHE STRING "Enable unit tests" FORCE) + ############################################################################## # Defining settings ############################################################################## -set(calcJ_VERSION_MAJOR 1 ) -set(calcJ_VERSION_MINOR 9 ) -set(calcJ_YEAR_PUBLISHED 2018 ) -set(calcJ_AUTHOR_SURNAME "\"Brown\"" ) -set(calcJ_AUTHOR_INITIALS "\"J. S.\"" ) -set(calcJ_TITLE "\"CATNIP\"") -set(calcJ_URL "\"https://github.com/JoshuaSBrown/QC_Tools\"" ) +set(catnip_YEAR_PUBLISHED 2018 ) +set(catnip_AUTHOR_SURNAME "\"Brown\"" ) +set(catnip_AUTHOR_INITIALS "\"J. S.\"" ) +set(catnip_TITLE "\"CATNIP\"") +set(catnip_URL "\"https://github.com/JoshuaSBrown/QC_Tools\"" ) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(COVERAGE_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage") set(COMMON_LIBRARIES stdc++ m) -set(LOG_LEVEL 0 CACHE INT "Choose the log level" ) +set(LOG_LEVEL 0 CACHE STRING "Choose the log level" ) # Prevents multiple file extensions from being appended one after the other # important for using gcov .o.gcno or .cpp.gcno now will be .gcno set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE 1) -set(CMAKE_CXX_FLAGS "-Wall -Wextra -std=c++11 -pedantic -Werror") +set(CMAKE_CXX_FLAGS "-Wall -std=c++11 -Werror") + +############################################################################## +# Check for Dependencies +############################################################################## + +find_package(mamap REQUIRED) +if( NOT ${mamap_FOUND} ) + include(${catnip_SOURCE_DIR}/cmake/InstallMAMAP.cmake) +else() + message(STATUS "found system installed mamap will not download") +endif() ############################################################################## # Configuring header file with cmake variables ############################################################################## # Configure header file to pass some of the CMake settings to the source code configure_file( - "${PROJECT_SOURCE_DIR}/src/libcatnip/calcJconfig.hpp.in" - "${PROJECT_SOURCE_DIR}/src/libcatnip/calcJconfig.hpp" + "${catnip_SOURCE_DIR}/src/libcatnip/catnip_config.hpp.in" + "${catnip_SOURCE_DIR}/src/libcatnip/catnip_config.hpp" ) ############################################################################## # Finding dependencies ############################################################################## # Find bash it is important for testing using scripts -find_program (BASH_PROGRAM bash) find_library (GCOV gcov) +#find_package (Eigen3 3.3 REQUIRED NO_MODULE) +#if (TARGET Eigen3::Eigen) +# message("-- Eigen found") +#endif(TARGET Eigen3::Eigen) add_definitions(-DLOG_LEVEL=${LOG_LEVEL}) +############################################################################## +# Setting up profiling +############################################################################## +if(${ENABLE_PROFILING}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg") +endif() ############################################################################## # Setting up testing ############################################################################## -if(ENABLE_INTEGRATION_TESTS) - if(EXISTS "${PROJECT_SOURCE_DIR}/GAUSSIANFILES") - message("GAUSSIANFILES found will not download") +message("ENable tests ${ENABLE_TESTS} and integration ${ENABLE_INTEGRATION_TESTING}") +if(${ENABLE_INTEGRATION_TESTING}) + if(EXISTS "${catnip_SOURCE_DIR}/GAUSSIANFILES") + message(STATUS "GAUSSIANFILES found will not download") set(DOWNLOAD_TUTORIAL_FILES OFF) - else(EXISTS "${PROJECT_SOURCE_DIR}/GAUSSIANFILES") - message("GAUSSIANFILES not found will download") - set(DOWNLOAD_TUTORIAL_FILES ON) - endif(EXISTS "${PROJECT_SOURCE_DIR}/GAUSSIANFILES") -endif() - -if(DOWNLOAD_TUTORIAL_FILES) - message("Downloading gaussian tutorial files") - execute_process(COMMAND ${PROJECT_SOURCE_DIR}/scripts/test_suite_install.bash "${PROJECT_SOURCE_DIR}" ) + else(EXISTS "${catnip_SOURCE_DIR}/GAUSSIANFILES") + message(STATUS "GAUSSIANFILES not found will attempt to download") + include(${catnip_SOURCE_DIR}/cmake/InstallGdown.cmake) + endif(EXISTS "${catnip_SOURCE_DIR}/GAUSSIANFILES") endif() -if(ENABLE_TESTS OR ENABLE_INTEGRATION_TESTS) +if(${ENABLE_UNIT_TESTING} OR ${ENABLE_INTEGRATION_TESTING}) + find_package(Catch2 2.11.1) + if( NOT ${Catch2_FOUND} ) + include(${catnip_SOURCE_DIR}/cmake/InstallCatch2.cmake) + else() + message(STATUS "found system installed Catch2 will not download") + endif() enable_testing() - add_subdirectory("${PROJECT_SOURCE_DIR}/src/tests") -endif() + include(Catch) + include(ParseAndAddCatchTests) -if (ENABLE_INTEGRATION_TESTS) - file( COPY "${PROJECT_SOURCE_DIR}/GAUSSIANFILES/90_unordered/90_pair.log" - DESTINATION "${PROJECT_BINARY_DIR}/GAUSSIANFILES/90_unordered") - file( COPY "${PROJECT_SOURCE_DIR}/GAUSSIANFILES/90_unordered/90_pair.pun" - DESTINATION "${PROJECT_BINARY_DIR}/GAUSSIANFILES/90_unordered") - - file( COPY "${PROJECT_SOURCE_DIR}/GAUSSIANFILES/30_unordered/30_pair.pun" - DESTINATION "${PROJECT_BINARY_DIR}/GAUSSIANFILES/30_unordered") - file( COPY "${PROJECT_SOURCE_DIR}/GAUSSIANFILES/30_unordered/ref.pun" - DESTINATION "${PROJECT_BINARY_DIR}/GAUSSIANFILES/30_unordered") - file( COPY "${PROJECT_SOURCE_DIR}/GAUSSIANFILES/30_unordered/30_2.pun" - DESTINATION "${PROJECT_BINARY_DIR}/GAUSSIANFILES/30_unordered") -endif() + if (${ENABLE_INTEGRATION_TESTING}) + file( COPY "${catnip_SOURCE_DIR}/GAUSSIANFILES/90_unordered/90_pair.log" + DESTINATION "${catnip_BINARY_DIR}/GAUSSIANFILES/90_unordered") + file( COPY "${catnip_SOURCE_DIR}/GAUSSIANFILES/90_unordered/90_pair.pun" + DESTINATION "${catnip_BINARY_DIR}/GAUSSIANFILES/90_unordered") -if (ENABLE_TESTS) - file( COPY "${PROJECT_SOURCE_DIR}/src/tests/testfile.pun" - DESTINATION "${PROJECT_BINARY_DIR}/src/tests") - file( COPY "${PROJECT_SOURCE_DIR}/src/tests/testfile.log" - DESTINATION "${PROJECT_BINARY_DIR}/src/tests") -endif() + file( COPY "${catnip_SOURCE_DIR}/GAUSSIANFILES/30_unordered/30_pair.pun" + DESTINATION "${catnip_BINARY_DIR}/GAUSSIANFILES/30_unordered") + file( COPY "${catnip_SOURCE_DIR}/GAUSSIANFILES/30_unordered/ref.pun" + DESTINATION "${catnip_BINARY_DIR}/GAUSSIANFILES/30_unordered") + file( COPY "${catnip_SOURCE_DIR}/GAUSSIANFILES/30_unordered/30_2.pun" + DESTINATION "${catnip_BINARY_DIR}/GAUSSIANFILES/30_unordered") + endif() + + if (${ENABLE_UNIT_TESTING}) + file( COPY "${catnip_SOURCE_DIR}/src/tests/testfile.pun" + DESTINATION "${catnip_BINARY_DIR}/src/tests") + file( COPY "${catnip_SOURCE_DIR}/src/tests/testfile.log" + DESTINATION "${catnip_BINARY_DIR}/src/tests") + endif() +endif() ############################################################################## # Compiling build tree/paths ############################################################################## -# Add the binary tree to the search path for include files -# so that we will find calcJconfig.hpp -include_directories("${PROJECT_BINARY_DIR}/src") -include_directories("${PROJECT_SOURCE_DIR}/src/libcatnip") -include_directories("${PROJECT_SOURCE_DIR}/src/libcatnip/io/arguments/properties") -include_directories("${PROJECT_SOURCE_DIR}/src/libcatnip/io/arguments") -include_directories("${PROJECT_SOURCE_DIR}/src/libcatnip/io/file_readers") -include_directories("${PROJECT_SOURCE_DIR}/src/libcatnip/io") - -link_directories("${PROJECT_SOURCE_DIR}/src/libcatnip/io/arguments/properties") -link_directories("${PROJECT_SOURCE_DIR}/src/libcatnip/io/arguments") -link_directories("${PROJECT_SOURCE_DIR}/src/libcatnip/io/file_readers") -link_directories("${PROJECT_SOURCE_DIR}/src/libcatnip/io") -link_directories("${PROJECT_SOURCE_DIR}/src/libcatnip") - -add_subdirectory("${PROJECT_SOURCE_DIR}/src/libcatnip") - -############################################################################## -# Creating calc_J and setting up code coverage if on -############################################################################## -add_executable(calc_J src/tools/main.cpp) -if(CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - target_link_libraries(calc_J gcov) - set_source_files_properties( src/tools/main.cpp PROPERTIES COMPILE_FLAGS ${COVERAGE_FLAGS}) -endif(CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") -target_link_libraries(calc_J libcatnip ${COMMON_LIBRARIES}) -install( TARGETS calc_J DESTINATION bin) +add_subdirectory("${catnip_SOURCE_DIR}/src") + + diff --git a/cmake/InstallCatch2.cmake b/cmake/InstallCatch2.cmake new file mode 100644 index 0000000..687e0f9 --- /dev/null +++ b/cmake/InstallCatch2.cmake @@ -0,0 +1,11 @@ +# If Catch2 is not found, instead use the git submodule +if (NOT EXISTS ${catnip_CURRENT_SOURCE_DIR}/external/Catch2/single_include) + # Unable to find the header files for Catch2 or they don't exist + message(STATUS "Downloading Catch2 submodule.") + + # Clone the submodule + execute_process(COMMAND git submodule update --init --force -- external/Catch2 WORKING_DIRECTORY ${catnip_SOURCE_DIR}) +endif() + +add_subdirectory(${catnip_SOURCE_DIR}/external/Catch2) +list(APPEND CMAKE_MODULE_PATH "${catnip_SOURCE_DIR}/external/Catch2/contrib") diff --git a/cmake/InstallGdown.cmake b/cmake/InstallGdown.cmake new file mode 100644 index 0000000..d1b5f7f --- /dev/null +++ b/cmake/InstallGdown.cmake @@ -0,0 +1,29 @@ + +if(NOT EXISTS "${CMAKE_SOURCE_DIR}/GAUSSIANFILES") + find_program(GDOWN gdown ~/.local/bin) + + if( NOT GDOWN) + find_program(PIP NAMES pip pip3 PATHS ~/.local/bin) + if( NOT PIP) + message(FATAL_ERROR "Unable to download tutorial files with gdown, tutorial" + "files are needed to run both the tutorials and the integration tests," + "unable to locate pip to install gdown, please install pip, or install gdown" + "through some other means.") + else() + message("Pip is ") + execute_process(COMMAND ${PIP} "install" "--user" "--upgrade" "pip") + execute_process(COMMAND ${PIP} "install" "--user" "gdown" ) + endif() + find_program(GDOWN gdown ~/.local/bin) + + endif() + + if( GDOWN ) + find_program(UNZIP unzip) + execute_process(COMMAND ${GDOWN} https://drive.google.com/uc?id=1rCsj_jpMyE0S0cokFJDyBSA0aPNiIHNb WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + execute_process(COMMAND ${UNZIP} "GAUSSIANFILES.zip" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) + execute_process(COMMAND rm "GAUSSIANFILES.zip" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + else() + message(FATAL_ERROR "Found pip, but still unable to install or find gdown") + endif() +endif() diff --git a/cmake/InstallMAMAP.cmake b/cmake/InstallMAMAP.cmake new file mode 100644 index 0000000..09b06d8 --- /dev/null +++ b/cmake/InstallMAMAP.cmake @@ -0,0 +1,10 @@ +# If Catch2 is not found, instead use the git submodule +if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/external/MAMAP/include/mamap/argument_parser.hpp) + # Unable to find the header files for Catch2 or they don't exist + message(STATUS "Downloading MAMAP submodule.") + + # Clone the submodule + execute_process(COMMAND git submodule update --init --force -- external/MAMAP WORKING_DIRECTORY ${catnip_SOURCE_DIR}) +endif() + +add_subdirectory(${catnip_SOURCE_DIR}/external/MAMAP) diff --git a/external/Catch2 b/external/Catch2 new file mode 160000 index 0000000..7f21cc6 --- /dev/null +++ b/external/Catch2 @@ -0,0 +1 @@ +Subproject commit 7f21cc6c5599f59835f769debf13b4c3e6148a28 diff --git a/external/MAMAP b/external/MAMAP new file mode 160000 index 0000000..0641040 --- /dev/null +++ b/external/MAMAP @@ -0,0 +1 @@ +Subproject commit 064104002b34a410f185fd8657196bcd70db5650 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..71ce73d --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,8 @@ +add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/libcatnip") +#add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/tools") +if(${ENABLE_UNIT_TESTING} OR ${ENABLE_INTEGRATION_TESTING}) + message(STATUS "adding test directory") + add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/tests") +endif() + + diff --git a/src/libcatnip/CMakeLists.txt b/src/libcatnip/CMakeLists.txt index 9e7f650..9484b81 100644 --- a/src/libcatnip/CMakeLists.txt +++ b/src/libcatnip/CMakeLists.txt @@ -1,9 +1,11 @@ file(GLOB CATNIP_SOURCE_FILES - *.cpp - io/*.cpp - io/arguments/*.cpp - io/arguments/properties/*.cpp - io/file_readers/*.cpp) + io/io.cpp + string_support.cpp + io/file_readers/*.cpp + *.cpp) add_library(libcatnip ${CATNIP_SOURCE_FILES}) +set_property(TARGET libcatnip PROPERTY CXX_STANDARD 17) +target_include_directories(libcatnip PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(libcatnip PUBLIC mamap) diff --git a/src/libcatnip/README.md b/src/libcatnip/README.md new file mode 100644 index 0000000..49842f7 --- /dev/null +++ b/src/libcatnip/README.md @@ -0,0 +1,17 @@ + # Outline + +Flow of the calc_J should follow as: + +1. Read arguments +2. Assign files to atomic groups +3. Read atomic coordinates +4. Create group container +5. Assign group types +6. Create atom system +7. Check basis sets line up between components and complex +8. Load overlap matrices and molecular orbital coefficients +9. Create swap engine +10. Order matrices if needed +11. Generate Transfer integral complex +12. Calculate transfer integral + diff --git a/src/libcatnip/atom.cpp b/src/libcatnip/atom.cpp new file mode 100644 index 0000000..1c342e1 --- /dev/null +++ b/src/libcatnip/atom.cpp @@ -0,0 +1,31 @@ +#include "atom.hpp" + +namespace catnip { + double round(double N, double n) + { + int h; + double b, d, e, i, j, m, f; + b = N; + + // Counting the no. of digits to the left of decimal point + // in the given no. + for (i = 0; b >= 1; ++i) + b = b / 10; + + d = n - i; + b = N; + b = b * std::pow(10, d); + e = b + 0.5; + if ((float)e == (float)std::ceil(b)) { + f = (std::ceil(b)); + h = f - 2; + if (h % 2 != 0) { + e = e - 1; + } + } + j = std::floor(e); + m = std::pow(10, d); + j = j / m; + return j; + } +} diff --git a/src/libcatnip/atom.hpp b/src/libcatnip/atom.hpp new file mode 100644 index 0000000..c5e4718 --- /dev/null +++ b/src/libcatnip/atom.hpp @@ -0,0 +1,76 @@ + +#pragma once +#ifndef _CATNIP_ATOM_HPP +#define _CATNIP_ATOM_HPP + +// Private local includes +#include "elements.hpp" + +// Third party includes +#include + +// Standard includes +#include + +namespace catnip { + + /** + * @brief Atom Class + * + * This class is responsible for packaging basic atomic information including + * atomic coordinates + * element + * the number of basis functions + */ + class Atom { + private: + // Element should not be able to change + const Element element_; + Eigen::Vector3d xyz_; + int basis_func_count_ = -1; + public: + Atom(Element element, double x, double y, double z) : element_(element), xyz_(x,y,z) {}; + + Element getElement() const noexcept { return element_; } + + Eigen::Vector3d getPos() const noexcept { return xyz_; } + + void setBasisFuncCount(int count) { + basis_func_count_ = count; + } + + int getBasisFuncCount() const noexcept { return basis_func_count_; } + + bool operator==( const Atom & atm2 ) const { + if ( element_ == atm2.element_ ){ + if ( xyz_.isApprox(atm2.xyz_)) { + return true; + } + } + return false; + } + + bool operator!=( const Atom & atm2 ) const { + return !(*this == atm2); + } + }; + + double round(double N, double n); +} + +namespace std { + + template <> + struct hash + { + std::size_t operator()(const catnip::Atom& atom) const + { + Eigen::Vector3d pos = atom.getPos(); + return ((((std::hash()(atom.getElement()) + ^ (hash()(catnip::round(pos(0),4)) << 1)) >> 1) + ^ (hash()(catnip::round(pos(1),4)) << 1)) >> 1) + ^ (hash()(catnip::round(pos(2),4)) << 1); + } + }; +} +#endif // _CATNIP_ATOM_HPP diff --git a/src/libcatnip/atom_group.cpp b/src/libcatnip/atom_group.cpp new file mode 100644 index 0000000..b910eab --- /dev/null +++ b/src/libcatnip/atom_group.cpp @@ -0,0 +1,45 @@ + +#include "atom_group.hpp" +#include "atom.hpp" + +// Standard includes +#include + +namespace catnip { + + std::vector AtomGroup::find(const Eigen::Vector3d pos) const { + std::vector indices; + int index = 0; + for ( const std::shared_ptr & atom_ : atoms_){ + if ( atom_->getPos().isApprox( pos )){ + indices.push_back(index); + } + ++index; + } + return indices; + } + + std::vector AtomGroup::find(std::shared_ptr atom) const { + std::vector indices; + int index = 0; + for ( const std::shared_ptr & atom_ : atoms_){ + if ( *atom_ == (*atom)){ + indices.push_back(index); + } + ++index; + } + return indices; + } + + std::vector AtomGroup::findStrict(std::shared_ptr atom) { + std::vector indices; + int index = 0; + for ( std::shared_ptr & atom_ : atoms_){ + if ( atom_.get() == atom.get()){ + indices.push_back(index); + } + ++index; + } + return indices; + } +} diff --git a/src/libcatnip/atom_group.hpp b/src/libcatnip/atom_group.hpp new file mode 100644 index 0000000..dd4ee12 --- /dev/null +++ b/src/libcatnip/atom_group.hpp @@ -0,0 +1,166 @@ +#pragma once +#ifndef CATNIP_ATOM_GROUP_HPP +#define CATNIP_ATOM_GROUP_HPP + +// Third party libary includes +#include + +// Standard includes +#include +#include +#include +#include +#include +#include +#include + +namespace catnip { + + class Atom; + + /** + * @brief Atom groups can either be a component or a complex + * + * Component - all atoms in the atom group have a matching atom in the + * complex, but do not share atoms between other components + * + * Complex - all atoms in this atom group have a matching atom in a component + * + * Island - non of the atoms appear in any of the other atom groups + * + * Unknown - some combination, may or may not have overlapping components + * + * Unassigned - has not yet been specified + */ + enum class GroupType { + Component, + Complex, + Island, + Unknown, + Unassigned + }; + + enum class MatrixType { + Overlap, + Coefficients, + MolecularOrbitalsEnergies + }; + + enum class FileType { + pun, + log + }; + + /** + * @brief Atom group essentially packages anything associated with a file + * + * Atom group is responsible for packaging the atoms associated with a + * group of atoms in one place. The group type can be assigned to the atom + * group once it is known. Once the group type is known a bunch of other + * operations open up.. + * + * Probably the core use of this class is to be able to compare atoms in the + * group and ensure that they are equivalent. + * + */ + class AtomGroup { + private: + GroupType type_ = GroupType::Unassigned; + std::string name_; + // Files associated with this atom_group + std::vector file_names_; + // Matries associated with the atom group + std::vector> atoms_; + std::unordered_map files_; + std::unordered_map> matrices_; + public: + AtomGroup() = default; + AtomGroup(std::string group_name) : name_(group_name) {}; + + void addFile(const std::string file_name) { file_names_.push_back(file_name); } + + void addMatrix(const MatrixType type, std::unique_ptr mat) { matrices_[type] = std::move(mat); } + + // Attempt to load overlap matrix hopefully a log file exists which can do + // this + void loadOverlapMatrix() {}; + void loadMOCoefMatrix() {}; + + std::string getName() const noexcept { return name_; } + + void addFile(FileType type, std::string file_name) { + files_[type] = file_name; + } + + size_t size() const noexcept { return atoms_.size(); } + + std::vector>::iterator + begin() { return atoms_.begin(); } + + std::vector>::const_iterator + begin() const { return atoms_.begin(); } + + std::vector>::iterator + end() { return atoms_.end(); } + + std::vector>::const_iterator + end() const { return atoms_.end(); } + + std::shared_ptr & at(size_t ind) { + return atoms_.at(ind); + } + + const std::shared_ptr & at(size_t ind) const { + return atoms_.at(ind); + } + + void add(std::shared_ptr atom){ + atoms_.push_back(atom); + } + + void add(std::vector> atoms){ + atoms_.insert(atoms_.end(),atoms.begin(),atoms.end()); + } + + bool is(const GroupType & type) const noexcept { + return type == type_; + } + + void setType(const GroupType & type) noexcept { + type_ = type; + } + const GroupType & getType() const noexcept { return type_; } + + /** + * @brief Find the index of the atom in the group if it exists and return + * the index, compares atoms + * + * @param atom + * + * @return indeces of atoms that match + */ + std::vector find(std::shared_ptr atom) const; + + /** + * @brief Find the index of the atom in the group if it shares the provided + * position + * + * @param pos + * + * @return indeces of atoms that match the position + */ + std::vector find(const Eigen::Vector3d pos) const; + + /** + * @brief Finds the exact matching atom in memory by looking at the address + * + * @param atom + * + * @return + */ + std::vector findStrict(std::shared_ptr atom); + }; + + +} // namespace catnip +#endif // CATNIP_ATOM_GROUP_HPP diff --git a/src/libcatnip/atom_group_container.cpp b/src/libcatnip/atom_group_container.cpp new file mode 100644 index 0000000..23f6807 --- /dev/null +++ b/src/libcatnip/atom_group_container.cpp @@ -0,0 +1,235 @@ +// Local private includes +#include "atom_group_container.hpp" + +#include "atom.hpp" +#include "atom_group.hpp" + +// Third party includes +#include + +// Standard includes +#include +#include +#include +#include +#include +#include +#include +#include + +namespace catnip { + + /**************************************************************************** + * Local private structs + ****************************************************************************/ + struct GroupAtomIndex { + int atm_ind; + int grp_ind; + }; + + /**************************************************************************** + * Local private functions + ****************************************************************************/ + static std::unordered_map> mapAtomsToGroups_( + const std::vector> & atom_groups_ ){ + + std::unordered_map> atm_map; + int grp_index = 0; + for ( const std::unique_ptr & grp : atom_groups_ ){ + int atom_index = 0; + for ( auto & atom_ptr : *grp ){ + atm_map[*atom_ptr].push_back(GroupAtomIndex{atom_index,grp_index}); + ++atom_index; + } + ++grp_index; + } + return atm_map; + } + + static const std::map> calculateConnectedGroups_( + std::unordered_map> atm_map, + const std::vector> & atom_groups_ + ){ + + std::map> grp_indices; + int grp_index = 0; + for ( const std::unique_ptr & grp : atom_groups_ ){ + // Initialize + grp_indices[grp_index]; + for ( const auto & atom_ptr : *grp ){ + for ( const GroupAtomIndex & grp_atm_ind : atm_map[*atom_ptr] ){ + if (grp_atm_ind.grp_ind != grp_index ){ + // Check that group has not already been added + if( grp_indices[grp_index].size() > 0 ){ + if( grp_indices[grp_index].back() != grp_atm_ind.grp_ind ) { + grp_indices[grp_index].push_back(grp_atm_ind.grp_ind); + } + }else { + grp_indices[grp_index].push_back(grp_atm_ind.grp_ind); + } + } + } + } + ++grp_index; + + } + return grp_indices; + } + + static void identifyAtomGroupsOfIslandType_( + const std::map> & grp_indices, + std::vector> & atom_groups_ + ) { + for ( std::pair> grp_groups : grp_indices){ + if(grp_groups.second.size() == 0) { + std::cout << "Empty makeing unit, does not share atoms" << std::endl; + atom_groups_.at(grp_groups.first)->setType(GroupType::Island); + } + } + } + + static void identifyAtomGroupsOfComponentComplexAndUnknownTypes_( + const std::map> & grp_indices, + std::vector> & atom_groups_ + ){ + std::vector potential_complexes; + for ( std::pair> grp_groups : grp_indices){ + if( grp_groups.second.size() > 1 ){ + potential_complexes.push_back(grp_groups.first); + } + } + + for( const int & potential_complex : potential_complexes){ + std::vector candidate_components = grp_indices.at(potential_complex); + bool candidate_components_valid = true; + for ( const int & candidate_component : candidate_components){ + std::cout << "Candiate component " << candidate_component << std::endl; + std::cout << "number of other groups sharing atoms " << grp_indices.at(candidate_component).size() << std::endl; + if ( grp_indices.at(candidate_component).size() != 1){ + candidate_components_valid = false; + break; // these are not components, and potential complex is not a complex + } + } + if ( candidate_components_valid){ + atom_groups_.at(potential_complex)->setType(GroupType::Complex); + for ( const int & candidate_component : candidate_components){ + atom_groups_.at(candidate_component)->setType(GroupType::Component); + } + }else{ + atom_groups_.at(potential_complex)->setType(GroupType::Unknown); + for ( const int & candidate_component : candidate_components){ + atom_groups_.at(candidate_component)->setType(GroupType::Unknown); + } + } + } + } + + /**************************************************************************** + * Private Methods + ****************************************************************************/ + bool AtomGroupContainer::isUniqueGroup_( const std::unique_ptr & atom_group ) const { + // Step 1 check the size of the atom group + if(atom_groups_.size() == 0) return true; + + for ( const std::unique_ptr & grp : atom_groups_ ){ + if ( grp->size() == atom_group->size() ){ + std::vector matchs(grp->size(),false); + // Determine if a match is found + for ( const auto & atm : *atom_group ) { + size_t index = 0; + for ( bool matched : matchs ){ + if ( not matched ){ + // Compare atoms + if ( *atm == *(grp->at(index)) ){ + matchs.at(index) = true; + break; + } + } + ++index; + } + // If an atom was not matched it means that there is at least one + // difference, and so we do not need to cycle through the other + // atoms in this particular group + if(index == grp->size()) break; + } + // Count the number of matches in the vector if all of the elements match + // then the atom group is not unique + for ( bool match : matchs ) { + if ( match == false ) break; + } + return false; + } + } + return true; + } + + /**************************************************************************** + * Public Methods + ****************************************************************************/ + + std::vector AtomGroupContainer::getGroups(const GroupType & type) const noexcept{ + std::vector groups; + int ind1 = 0; + for( const std::unique_ptr & group : atom_groups_ ){ + if( group->getType() == type){ + groups.push_back(ind1); + } + ++ind1; + } + return groups; + } + + // As soon as we add a new atom group it should invalidate the labels on + // all the other groups + void AtomGroupContainer::add( std::unique_ptr atom_group ) { + std::cout << "Adding group " << atom_group->getName() << std::endl; + if( isUniqueGroup_(atom_group) ){ + std::cout << "Is unique" << std::endl; + atom_groups_.push_back(std::move(atom_group)); + } else { + return; + } + + group_types_uptodate_ = false; + } + +// Create a map with an atom as the key and a vector of indices to indicate +// where there is overlap, the group and index of where the overlap occurs + void AtomGroupContainer::assignGroupTypes(){ + + // If already uptodate do nothing + if( group_types_uptodate_ ) return; + std::unordered_map> atm_map = mapAtomsToGroups_( atom_groups_ ); + + // For each atom in a group find out how many other groups share the atoms + // First index is the group index the vector stores the other groups that + // share atoms + const std::map> grp_indices = calculateConnectedGroups_(atm_map, atom_groups_ ); + + // Calculate which groups do not share atoms with other groups these are units + identifyAtomGroupsOfIslandType_(grp_indices, atom_groups_); + + identifyAtomGroupsOfComponentComplexAndUnknownTypes_(grp_indices,atom_groups_ ); + + group_types_uptodate_ = true; + } + + bool AtomGroupContainer::exists(GroupType type) const { + // First check that all the group types have been assigned + for ( const std::unique_ptr & grp : atom_groups_ ){ + if( grp->getType() == type ) return true; + } + return false; + } + + std::vector AtomGroupContainer::getType(const std::string & group_name) const { + std::vector group_types; + for ( const std::unique_ptr & grp : atom_groups_ ){ + if ( group_name == grp->getName() ) { + group_types.push_back(grp->getType()); + } + } + return group_types; + } + +} // namespace catnip diff --git a/src/libcatnip/atom_group_container.hpp b/src/libcatnip/atom_group_container.hpp new file mode 100644 index 0000000..a466777 --- /dev/null +++ b/src/libcatnip/atom_group_container.hpp @@ -0,0 +1,110 @@ +#pragma once +#ifndef CATNIP_ATOM_GROUP_CONTAINER_HPP +#define CATNIP_ATOM_GROUP_CONTAINER_HPP + +// Local private includes +#include "atom_group.hpp" + +// Third party includes +#include + +// Standard includes +#include +#include +#include +#include +#include +#include +#include + +namespace catnip { + + /** + * @brief Allows auto detection of atom groups + * + * What this means is that if you pass in atom groups and thier state is not + * known, this class can automatically detect if they are related, if they + * are an island a complex or a component. + * + * Accurate assignment of a group type can only be achieved after all of the + * groups are added. If a new group is added after group types have been + * assigned it will invalidate the previously assigned group types. + */ + class AtomGroupContainer { + std::vector> atom_groups_; + + bool group_types_uptodate_ = false; + + /** + * @brief Checks to makes sure the group is unique + * + * Does not compare atom addresses just the atoms in the group the size + * Ignores the atom group name in the comparison + * @param atom_group + * + * @return + */ + bool isUniqueGroup_( const std::unique_ptr & atom_group ) const; + + + public: + + // Invalidates groups if non const because cannot ensure that groups are + // not changed + std::vector>::iterator + begin() { group_types_uptodate_ = false; return atom_groups_.begin(); } + + std::vector>::const_iterator + begin() const { return atom_groups_.begin(); } + + // Invalidates groups if non const because cannot ensure that groups are + // not changed + std::vector>::iterator + end() { group_types_uptodate_ = false; return atom_groups_.end(); } + + std::vector>::const_iterator + end() const { return atom_groups_.end(); } + + void add( std::unique_ptr atom_group ); + + size_t size() const noexcept { return atom_groups_.size(); } + + /** + * @brief This algorithm assignes a group type to each each of the groups + */ + void assignGroupTypes(); + + bool isUpToDate() const noexcept { return group_types_uptodate_; } + + /** + * @brief Determine if a specified group type exists within the atom groups + * + * @return + */ + bool exists(GroupType type) const; + + const GroupType & getType(int index) const { return atom_groups_.at(index)->getType(); } + + std::vector getType(const std::string & group_name) const; + + /** + * @brief Get the indices of all the groups of the specified group type + * + * @param type + * + * @return + */ + std::vector getGroups(const GroupType & type) const noexcept; + + std::unique_ptr & at(size_t ind) { + group_types_uptodate_ = false; + return atom_groups_.at(ind); + } + + const std::unique_ptr & at(size_t ind) const { return atom_groups_.at(ind);} + }; + + + +} // namespace catnip +#endif // CATNIP_ATOM_GROUP_CONTAINER_HPP diff --git a/src/libcatnip/atom_system.cpp b/src/libcatnip/atom_system.cpp new file mode 100644 index 0000000..0043f74 --- /dev/null +++ b/src/libcatnip/atom_system.cpp @@ -0,0 +1,362 @@ + +// Local private includes +#include "atom_system.hpp" + +#include "atom.hpp" + +// Standard includes +#include +#include +#include + +namespace catnip { + + /**************************************************************************** + * Local private structs + ****************************************************************************/ +/* struct AtomMatch { + int index_component; + int index_component_atom; + int index_complex_atom; + };*/ + + /**************************************************************************** + * Local private functions + ****************************************************************************/ + + static void assignBasisFunctionsToSynchronisedAtoms_( + int grp_ind, + const std::vector& basis_func_count, + std::unique_ptr & grp, + std::unique_ptr & atm_grp_cont ){ + + int index = 0; + for( std::shared_ptr & atom_ptr : *grp ){ + std::cout << "Assigning basis function atom at index " << index << std::endl; + if( atom_ptr->getBasisFuncCount() == -1){ + atom_ptr->setBasisFuncCount(basis_func_count.at(index)); + } else if(atom_ptr->getBasisFuncCount() != basis_func_count.at(index) ){ + // Make sure the new assignment is consistent with the old one + // if not throw an error, because you have a conflicting number of basis + // functions between groups + throw std::runtime_error("Inconsistency detected in the number of " + "basis functions detected between atom groups. Ensure that the " + "basis function count vector is in a consistent order with the " + "atoms in the atom group"); + } + index++; + } + + } + + static void checkLinkedAtomsInComplexForConsistentBasisFunctionCounts( + int grp_ind, + const std::unique_ptr & grp, + std::unique_ptr & atm_grp_cont, + std::map>> linked_atoms ){ + + for ( auto grp_linked_atms : linked_atoms ){ + const std::unique_ptr & component = atm_grp_cont->at(grp_linked_atms.first); + for( std::pair linked_atoms : grp_linked_atms.second ){ + if ( component->at(linked_atoms.first)->getBasisFuncCount() != -1){ + if ( component->at(linked_atoms.first)->getBasisFuncCount() != grp->at(linked_atoms.second)->getBasisFuncCount()){ + throw std::runtime_error("There are inconsistencies between the " + "the number of basis functions used in a linked atom. Atoms " + "in a component must contain the same number of basis " + "functions as thier linked atoms in the complex"); + } + } + } + } + } + + static void checkLinkedAtomsInComponentForConsistentBasisFunctionCounts( + int grp_ind, + const std::unique_ptr & grp, + std::unique_ptr & atm_grp_cont, + std::map>> linked_atoms + ) { + + std::vector complex_grps = atm_grp_cont->getGroups(GroupType::Complex); + assert(complex_grps.size() == 1 && "There must be at least one complex"); + const std::unique_ptr & complex_grp = atm_grp_cont->at(complex_grps.at(0)); + for( std::pair linked_atoms : linked_atoms[grp_ind] ){ + if ( complex_grp->at(linked_atoms.second)->getBasisFuncCount() != -1){ + if ( complex_grp->at(linked_atoms.second)->getBasisFuncCount() != grp->at(linked_atoms.first)->getBasisFuncCount()){ + throw std::runtime_error("There are inconsistencies between the " + "the number of basis functions used in a linked atom. Atoms " + "in a component must contain the same number of basis " + "functions as thier linked atoms in the complex"); + } + } + } + } + + /** + * @brief Assigns basis function to atoms in group + * + * This fucntions should only be called after the atoms have been syncrhonized + * between atom groups + * + * @param grp_ind + * @param basis_func_count + * @param atm_grp_cont + */ + static void assignBasisFuncs_( + int grp_ind, + const std::vector& basis_func_count, + std::unique_ptr & atm_grp_cont, + std::map>> linked_atoms + ) { + // Cycle through the atoms in the complex and assign the correct number of + // basis functions + + std::unique_ptr & grp = atm_grp_cont->at(grp_ind); + std::cout << "Assign to Synchronize atoms" << std::endl; + assignBasisFunctionsToSynchronisedAtoms_( + grp_ind, + basis_func_count, + grp, + atm_grp_cont); + // Make sure that there are no inconsistencies between the linked atoms + if ( atm_grp_cont->at(grp_ind)->is(GroupType::Complex)){ + // If it is a complex + std::cout << "Assign to Linked atoms in complex" << std::endl; + checkLinkedAtomsInComplexForConsistentBasisFunctionCounts( + grp_ind, + grp, + atm_grp_cont, + linked_atoms); + + }else { + // If it is a component + std::cout << "Assign to Linked atoms in component" << std::endl; + checkLinkedAtomsInComponentForConsistentBasisFunctionCounts( + grp_ind, + grp, + atm_grp_cont, + linked_atoms); + } + } +/* + static std::vector matchComponentAtomsToComplex_(){ + + AtomGroup complex_group = atom_groups_.at(index_of_complex_); + std::vector component_indices = getGroups(GroupType::Component); + std::vector all_paired_atoms; + for ( const int & component_index : component_indices ) { + std::unordered_map paired_atoms = matchAtoms_(complex_group,atom_groups_.at(component_index)); + // Pass to vector + for ( auto pr : paired_atoms ){ + AtomMatch atom_match; + atom_match.index_component = component_index; + atom_match.index_component_atom = pr.second; + atom_match.index_complex_atom = pr.first; + all_paired_atoms.push_back(atom_match); + } + } + return all_paired_atoms; + }*/ + + static void checkValidSystemCriteria_(std::unique_ptr & atm_grp_cont){ + std::vector complex_indices = + atm_grp_cont->getGroups(GroupType::Complex); + + if( complex_indices.size() == 0 ){ + throw std::runtime_error("Cannot create atom system, no complexes were " + "found in the atom group container."); + } else if( complex_indices.size() > 1 ){ + throw std::runtime_error("Cannot create atom system, several complexes " + "were found in the atom group. The atom system can only contain a " + "single complex."); + } + + std::vector component_indices = + atm_grp_cont->getGroups(GroupType::Component); + + if ( component_indices.size() < 2){ + throw std::runtime_error("Cannot create atom system, must contain at " + "least two components"); + } + } + + // Map + // first int - index of the group + // first int of the pair - index of the atom in the component + // second int of the pair - index of the linked atom in the complex + static std::map>> findNonConsistentAtoms_( + std::unique_ptr & atm_grp_cont) { + + std::map>> linked_atoms; + // Overwrite any of the pointers in the component that have the same atom + // with the complex, with the atom pointer from the complex + int complex_index = + atm_grp_cont->getGroups(GroupType::Complex).at(0); + + std::vector component_indices = + atm_grp_cont->getGroups(GroupType::Component); + + std::unique_ptr & atm_complex = atm_grp_cont->at(complex_index); + for ( const int component_ind : component_indices){ + std::unique_ptr & atm_grp = atm_grp_cont->at(component_ind); + // Cycle atoms in atm_grp + int ind_atm = 0; + for ( std::shared_ptr & atm : *atm_grp){ + std::vector complex_atm_ind = atm_complex->find(atm->getPos()); + // This vector must be of size 1 + if( complex_atm_ind.size() == 1){ + // If the elements dont' match it is non-consistent + if( atm_complex->at(complex_atm_ind.at(0))->getElement() != atm_grp->at(ind_atm)->getElement() ){ + linked_atoms[component_ind].push_back(std::pair(ind_atm,complex_atm_ind.at(0))); + } + }else if (complex_atm_ind.size() == 0) { + std::string error_msg = "A component atom did not have a matching " + "atom in the complex (" + atm_complex->getName() + "). The " + "atom in the component (" + atm_grp->getName() + ") does not have " + "to have the same element as the atom in the complex but must " + "share the same position."; + throw std::runtime_error(error_msg); + } else { + throw std::runtime_error("A component atom matches more than a single" + " atom in the complex. There appears to be a problem with the " + "complex, as more than one atom occupies the same location."); + } + ++ind_atm; + } + } + return linked_atoms; + } + + static void synchroniseAtoms_(std::unique_ptr & atm_grp_cont){ + + // Overwrite any of the pointers in the component that have the same atom + // with the complex, with the atom pointer from the complex + int complex_index = + atm_grp_cont->getGroups(GroupType::Complex).at(0); + + std::vector component_indices = + atm_grp_cont->getGroups(GroupType::Component); + + std::unique_ptr & atm_complex = atm_grp_cont->at(complex_index); + for ( const int component_ind : component_indices){ + std::unique_ptr & atm_grp = atm_grp_cont->at(component_ind); + // Cycle atoms in atm_grp + for ( std::shared_ptr & atm : *atm_grp){ + std::vector complex_atm_ind = atm_complex->find(atm); + // This vector should be 0 or 1 + if( complex_atm_ind.size() == 1){ + // Change the pointer + atm = atm_complex->at(complex_atm_ind.at(0)); + } + } + } + } + /**************************************************************************** + * Public Methods + ****************************************************************************/ + + /** + * @brief Creates an atom system if possible + * + * The criteria to create an atom system is that the AtomGroupContainer must + * contain only a single complex and the components that belong to that + * complex + * + * @param atm_grp_cont + */ + AtomSystem::AtomSystem(std::unique_ptr atm_grp_cont) { + atm_grp_cont->assignGroupTypes(); + + checkValidSystemCriteria_(atm_grp_cont); + + std::vector complex_indices = + atm_grp_cont->getGroups(GroupType::Complex); + index_complex_ = complex_indices.at(0); + // Searches for atoms that exist in the component that share a position with + // an atom in the complex, but are of a different element + linked_atoms_ = findNonConsistentAtoms_(atm_grp_cont); + + // Make atoms consistent between components and the complex, this is done + // by making atoms that share the same location point to the same place + // in memory + synchroniseAtoms_(atm_grp_cont); + + atm_grp_cont_ = std::move(atm_grp_cont); + } + + int AtomSystem::getTotalBasisFunctions(const GroupType & type) const { + int total_num_basis = 0; + std::vector group_indices = atm_grp_cont_->getGroups(type); + for ( int ind : group_indices ){ + const std::unique_ptr & group = atm_grp_cont_->at(ind); + for( const std::shared_ptr & atom_ptr : *group ) { + total_num_basis += atom_ptr->getBasisFuncCount(); + } + } + return total_num_basis; + } + + int AtomSystem::getMaxBasisFunctions(const GroupType & type) const { + int max_num_basis = 0; + std::vector group_indices = atm_grp_cont_->getGroups(type); + for ( int ind : group_indices ){ + const std::unique_ptr & group = atm_grp_cont_->at(ind); + for( const std::shared_ptr & atom_ptr : *group ) { + if( atom_ptr->getBasisFuncCount() > max_num_basis){ + max_num_basis = atom_ptr->getBasisFuncCount(); + } + } + } + return max_num_basis; + } + + + void AtomSystem::assignBasisFunctions(int index, + const std::vector& basis_func_count) { + + // 2. Check that the number of atoms in the grp is consistent with + // the number of values provided + if ( basis_func_count.size() != atm_grp_cont_->at(index)->size() ){ + throw std::runtime_error("Cannot assign basis function count to atoms " + "as the basis function count vector is not equal to the number of " + "atoms in the group!"); + } + + assignBasisFuncs_(index, basis_func_count, atm_grp_cont_, linked_atoms_); + } + + bool AtomSystem::systemComplete() const noexcept { + for ( const std::unique_ptr & grp : *atm_grp_cont_){ + for( const std::shared_ptr & atm : *grp){ + if(atm->getBasisFuncCount() == -1) return false; + } + } + return true; + } + + const std::unique_ptr & AtomSystem::at(int ind) const { + return atm_grp_cont_->at(ind); + } + + std::vector AtomSystem::getLinkedAtomsWithDifferentElements() const noexcept { + + std::vector links; + std::string complex_name = atm_grp_cont_->at(index_complex_)->getName(); + for ( std::pair>> grp_links : linked_atoms_){ + int component_ind = grp_links.first; + std::string component_name = atm_grp_cont_->at(component_ind)->getName(); + for ( std::pair atm1_atm2 : grp_links.second){ + Link link{ + component_name, // Component name + component_ind, // Component index + atm1_atm2.first, // Component atom index + complex_name, // Complex name + index_complex_, // Complex index + atm1_atm2.second }; // Complex atom index + + links.push_back(link); + } + } + return links; + } +} diff --git a/src/libcatnip/atom_system.hpp b/src/libcatnip/atom_system.hpp new file mode 100644 index 0000000..b040dd0 --- /dev/null +++ b/src/libcatnip/atom_system.hpp @@ -0,0 +1,108 @@ + +#pragma once +#ifndef CATNIP_ATOM_SYSTEM_HPP +#define CATNIP_ATOM_SYSTEM_HPP + +// Local private includes +#include "atom_group_container.hpp" + +// Standard includes +#include +#include +#include + +namespace catnip { + + /** + * @brief Unlike atom group container, this atom system does not allow to + * change group types + * + * It can only be created if there are known group types and there is only + * a single complex, and it's components. The presence of these group types + * is what makes it possible to run the charge transfer integral calculations. + * + * Each atom in a component must only be shared with the complex, the atom of + * a component is allowed to be of a different element then what is in the + * complex, but must have the same position. + * + * Basis functions can be assigned using the atom system, atoms shared between + * a component and the complex will be made consistent in terms of the + * number of basis functions that are associated with them. + */ + class AtomSystem { + // Atoms in each component that share the same location with atoms in + // the complex but do not share the same element + std::map>> linked_atoms_; + std::unique_ptr atm_grp_cont_; + int index_complex_; + public: + + struct Link { + std::string component_name; + int component_ind; + int component_atm_ind; + std::string complex_name; + int complex_ind; + int complex_atm_ind; + }; + + AtomSystem(std::unique_ptr atm_cont); + + /** + * @brief assign basis functions to atom group + * + * Note that atoms that are linked between component and complex must + * have the exact same number of basis functions. + * + * @param complex_basis_func_count + */ + void assignBasisFunctions(int index, const std::vector& basis_funcs); + + /** + * @brief Determine if there is a conflict between the basis functions + * you are attempting to assign and the currently assigned basis functions + * + * This is done by comparing the basis functions on atoms that are shared + * between atom groups. + * + * @param index + * @param basis_funcs + * + * @return + */ + bool conflictBasisFunctions(int index, const std::vector & basis_funcs) const; + + int getTotalBasisFunctions(const GroupType & type) const; + + int getMaxBasisFunctions(const GroupType & type) const; + + const std::unique_ptr & getComplex() const { + return atm_grp_cont_->at(index_complex_); + } + + std::vector getComponentIndices() const noexcept { + return atm_grp_cont_->getGroups(GroupType::Component); + } + + + /** + * @brief Gets atoms that are linked because they share the same position + * but don't share the same element + * + * @return + */ + std::vector getLinkedAtomsWithDifferentElements() const noexcept; + + const std::unique_ptr & at(int ind) const; + /** + * @brief Check that every atom knows how many basis functions are + * assigned to it + * + * @return + */ + bool systemComplete() const noexcept; + }; + +}; + +#endif // CATNIP_ATOM_SYSTEM_HPP diff --git a/src/libcatnip/basis_map.cpp b/src/libcatnip/basis_map.cpp new file mode 100644 index 0000000..656ed44 --- /dev/null +++ b/src/libcatnip/basis_map.cpp @@ -0,0 +1,79 @@ + + +#include "basis_map.hpp" + +#include "atom.hpp" +#include "atom_system.hpp" + +// Standard includes +#include +#include + +namespace catnip { + + BasisMap::BasisMap(const AtomSystem & atm_sys){ + if ( not atm_sys.systemComplete() ) { + throw std::runtime_error("Cannot build an index map from an incomplete " + "atom system."); + } + + // 1. map each of the atoms in complex to an offset based on the number + // of basis functions up to that point, + // E.g. + // atom1 2 basis functs + // atom2 3 basis functs + // atom3 1 basis functs + // + // offset_map[0] = 0; // atom1 + // offset_map[1] = 2; // atom2 + // offset_map[2] = 5; // atom3 + + std::unordered_map offset_map; + const std::unique_ptr & complex_grp = atm_sys.getComplex(); + int offset = 0; + int complex_atm_ind = 0; + for ( const std::shared_ptr & atm_ptr : *complex_grp){ + offset_map[complex_atm_ind] = offset; + offset += atm_ptr->getBasisFuncCount(); + ++complex_atm_ind; + } + + std::vector component_indices = atm_sys.getComponentIndices(); + int sys_ind = 0; + for ( int & component_ind : component_indices) { + const std::unique_ptr & component_grp = atm_sys.at(component_ind); + std::cout << "Component grp " << component_grp->getName() << " component ind " << component_ind << " size " << component_grp->size() << std::endl; + for( const std::shared_ptr & atm_ptr : *component_grp){ + std::vector atm_indices = complex_grp->find(atm_ptr->getPos()); + assert(atm_indices.size() == 1); + int atm_ind = atm_indices.at(0); + int num_basis = complex_grp->at(atm_ind)->getBasisFuncCount(); + int complex_offset = offset_map[atm_ind]; + + for ( int ind_temp = 0; ind_temp BasisMap::findLocation(int row){ + for( std::pair> group_rows : row_col_current){ + int row_ind = 0; + for ( int row_ : group_rows.second ){ + if (row_ == row){ + return std::pair(group_rows.first, row_ind); + } + ++row_ind; + } + } + return std::pair(); + } + +} // namespace catnip diff --git a/src/libcatnip/basis_map.hpp b/src/libcatnip/basis_map.hpp new file mode 100644 index 0000000..8325581 --- /dev/null +++ b/src/libcatnip/basis_map.hpp @@ -0,0 +1,45 @@ + +#pragma once +#ifndef _CATNIP_INDEX_MAP_HPP +#define _CATNIP_INDEX_MAP_HPP + +// Local private includes +#include "atom_system.hpp" + +// Standard includes +#include +#include + +namespace catnip { + + + /** + * @brief This class tracks how the basis functions map to the rows in the + * complex + */ + class BasisMap { + public: + BasisMap() = default; + BasisMap(const AtomSystem & atm_sys); + // The component rows and colums in their current locations in + // in the full system matrix of the complex + std::map> row_col_current; + + // Map indicate where the rows and cols should go in the final state + // Each int in the vector represents the location in the full system matrix + std::map> row_col_final; + + /** + * @brief Given a row of the complex finds it's location in one of the + * components + * + * @param row_complex + * + * @return + */ + std::pair findLocation(int row_complex); + }; + + +} // namespace catnip +#endif // _CATNIP_INDEX_MAP_HPP diff --git a/src/libcatnip/calcJconfig.hpp.in b/src/libcatnip/calcJconfig.hpp.in index f7777ce..83ca160 100644 --- a/src/libcatnip/calcJconfig.hpp.in +++ b/src/libcatnip/calcJconfig.hpp.in @@ -6,8 +6,8 @@ #include namespace catnip { -const int calcJ_VERSION_MAJOR = @calcJ_VERSION_MAJOR@; -const int calcJ_VERSION_MINOR = @calcJ_VERSION_MINOR@; +const int calcJ_VERSION_MAJOR = @PROJECT_VERSION_MAJOR@; +const int calcJ_VERSION_MINOR = @PROJECT_VERSION_MINOR@; const int calcJ_YEAR_PUBLISHED = @calcJ_YEAR_PUBLISHED@; const std::string calcJ_AUTHOR_SURNAME = @calcJ_AUTHOR_SURNAME@; const std::string calcJ_AUTHOR_INITIALS = @calcJ_AUTHOR_INITIALS@; diff --git a/src/libcatnip/catnip_config.hpp.in b/src/libcatnip/catnip_config.hpp.in new file mode 100644 index 0000000..4632328 --- /dev/null +++ b/src/libcatnip/catnip_config.hpp.in @@ -0,0 +1,18 @@ +// Configured options and settings for catnip + +#ifndef CATNIP_CONFIG_HPP +#define CATNIP_CONFIG_HPP + +#include + +namespace catnip { + const int catnip_VERSION_MAJOR = @catnip_VERSION_MAJOR@; + const int catnip_VERSION_MINOR = @catnip_VERSION_MINOR@; + const int catnip_YEAR_PUBLISHED = @catnip_YEAR_PUBLISHED@; + const std::string catnip_AUTHOR_SURNAME = @catnip_AUTHOR_SURNAME@; + const std::string catnip_AUTHOR_INITIALS = @catnip_AUTHOR_INITIALS@; + const std::string catnip_TITLE = @catnip_TITLE@; + const std::string catnip_URL = @catnip_URL@; +} // namespace catnip + +#endif // CATNIP_CONFIG_HPP diff --git a/src/libcatnip/elements.hpp b/src/libcatnip/elements.hpp new file mode 100644 index 0000000..6959d7d --- /dev/null +++ b/src/libcatnip/elements.hpp @@ -0,0 +1,536 @@ + +#pragma once +#ifndef _CATNIP_ELEMENTS_HPP +#define _CATNIP_ELEMENTS_HPP +#include +#include +#include +#include +#include + +namespace catnip { + + enum class Element { + Ac, + Al, + Am, + Sb, + Ar, + As, + At, + Ba, + Bk, + Be, + Bi, + Bh, + B, + Br, + Cd, + Ca, + Cf, + C, + Ce, + Cs, + Cl, + Cr, + Co, + Cu, + Cm, + Ds, + Db, + Dy, + Es, + Er, + Eu, + Fm, + F, + Fr, + Gd, + Ga, + Ge, + Au, + Hf, + Hs, + He, + Ho, + H, + In, + I, + Ir, + Fe, + Kr, + La, + Lr, + Pb, + Li, + Lu, + Mg, + Mn, + Mt, + Md, + Hg, + Mo, + Nd, + Ne, + Np, + Ni, + Nb, + N, + No, + Uuo, + Os, + O, + Pd, + P, + Pt, + Pu, + Po, + K, + Pr, + Pm, + Pa, + Ra, + Rn, + Re, + Rh, + Rg, + Rb, + Ru, + Rf, + Sm, + Sc, + Sg, + Se, + Si, + Ag, + Na, + Sr, + S, + Ta, + Tc, + Te, + Tb, + Tl, + Th, + Tm, + Sn, + Ti, + W, + Uub, + Uuh, + Uup, + Uuq, + Uus, + Uut, + U, + V, + Xe, + Yb, + Y, + Zn, + Zr, + Unknown + }; + + /** + * @brief For manipulating Elements + * + * Converts string to enum class type + */ + class Elements { + + private: + void to_lower_(std::string & data) const noexcept { + std::transform(data.begin(), data.end(), data.begin(), + [](unsigned char c){ return std::tolower(c); }); + } + public: + + /** + * @brief Case insensitive get Element enum + * + * @param element_name + * + * @return + */ + Element getElement(std::string element_name) const noexcept { + to_lower_(element_name); + if( elements_.count(element_name)) { + return elements_.at(element_name); + } + if( elementssym_.count(element_name)) { + return elementssym_.at(element_name); + } + return Element::Unknown; + } + + std::string getString(Element element) const noexcept { + return elements_str_sym_.at(static_cast(element)); + } + private: + + std::vector elements_str_sym_ = { + "Ac", + "Al", + "Am", + "Sb", + "Ar", + "As", + "At", + "Ba", + "Bk", + "Be", + "Bi", + "Bh", + "B", + "Br", + "Cd", + "Ca", + "Cf", + "C", + "Ce", + "Cs", + "Cl", + "Cr", + "Co", + "Cu", + "Cm", + "Ds", + "Db", + "Dy", + "Es", + "Er", + "Eu", + "Fm", + "F", + "Fr", + "Gd", + "Ga", + "Ge", + "Au", + "Hf", + "Hs", + "He", + "Ho", + "H", + "In", + "I", + "Ir", + "Fe", + "Kr", + "La", + "Lr", + "Pb", + "Li", + "Lu", + "Mg", + "Mn", + "Mt", + "Md", + "Hg", + "Mo", + "Nd", + "Ne", + "Np", + "Ni", + "Nb", + "N", + "No", + "Uuo", + "Os", + "O", + "Pd", + "P", + "Pt", + "Pu", + "Po", + "K", + "Pr", + "Pm", + "Pa", + "Ra", + "Rn", + "Re", + "Rh", + "Rg", + "Rb", + "Ru", + "Rf", + "Sm", + "Sc", + "Sg", + "Se", + "Si", + "Ag", + "Na", + "Sr", + "S", + "Ta", + "Tc", + "Te", + "Tb", + "Tl", + "Th", + "Tm", + "Sn", + "Ti", + "W", + "Uub", + "Uuh", + "Uup", + "Uuq", + "Uus", + "Uut", + "U", + "V", + "Xe", + "Yb", + "Y", + "Zn", + "Zr", + "Unknown"}; + + std::map elements_ = { + {"actinium", Element::Ac}, + {"aluminum", Element::Al}, + {"americium", Element::Am}, + {"antimony", Element::Sb}, + {"argon", Element::Ar}, + {"arsenic", Element::As}, + {"astatine", Element::At}, + {"barium", Element::Ba}, + {"berkelium", Element::Bk}, + {"beryllium", Element::Be}, + {"bismuth", Element::Bi}, + {"bohrium", Element::Bh}, + {"boron", Element::B}, + {"bromine", Element::Br}, + {"cadmium", Element::Cd}, + {"calcium", Element::Ca}, + {"californium", Element::Cf}, + {"carbon", Element::C}, + {"cerium", Element::Ce}, + {"cesium", Element::Cs}, + {"chlorine", Element::Cl}, + {"chromium", Element::Cr}, + {"cobalt", Element::Co}, + {"copper", Element::Cu}, + {"curium", Element::Cm}, + {"darmstadtium", Element::Ds}, + {"dubnium", Element::Db}, + {"dysprosium", Element::Dy}, + {"einsteinium", Element::Es}, + {"erbium", Element::Er}, + {"europium", Element::Eu}, + {"fermium", Element::Fm}, + {"fluorine", Element::F}, + {"francium", Element::Fr}, + {"gadolinium", Element::Gd}, + {"gallium", Element::Ga}, + {"germanium", Element::Ge}, + {"gold", Element::Au}, + {"hafnium", Element::Hf}, + {"hassium", Element::Hs}, + {"helium", Element::He}, + {"holmium", Element::Ho}, + {"hydrogen", Element::H}, + {"indium", Element::In}, + {"iodine", Element::I}, + {"iridium", Element::Ir}, + {"iron", Element::Fe}, + {"krypton", Element::Kr}, + {"lanthanum", Element::La}, + {"lawrencium", Element::Lr}, + {"lead", Element::Pb}, + {"lithium", Element::Li}, + {"lutetium", Element::Lu}, + {"magnesium", Element::Mg}, + {"manganese", Element::Mn}, + {"meitnerium", Element::Mt}, + {"mendelevium", Element::Md}, + {"mercury", Element::Hg}, + {"molybdenum", Element::Mo}, + {"neodymium", Element::Nd}, + {"neon", Element::Ne}, + {"neptunium", Element::Np}, + {"nickel", Element::Ni}, + {"niobium", Element::Nb}, + {"nitrogen", Element::N}, + {"nobelium", Element::No}, + {"oganesson", Element::Uuo}, + {"osmium", Element::Os}, + {"oxygen", Element::O}, + {"palladium", Element::Pd}, + {"phosphorus", Element::P}, + {"platinum", Element::Pt}, + {"plutonium", Element::Pu}, + {"polonium", Element::Po}, + {"potassium", Element::K}, + {"praseodymium", Element::Pr}, + {"promethium", Element::Pm}, + {"protactinium", Element::Pa}, + {"radium", Element::Ra}, + {"radon", Element::Rn}, + {"rhenium", Element::Re}, + {"rhodium", Element::Rh}, + {"roentgenium", Element::Rg}, + {"rubidium", Element::Rb}, + {"ruthenium", Element::Ru}, + {"rutherfordium",Element::Rf}, + {"samarium", Element::Sm}, + {"scandium", Element::Sc}, + {"seaborgium", Element::Sg}, + {"selenium", Element::Se}, + {"silicon", Element::Si}, + {"silver", Element::Ag}, + {"sodium", Element::Na}, + {"strontium", Element::Sr}, + {"sulfur", Element::S}, + {"tantalum", Element::Ta}, + {"technetium", Element::Tc}, + {"tellurium", Element::Te}, + {"terbium", Element::Tb}, + {"thallium", Element::Tl}, + {"thorium", Element::Th}, + {"thulium", Element::Tm}, + {"tin", Element::Sn}, + {"titanium", Element::Ti}, + {"tungsten", Element::W}, + {"ununbium", Element::Uub}, + {"ununhexium", Element::Uuh}, + {"ununpentium", Element::Uup}, + {"ununquadium", Element::Uuq}, + {"ununseptium", Element::Uus}, + {"ununtrium", Element::Uut}, + {"uranium", Element::U}, + {"vanadium", Element::V}, + {"xenon", Element::Xe}, + {"ytterbium", Element::Yb}, + {"yttrium", Element::Y}, + {"zinc", Element::Zn}, + {"zirconium", Element::Zr}}; + + std::map elementssym_ = { + {"ac", Element::Ac}, + {"al", Element::Al}, + {"am", Element::Am}, + {"sb", Element::Sb}, + {"ar", Element::Ar}, + {"as", Element::As}, + {"at", Element::At}, + {"ba", Element::Ba}, + {"bk", Element::Bk}, + {"be", Element::Be}, + {"bi", Element::Bi}, + {"bh", Element::Bh}, + {"b", Element::B}, + {"br", Element::Br}, + {"cd", Element::Cd}, + {"ca", Element::Ca}, + {"cf", Element::Cf}, + {"c", Element::C}, + {"ce", Element::Ce}, + {"cs", Element::Cs}, + {"cl", Element::Cl}, + {"cr", Element::Cr}, + {"co", Element::Co}, + {"cu", Element::Cu}, + {"cm", Element::Cm}, + {"ds", Element::Ds}, + {"db", Element::Db}, + {"dy", Element::Dy}, + {"es", Element::Es}, + {"er", Element::Er}, + {"eu", Element::Eu}, + {"fm", Element::Fm}, + {"f", Element::F}, + {"fr", Element::Fr}, + {"gd", Element::Gd}, + {"ga", Element::Ga}, + {"ge", Element::Ge}, + {"au", Element::Au}, + {"hf", Element::Hf}, + {"hs", Element::Hs}, + {"he", Element::He}, + {"ho", Element::Ho}, + {"h", Element::H}, + {"in", Element::In}, + {"i", Element::I}, + {"ir", Element::Ir}, + {"fe", Element::Fe}, + {"kr", Element::Kr}, + {"la", Element::La}, + {"lr", Element::Lr}, + {"pb", Element::Pb}, + {"li", Element::Li}, + {"lu", Element::Lu}, + {"mg", Element::Mg}, + {"mn", Element::Mn}, + {"mt", Element::Mt}, + {"md", Element::Md}, + {"hg", Element::Hg}, + {"mo", Element::Mo}, + {"nd", Element::Nd}, + {"ne", Element::Ne}, + {"np", Element::Np}, + {"ni", Element::Ni}, + {"nb", Element::Nb}, + {"n", Element::N}, + {"no", Element::No}, + {"uuo", Element::Uuo}, + {"os", Element::Os}, + {"o", Element::O}, + {"pd", Element::Pd}, + {"p", Element::P}, + {"pt", Element::Pt}, + {"pu", Element::Pu}, + {"po", Element::Po}, + {"k", Element::K}, + {"pr", Element::Pr}, + {"pm", Element::Pm}, + {"pa", Element::Pa}, + {"ra", Element::Ra}, + {"rn", Element::Rn}, + {"re", Element::Re}, + {"rh", Element::Rh}, + {"rg", Element::Rg}, + {"rb", Element::Rb}, + {"ru", Element::Ru}, + {"rf", Element::Rf}, + {"sm", Element::Sm}, + {"sc", Element::Sc}, + {"sg", Element::Sg}, + {"se", Element::Se}, + {"si", Element::Si}, + {"ag", Element::Ag}, + {"na", Element::Na}, + {"sr", Element::Sr}, + {"s", Element::S}, + {"ta", Element::Ta}, + {"tc", Element::Tc}, + {"te", Element::Te}, + {"tb", Element::Tb}, + {"tl", Element::Tl}, + {"th", Element::Th}, + {"tm", Element::Tm}, + {"sn", Element::Sn}, + {"ti", Element::Ti}, + {"w", Element::W}, + {"uub", Element::Uub}, + {"uuh", Element::Uuh}, + {"uup", Element::Uup}, + {"uuq", Element::Uuq}, + {"uus", Element::Uus}, + {"uut", Element::Uut}, + {"u", Element::U}, + {"v", Element::V}, + {"xe", Element::Xe}, + {"yb", Element::Yb}, + {"y", Element::Y}, + {"zn", Element::Zn}, + {"zr", Element::Zr}}; + + }; + +} +#endif // _CATNIP_ELEMENTS_HPP diff --git a/src/libcatnip/io/argumentparser.cpp b/src/libcatnip/io/argumentparser.cpp deleted file mode 100644 index 0615d2a..0000000 --- a/src/libcatnip/io/argumentparser.cpp +++ /dev/null @@ -1,687 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "argumentparser.hpp" - -#include "../calcJconfig.hpp" -#include "../string_support.hpp" - -using namespace catnip; -using namespace std; - -ArgumentParser::ArgumentParser(set> flags) { - - vector flag_help; - flag_help.push_back("--help"); - flag_help.push_back("-h"); - flag_help.push_back("Display help message"); - flags.insert(flag_help); - - maxShortFlagSize = 0; - maxFullFlagSize = 0; - maxDescriptionSize = 0; - - for (auto flag : flags) { - - if (flag.size() > 3) { - throw invalid_argument( - "Flags may only be passed with a max of three " - "values: full flag name, abbreviated name, and flag description"); - } - - string full_flag = "NO_FLAG_SPECIFIED"; - string short_flag = "NO_SHORT_FLAG_SPECIFIED"; - string desc = "NO_DESCRIPTION_GIVEN"; - - bool description = false; - bool abbreviation = false; - bool flag_name = false; - for (auto item : flag) { - trim(item); - string doubledash = firstN(item, 2); - string singledash = firstN(item, 1); - if (doubledash.compare("--") == 0) { - if (flag_name) { - string err = "A flag name has already been suppied:\n"; - err.append(full_flag); - err.append("\nNow you are supplying a second one:\n"); - err.append(item); - throw invalid_argument(err); - } - full_flag = item; - defaults_set_[item] = false; - flag_name = true; - if (full_flag.size() > maxFullFlagSize) { - maxFullFlagSize = full_flag.size(); - } - } else if (singledash.compare("-") == 0) { - if (abbreviation) { - string err = "A flag name has already been suppied:\n"; - err.append(short_flag); - err.append("\nNow you are supplying a second one:\n"); - err.append(item); - throw invalid_argument(err); - } - short_flag = item; - abbreviation = true; - if (short_flag.size() > maxShortFlagSize) { - maxShortFlagSize = short_flag.size(); - } - } else { - if (description) { - string err = "A description has already been suppied:\n"; - err.append(desc); - err.append("\nNow you are supplying a second one:\n"); - err.append(item); - throw invalid_argument(err); - } - desc = item; - description = true; - if (desc.size() > maxDescriptionSize) { - maxDescriptionSize = desc.size(); - } - } - } - if (!flag_name) { - throw invalid_argument("You have failed to provide the full flag name"); - } - flags_[full_flag] = make_pair(short_flag, desc); - } -} - -void ArgumentParser::showUsage(void) { - cout << endl; - cout << endl; - cout << "Options:" << endl; - cout << endl; - - for (auto item : flags_) { - string full_flag = item.first; - size_t diff = maxFullFlagSize - full_flag.size(); - cout << full_flag; - for (size_t i = 0; i <= diff; ++i) { - cout << " "; - } - string short_flag = item.second.first; - diff = maxShortFlagSize - short_flag.size(); - cout << short_flag; - for (size_t i = 0; i <= diff; ++i) { - cout << " "; - } - - size_t space = maxFullFlagSize + maxShortFlagSize + 2; - size_t allowed = maxLineLength - space; - string space_block = ""; - for (size_t sp = 0; sp < space; sp++) { - space_block.append(" "); - } - - string desc = item.second.second; - vector vec_string = splitSt(desc); - size_t words_size = 0; - for (auto word : vec_string) { - words_size += word.size() + 1; - if (words_size < allowed) { - cout << word << " "; - } else { - cout << endl; - cout << space_block; - cout << word << " "; - words_size = 0; - } - } - cout << endl; - cout << endl; - } - cout << endl; -} - -void ArgumentParser::addFlagArg(string flag, string argname) { - - if (argname.compare("ARGUMENT_INT") == 0) { - if (int_arg_.count(flag) == 0) { - ArgumentInt* ArInt = new ArgumentInt; - int_arg_[flag] = ArInt; - } else { - throw invalid_argument( - "Int argument has already been added for " - "flag " + - flag); - } - } else if (argname.compare("ARGUMENT_SWITCH") == 0) { - if (switch_arg_.count(flag) == 0) { - ArgumentSwitch* ArSwitch = new ArgumentSwitch; - switch_arg_[flag] = ArSwitch; - } else { - throw invalid_argument( - "switch argument has already been added for " - "flag " + - flag); - } - } else if (argname.compare("ARGUMENT_STRING") == 0) { - if (str_arg_.count(flag) == 0) { - ArgumentString* ArString = new ArgumentString; - str_arg_[flag] = ArString; - } else { - throw invalid_argument( - "string argument has already been added for " - "flag " + - flag); - } - } else if (argname.compare("ARGUMENT_FILE") == 0) { - if (file_arg_.count(flag) == 0) { - ArgumentFile* ArFile = new ArgumentFile; - file_arg_[flag] = ArFile; - } else { - throw invalid_argument( - "File argument has already been added for " - "flag " + - flag); - } - } else if (argname.compare("ARGUMENT_DOUBLE") == 0) { - if (file_arg_.count(flag) == 0) { - ArgumentDouble* ArDouble = new ArgumentDouble; - double_arg_[flag] = ArDouble; - } else { - throw invalid_argument( - "Double argument has already been added for " - "flag " + - flag); - } - } else { - throw invalid_argument( - "Unrecognized argument being added for flag" - " argname is " + - argname + " flag name is " + flag); - } -} - -void ArgumentParser::setFlagDefaultValue(string flag,const int & val) { - int_values_[flag] = val; - defaults_set_[flag] = true; -} - -void ArgumentParser::setFlagDefaultValue(string flag,const size_t & val) { - size_t_values_[flag] = val; - defaults_set_[flag] = true; -} - -void ArgumentParser::setFlagDefaultValue(string flag,const double & val) { - double_values_[flag] = val; - defaults_set_[flag] = true; -} - -void ArgumentParser::setFlagDefaultValue(string flag,const string & val) { - string_values_[flag] = val; - defaults_set_[flag] = true; -} - -void ArgumentParser::setFlagArgOpt(string flag, string argname, string property, - string option, int val) { - - if (argname.compare("ARGUMENT_INT") == 0) { - if (int_arg_.count(flag) == 0) { - ArgumentInt* ArInt = new ArgumentInt; - ArInt->setArgPropertyOpt(property, option, val); - int_arg_[flag] = ArInt; - } else { - int_arg_[flag]->setArgPropertyOpt(property, option, val); - } - } else if (argname.compare("ARGUMENT_STRING") == 0) { - if (str_arg_.count(flag) == 0) { - ArgumentString* ArString = new ArgumentString; - ArString->setArgPropertyOpt(property, option, val); - str_arg_[flag] = ArString; - } else { - str_arg_[flag]->setArgPropertyOpt(property, option, val); - } - } else if (argname.compare("ARGUMENT_SWITCH") == 0) { - if (switch_arg_.count(flag) == 0) { - ArgumentSwitch* ArSwitch = new ArgumentSwitch; - if (val == 0) { - ArSwitch->setArgPropertyOpt(property, option, "OFF"); - } else if (val == 1) { - ArSwitch->setArgPropertyOpt(property, option, "ON"); - } else { - throw invalid_argument("Unrecognized option for switch " + - to_string(val)); - } - switch_arg_[flag] = ArSwitch; - } else { - if (val == 0) { - switch_arg_[flag]->setArgPropertyOpt(property, option, "OFF"); - } else if (val == 1) { - switch_arg_[flag]->setArgPropertyOpt(property, option, "ON"); - } else { - throw invalid_argument("Unrecognized option for switch " + - to_string(val)); - } - } - } else if (argname.compare("ARGUMENT_FILE") == 0) { - if (file_arg_.count(flag) == 0) { - ArgumentFile* ArFile = new ArgumentFile; - - ArFile->setArgPropertyOpt(property, option, val); - file_arg_[flag] = ArFile; - } else { - file_arg_[flag]->setArgPropertyOpt(property, option, val); - } - } else { - throw invalid_argument("Unrecognized int arg"); - } -} - -void ArgumentParser::setFlagArgOpt(string flag, string argname, string property, - string option, double val) { - - if (argname.compare("ARGUMENT_DOUBLE") == 0) { - if (double_arg_.count(flag) == 0) { - ArgumentDouble* ArDouble = new ArgumentDouble; - ArDouble->setArgPropertyOpt(property, option, val); - double_arg_[flag] = ArDouble; - } else { - double_arg_[flag]->setArgPropertyOpt(property, option, val); - } - } else if (argname.compare("ARGUMENT_STRING") == 0) { - if (str_arg_.count(flag) == 0) { - ArgumentString* ArString = new ArgumentString; - ArString->setArgPropertyOpt(property, option, val); - str_arg_[flag] = ArString; - } else { - str_arg_[flag]->setArgPropertyOpt(property, option, val); - } - } else { - throw invalid_argument("Unrecognized double arg"); - } -} - -void ArgumentParser::setFlagArgOpt(string flag, string argname, string property, - string option, string val) { - - if (argname.compare("ARGUMENT_FILE") == 0) { - if (file_arg_.count(flag) == 0) { - - if (property.compare("PROPERTY_FILE_EXT") == 0) { - set temp{val}; - ArgumentFile* ArFile = new ArgumentFile; - ArFile->setArgPropertyOpt(property, option, temp); - file_arg_[flag] = ArFile; - } else if (property.compare("PROPERTY_SISTER_FILE_EXT") == 0) { - vector temp{val}; - ArgumentFile* ArFile = new ArgumentFile; - ArFile->setArgPropertyOpt(property, option, temp); - file_arg_[flag] = ArFile; - } else { - ArgumentFile* ArFile = new ArgumentFile; - ArFile->setArgPropertyOpt(property, option, val); - file_arg_[flag] = ArFile; - } - } else { - if (property.compare("PROPERTY_FILE_EXT") == 0) { - set temp{val}; - file_arg_[flag]->setArgPropertyOpt(property, option, temp); - } else { - file_arg_[flag]->setArgPropertyOpt(property, option, val); - } - } - } else if (argname.compare("ARGUMENT_SWITCH") == 0) { - if (switch_arg_.count(flag) == 0) { - ArgumentSwitch* ArSwitch = new ArgumentSwitch; - if (val.compare("OFF") != 0 && val.compare("ON") != 0) { - throw invalid_argument("Unrecognized option for switch " + val); - } else { - ArSwitch->setArgPropertyOpt(property, option, val); - } - switch_arg_[flag] = ArSwitch; - } else { - if (val.compare("OFF") != 0 && val.compare("ON") != 0) { - throw invalid_argument("Unrecognized option for switch" + val); - } else { - switch_arg_[flag]->setArgPropertyOpt(property, option, val); - } - } - - } else if (argname.compare("ARGUMENT_STRING") == 0) { - if (str_arg_.count(flag) == 0) { - set temp{val}; - ArgumentString* ArStr = new ArgumentString; - ArStr->setArgPropertyOpt(property, option, temp); - str_arg_[flag] = ArStr; - } else { - set temp{val}; - str_arg_[flag]->setArgPropertyOpt(property, option, temp); - } - } else { - throw invalid_argument("Unrecognized string arg " + argname); - } -} - -void ArgumentParser::setFlagArgOpt(string flag, string argname, string property, - string option, set vals) { - - if (argname.compare("ARGUMENT_FILE") == 0) { - if (file_arg_.count(flag) == 0) { - ArgumentFile* ArFile = new ArgumentFile; - ArFile->setArgPropertyOpt(property, option, vals); - file_arg_[flag] = ArFile; - } else { - file_arg_[flag]->setArgPropertyOpt(property, option, vals); - } - } else if (argname.compare("ARGUMENT_STRING") == 0) { - if (str_arg_.count(flag) == 0) { - ArgumentString* ArStr = new ArgumentString; - ArStr->setArgPropertyOpt(property, option, vals); - str_arg_[flag] = ArStr; - } else { - str_arg_[flag]->setArgPropertyOpt(property, option, vals); - } - } else { - throw invalid_argument("Unrecognized set arg"); - } -} - -void ArgumentParser::setFlagArgOpt(string flag, string argname, string property, - string option, vector vals) { - - if (argname.compare("ARGUMENT_FILE") == 0) { - if (file_arg_.count(flag) == 0) { - ArgumentFile* ArFile = new ArgumentFile; - ArFile->setArgPropertyOpt(property, option, vals); - file_arg_[flag] = ArFile; - } else { - file_arg_[flag]->setArgPropertyOpt(property, option, vals); - } - } else { - throw invalid_argument("Unrecognized vector arg"); - } -} - -bool ArgumentParser::nextParameterIsAFlag_(size_t index, - vector arguments) { - - if ((index + 1) < arguments.size()) { - for (auto flag : flags_) { - if (flag.first.compare(arguments.at(index + 1)) == 0) { - return true; - } else if (flag.second.first.compare(arguments.at(index + 1)) == 0) { - return true; - } - } - } - return false; -} - -void ArgumentParser::parseArg_(size_t& index, vector arguments) { - string flag = arguments.at(index); - // If the abbreviated flag is passed we need to resolve the full flag name - if (flags_.count(flag) == 0) { - for (auto item : flags_) { - if (item.second.first.compare(flag) == 0) { - flag = item.first; - break; - } - } - } - - bool unrecognized = true; - if (str_arg_.count(flag) != 0) { - - if (!nextParameterIsAFlag_(index, arguments) || - str_arg_[flag]->requiresParameter()) { - - if ((index + 1) >= arguments.size()) { - string err = "" + flag + " Missing arguments"; - throw runtime_error(err); - } - string argument = arguments.at(index + 1); - str_arg_[flag]->argValid(argument); - unrecognized = false; - string_values_[flag] = argument; - ++index; - } - } - if (switch_arg_.count(flag) != 0) { - - if (!nextParameterIsAFlag_(index, arguments)) { - - if ((index + 1) >= arguments.size()) { - if (switch_arg_[flag]->requiresParameter()) { - string err = "" + flag + " Missing arguments"; - throw runtime_error(err); - } else { - unrecognized = false; - int_values_[flag] = 1; - } - } else { - string argument = arguments.at(index + 1); - switch_arg_[flag]->argValid(argument); - unrecognized = false; - string_values_[flag] = argument; - if (switch_arg_[flag]->positive(argument)) { - int_values_[flag] = 1; - } else { - int_values_[flag] = 0; - } - } - } else { - unrecognized = false; - int_values_[flag] = 1; - } - } - if (int_arg_.count(flag) != 0) { - if (!nextParameterIsAFlag_(index, arguments) || - int_arg_[flag]->requiresParameter()) { - if ((index + 1) >= arguments.size()) { - string err = "" + flag + " Missing arguments"; - throw runtime_error(err); - } - string argument = arguments.at(index + 1); - int_arg_[flag]->argValid(stoi(argument)); - unrecognized = false; - int_values_[flag] = stoi(argument); - ++index; - } - } - if (double_arg_.count(flag) != 0) { - if (!nextParameterIsAFlag_(index, arguments) || - double_arg_[flag]->requiresParameter()) { - if ((index + 1) >= arguments.size()) { - string err = "" + flag + " Missing arguments"; - throw runtime_error(err); - } - string argument = arguments.at(index + 1); - double_arg_[flag]->argValid(stod(argument)); - unrecognized = false; - double_values_[flag] = stod(argument); - ++index; - } - } - if (file_arg_.count(flag) != 0) { - if (!nextParameterIsAFlag_(index, arguments) || - file_arg_[flag]->requiresParameter()) { - if ((index + 1) >= arguments.size()) { - string err = "" + flag + " Missing arguments"; - throw runtime_error(err); - } - string argument = arguments.at(index + 1); - file_arg_[flag]->argValid(argument); - unrecognized = false; - string_values_[flag] = argument; - ++index; - } - } - - if (unrecognized) { - throw invalid_argument("The flag " + flag + " was unrecognized"); - } -} - -string ArgumentParser::getFlagArgOptValue(string flag, string argname, - string property, string option) { - - if (str_arg_.count(flag) != 0) { - auto argStr = str_arg_[flag]; - auto argName = argStr->getArgumentName(); - if (argName.compare(argname) == 0) { - return argStr->getPropertyValues(property, option); - } - } - if (switch_arg_.count(flag) != 0) { - auto argSwitch = switch_arg_[flag]; - auto argName = argSwitch->getArgumentName(); - if (argName.compare(argname) == 0) { - return argSwitch->getPropertyValues(property, option); - } - } - if (file_arg_.count(flag) != 0) { - auto argFile = file_arg_[flag]; - auto argName = argFile->getArgumentName(); - if (argName.compare(argname) == 0) { - return argFile->getPropertyValues(property, option); - } - } - if (int_arg_.count(flag) != 0) { - auto argInt = int_arg_[flag]; - auto argName = argInt->getArgumentName(); - if (argName.compare(argname) == 0) { - return argInt->getPropertyValues(property, option); - } - } - - throw invalid_argument("Unrecognized flag or argument " + flag + " " + - argname); -} - -int ArgumentParser::getInt(string flag) { - - if (int_values_.count(flag) == 0) { - if (switch_arg_.count(flag)) { - if (string_values_.count(flag)) { - if (switch_arg_[flag]->positive(string_values_[flag])) { - return 1; - } else { - return 0; - } - } - } - string err = "" + flag + - " does not contain an int. It is also possible that " - "you did not specify a default value"; - throw invalid_argument(err); - } - return int_values_[flag]; -} - -double ArgumentParser::getDouble(string flag) { - if (double_values_.count(flag) == 0) { - string err = "" + flag + - " does not contain a double. It is also possible that " - "you did not specify a default value"; - throw invalid_argument(err); - } - return double_values_[flag]; -} - -string ArgumentParser::getStr(string flag) { - if (string_values_.count(flag) == 0) { - if (switch_arg_.count(flag)) { - if (int_values_.count(flag)) { - if (switch_arg_[flag]->positive(int_values_[flag])) { - return "ON"; - } else { - return "OFF"; - } - } - } - string err = "" + flag + - " does not contain a string. It is also possible that " - "you did not specify a default value"; - throw invalid_argument(err); - } - return string_values_[flag]; -} - -size_t ArgumentParser::getSize_t(string flag) { - if (size_t_values_.count(flag) == 0) { - string err = "" + flag + - " does not contain a size_t. It is also possible that " - "you did not specify a default value"; - throw invalid_argument(err); - } - return size_t_values_[flag]; -} - -void ArgumentParser::postParseCheck(void) { - - for (auto str_arg : str_arg_) { - str_arg.second->postArgCheck(); - } - for (auto switch_arg : switch_arg_) { - switch_arg.second->postArgCheck(); - } - for (auto int_arg : int_arg_) { - int_arg.second->postArgCheck(); - } - for (auto double_arg : double_arg_) { - double_arg.second->postArgCheck(); - } - for (auto file_arg : file_arg_) { - file_arg.second->postArgCheck(); - } -} - -void ArgumentParser::parse(const char* argv[], int argc) { - - // Convert to vector of strings - vector arguments(argv, argv + argc); - - if (argc <= 1) { - cout << "Usage: " << arguments.at(0) << " SOURCES"; - showUsage(); - throw runtime_error("Must provide arguments"); - } - - string help_flag = "--help"; - string help_flag_short = "-h"; - string citation_flag = "--citation"; - string citation_flag_short = "-cite"; - string version_flag = "--version"; - string version_flag_short = "-version"; - - size_t allowed_args_before_exit = 2; - for (size_t index = 1; index < arguments.size(); ++index) { - if (help_flag.compare(arguments.at(index)) == 0 || - help_flag_short.compare(arguments.at(index)) == 0) { - cout << "Usage: " << arguments.at(0) << " SOURCES"; - showUsage(); - if (allowed_args_before_exit == arguments.size()) { - exit(0); - } - ++allowed_args_before_exit; - } else if (version_flag.compare(arguments.at(index)) == 0 || - version_flag_short.compare(arguments.at(index)) == 0) { - exit(0); - } else if (citation_flag.compare(arguments.at(index)) == 0 || - citation_flag_short.compare(arguments.at(index)) == 0) { - cout << "\nCitation: " << calcJ_AUTHOR_SURNAME << ", "; - cout << calcJ_AUTHOR_INITIALS << " ("; - cout << calcJ_YEAR_PUBLISHED << "). "; - cout << calcJ_TITLE << " (Version "; - cout << calcJ_VERSION_MAJOR << "."; - cout << calcJ_VERSION_MINOR << "). [Software]. Available from "; - cout << calcJ_URL << ".\n\n"; - if (allowed_args_before_exit == arguments.size()) { - exit(0); - } - ++allowed_args_before_exit; - } else { - parseArg_(index, arguments); - } - } - - postParseCheck(); -} diff --git a/src/libcatnip/io/argumentparser.hpp b/src/libcatnip/io/argumentparser.hpp deleted file mode 100644 index 34338b4..0000000 --- a/src/libcatnip/io/argumentparser.hpp +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef _CATNIP_ARGUMENTPARSER_HPP -#define _CATNIP_ARGUMENTPARSER_HPP -#include "../matrix.hpp" -#include "../parameters.hpp" -#include -#include -#include -#include - -#include "arguments/argumentdouble.hpp" -#include "arguments/argumentfile.hpp" -#include "arguments/argumentint.hpp" -#include "arguments/argumentstring.hpp" -#include "arguments/argumentswitch.hpp" - -namespace catnip { - -class ArgumentParser { - private: - // 1 - flag name - // 2 - type - std::map str_arg_; - std::map switch_arg_; - std::map int_arg_; - std::map double_arg_; - std::map file_arg_; - - // Known rules - std::set argument_types_; - - // Known flags and their description - std::map> flags_; - - std::map defaults_set_; - // Arguments that are stored when argc and argv are parsed - std::map int_values_; - std::map double_values_; - std::map string_values_; - std::map size_t_values_; - - void parseArg_(size_t& index, std::vector arguments); - - // Determine if the next value in arguments vector is a recognized flag - bool nextParameterIsAFlag_(size_t index, std::vector arguments); - - size_t maxShortFlagSize; - size_t maxFullFlagSize; - size_t maxDescriptionSize; - size_t maxLineLength = 80; - - public: - // 1 - short flag - // 2 - long flag - // 3 - description - explicit ArgumentParser(std::set> flags); - - // Set Defaults for the flags in the case that they are not found - void setFlagDefaultValue(std::string flag,const int & val); - void setFlagDefaultValue(std::string flag,const size_t & val); - void setFlagDefaultValue(std::string flag,const double & val); - void setFlagDefaultValue(std::string flag,const std::string & val); - - // Add a argument without setting any of the values - void addFlagArg(std::string flag, std::string argname); - // Set the rules for the flag and the type it is associated with types - // include: - // "FILE_EXT" - // "FILE_EXIST" - // "DOUBLE" - // "INT" - // "STRING" - // The rules are dependent on the type - void setFlagArgOpt(std::string flag, std::string argname, - std::string property, std::string option, int val); - - void setFlagArgOpt(std::string flag, std::string argname, - std::string property, std::string option, double val); - - void setFlagArgOpt(std::string flag, std::string argname, - std::string property, std::string option, std::string val); - - void setFlagArgOpt(std::string flag, std::string argname, - std::string property, std::string option, - std::set vals); - - void setFlagArgOpt(std::string flag, std::string argname, - std::string property, std::string option, - std::vector vals); - - std::string getFlagArgOptValue(std::string flag, std::string argname, - std::string property, std::string option); - - double getDouble(std::string flag); - int getInt(std::string flag); - std::string getStr(std::string flag); - size_t getSize_t(std::string flag); - - void postParseCheck(void); - - void parse(const char* argv[], int argc); - void showUsage(); -}; - -} // namespace catnip -#endif // _CATNIP_ARGUMENTPARSER_HPP diff --git a/src/libcatnip/io/arguments/Makefile b/src/libcatnip/io/arguments/Makefile deleted file mode 100644 index 64312c7..0000000 --- a/src/libcatnip/io/arguments/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -CC=g++ -CFLAGS= -Wall -Wextra -pedantic -std=c++11 - -all: test_argumentfile test_argumentswitch test_argumentint test_argumentdouble test_argumentstring - -test_argumentswitch: test_argumentswitch.cpp string_support.o argumentswitch.o propertyswitch.o - $(CC) $(CFLAGS) test_argumentswitch.cpp string_support.o argumentswitch.o propertyswitch.o -o test_argumentswitch - -argumentswitch.o : argumentswitch.cpp - $(CC) $(CFLAGS) -c argumentswitch.cpp - -test_argumentstring: test_argumentstring.cpp argumentstring.o string_support.o propertystring.o propertystringchoice.o - $(CC) $(CFLAGS) test_argumentstring.cpp argumentstring.o propertystring.o string_support.o propertystringchoice.o -o test_argumentstring - -argumentstring.o : argumentstring.cpp - $(CC) $(CFLAGS) -c argumentstring.cpp - -propertystring.o : PROPERTIES/propertystring.cpp - $(CC) $(CFLAGS) -c PROPERTIES/propertystring.cpp - -test_argumentdouble: test_argumentdouble.cpp argumentdouble.o string_support.o propertydouble.o - $(CC) $(CFLAGS) test_argumentdouble.cpp argumentdouble.o propertydouble.o string_support.o -o test_argumentdouble - -argumentdouble.o : argumentdouble.cpp - $(CC) $(CFLAGS) -c argumentdouble.cpp - -propertydouble.o : PROPERTIES/propertydouble.cpp - $(CC) $(CFLAGS) -c PROPERTIES/propertydouble.cpp - -test_argumentint: test_argumentint.cpp argumentint.o string_support.o propertyint.o - $(CC) $(CFLAGS) test_argumentint.cpp argumentint.o propertyint.o string_support.o -o test_argumentint - -argumentint.o : argumentint.cpp - $(CC) $(CFLAGS) -c argumentint.cpp - -test_argumentfile: test_argumentfile.cpp propertysisterfile.o argumentfile.o string_support.o propertyfileexist.o propertyfileext.o - $(CC) $(CFLAGS) test_argumentfile.cpp argumentfile.o propertysisterfile.o propertyfileexist.o propertyfileext.o string_support.o -o test_argumentfile - -argumentfile.o : argumentfile.cpp - $(CC) $(CFLAGS) -c argumentfile.cpp - -propertyswitch.o : PROPERTIES/propertyswitch.cpp - $(CC) $(CFLAGS) -c PROPERTIES/propertyswitch.cpp - -propertysisterfile.o : PROPERTIES/propertysisterfile.cpp - $(CC) $(CFLAGS) -c PROPERTIES/propertysisterfile.cpp - -propertyint.o : PROPERTIES/propertyint.cpp - $(CC) $(CFLAGS) -c PROPERTIES/propertyint.cpp - -propertyfileexist.o : PROPERTIES/propertyfileexist.cpp - $(CC) $(CFLAGS) -c PROPERTIES/propertyfileexist.cpp - -propertystringchoice.o : PROPERTIES/propertystringchoice.cpp - $(CC) $(CFLAGS) -c PROPERTIES/propertystringchoice.cpp - -propertyfileext.o : PROPERTIES/propertyfileext.cpp - $(CC) $(CFLAGS) -c PROPERTIES/propertyfileext.cpp - -string_support.o: ../../STRING_SUPPORT/string_support.cpp - $(CC) $(CFLAGS) -c ../../STRING_SUPPORT/string_support.cpp - -clean: - rm *.o test_argumentfile test_argumentswitch test_argumentint test_argumentdouble test_argumentstring diff --git a/src/libcatnip/io/arguments/README.md b/src/libcatnip/io/arguments/README.md deleted file mode 100644 index 93ba0f2..0000000 --- a/src/libcatnip/io/arguments/README.md +++ /dev/null @@ -1,10 +0,0 @@ - -# Arguments - -The arguments classes are used to define the criteria that the arguments passed in from the command line should meet. - -For instance if you are passing the a file name in then there will be an argument class for dealing with file names. If you are passing integer in there will be a argument class for deaing with integers. - -# Properties - -The properties classes are the criteria used to check the arguments. For instance if a file argument is passed in, for the file name to be valid maybe it needs to exist or have a relevant extension. There are properties defined for this kind of functionality. diff --git a/src/libcatnip/io/arguments/argumentdouble.cpp b/src/libcatnip/io/arguments/argumentdouble.cpp deleted file mode 100644 index 61735a3..0000000 --- a/src/libcatnip/io/arguments/argumentdouble.cpp +++ /dev/null @@ -1,14 +0,0 @@ - -#include "argumentdouble.hpp" -#include "properties/propertydouble.hpp" -#include - -using namespace catnip; -using namespace std; - -ArgumentDouble::ArgumentDouble(void) { registerProperties_(); } - -void ArgumentDouble::registerProperties_(void) { - PropertyDouble* prop_double = new PropertyDouble(); - double_propobjs_.push_back(prop_double); -} diff --git a/src/libcatnip/io/arguments/argumentdouble.hpp b/src/libcatnip/io/arguments/argumentdouble.hpp deleted file mode 100644 index 7d1b2f4..0000000 --- a/src/libcatnip/io/arguments/argumentdouble.hpp +++ /dev/null @@ -1,20 +0,0 @@ - -#ifndef _CATNIP_ARGUMENT_DOUBLE_HPP -#define _CATNIP_ARGUMENT_DOUBLE_HPP - -#include "argumentobject.hpp" -#include - -namespace catnip { - -class ArgumentDouble : public ArgumentObject { - private: - std::string getName_(void) const { return "ARGUMENT_DOUBLE"; } - void registerProperties_(void); - - public: - ArgumentDouble(void); -}; - -} // namespace catnip -#endif // _CATNIP_ARGUMENT_DOUBLE_HPP diff --git a/src/libcatnip/io/arguments/argumentfile.cpp b/src/libcatnip/io/arguments/argumentfile.cpp deleted file mode 100644 index 542c4af..0000000 --- a/src/libcatnip/io/arguments/argumentfile.cpp +++ /dev/null @@ -1,21 +0,0 @@ - -#include "argumentfile.hpp" -#include "properties/propertyfileexist.hpp" -#include "properties/propertyfileext.hpp" -#include "properties/propertysisterfile.hpp" -#include - -using namespace catnip; -using namespace std; - -ArgumentFile::ArgumentFile(void) { registerProperties_(); } - -void ArgumentFile::registerProperties_(void) { - - PropertyFileExist* prop_file_exist = new PropertyFileExist(); - int_propobjs_.push_back(prop_file_exist); - PropertyFileExt* prop_file_ext = new PropertyFileExt(); - string_set_propobjs_.push_back(prop_file_ext); - PropertySisterFile* prop_sis_file = new PropertySisterFile(); - string_vec_propobjs_.push_back(prop_sis_file); -} diff --git a/src/libcatnip/io/arguments/argumentfile.hpp b/src/libcatnip/io/arguments/argumentfile.hpp deleted file mode 100644 index 4b1e4c2..0000000 --- a/src/libcatnip/io/arguments/argumentfile.hpp +++ /dev/null @@ -1,21 +0,0 @@ - -#ifndef _CATNIP_ARGUMENT_FILE_HPP -#define _CATNIP_ARGUMENT_FILE_HPP - -#include "argumentobject.hpp" -#include - -namespace catnip { - -class ArgumentFile : public ArgumentObject { - private: - std::string getName_(void) const { return "ARGUMENT_FILE"; } - void registerProperties_(void); - - public: - ArgumentFile(void); -}; - -} // namespace catnip - -#endif // _CATNIP_ARGUMENT_FILE_HPP diff --git a/src/libcatnip/io/arguments/argumentint.cpp b/src/libcatnip/io/arguments/argumentint.cpp deleted file mode 100644 index 494e935..0000000 --- a/src/libcatnip/io/arguments/argumentint.cpp +++ /dev/null @@ -1,14 +0,0 @@ - -#include "argumentint.hpp" -#include "properties/propertyint.hpp" -#include - -using namespace catnip; -using namespace std; - -ArgumentInt::ArgumentInt(void) { registerProperties_(); } - -void ArgumentInt::registerProperties_(void) { - PropertyInt* prop_int = new PropertyInt; - int_propobjs_.push_back(prop_int); -} diff --git a/src/libcatnip/io/arguments/argumentint.hpp b/src/libcatnip/io/arguments/argumentint.hpp deleted file mode 100644 index e4040c5..0000000 --- a/src/libcatnip/io/arguments/argumentint.hpp +++ /dev/null @@ -1,21 +0,0 @@ - -#ifndef _CATNIP_ARGUMENT_INT_HPP -#define _CATNIP_ARGUMENT_INT_HPP - -#include "argumentobject.hpp" -#include - -namespace catnip { - -class ArgumentInt : public ArgumentObject { - private: - std::string getName_(void) const { return "ARGUMENT_INT"; } - void registerProperties_(void); - - public: - ArgumentInt(void); -}; - -} // namespace catnip - -#endif // _CATNIP_ARGUMENT_INT_HPP diff --git a/src/libcatnip/io/arguments/argumentobject.hpp b/src/libcatnip/io/arguments/argumentobject.hpp deleted file mode 100644 index a54b549..0000000 --- a/src/libcatnip/io/arguments/argumentobject.hpp +++ /dev/null @@ -1,428 +0,0 @@ - -#ifndef _CATNIP_ARGUMENTOBJECT_HPP -#define _CATNIP_ARGUMENTOBJECT_HPP - -#include "../../string_support.hpp" -#include "properties/propertyobject.hpp" -#include -#include -#include -#include -#include -#include - -namespace catnip { -// The template is simply for specifying the type of the argument coming -// from the command line -template -class ArgumentObject { - protected: - std::vector*> int_propobjs_; - std::vector*> double_propobjs_; - std::vector*> size_t_propobjs_; - std::vector*> string_propobjs_; - std::vector>*> string_set_propobjs_; - std::vector>*> - string_vec_propobjs_; - - virtual std::string getName_(void) const { return "UNKNOWN"; } - - void checkValid_(const S& val) const { - for (auto prop : int_propobjs_) { - prop->propValid(val); - } - for (auto prop : double_propobjs_) { - prop->propValid(val); - } - for (auto prop : size_t_propobjs_) { - prop->propValid(val); - } - for (auto prop : string_propobjs_) { - prop->propValid(val); - } - for (auto prop : string_set_propobjs_) { - prop->propValid(val); - } - for (auto prop : string_vec_propobjs_) { - prop->propValid(val); - } - } - - // Register the relevant properties - virtual void registerProperties_(void){}; - - public: - virtual ~ArgumentObject(void) { - - for (auto int_ptr : int_propobjs_) { - delete int_ptr; - } - int_propobjs_.clear(); - for (auto double_ptr : double_propobjs_) { - delete double_ptr; - } - double_propobjs_.clear(); - for (auto size_t_ptr : size_t_propobjs_) { - delete size_t_ptr; - } - size_t_propobjs_.clear(); - for (auto str_ptr : string_propobjs_) { - delete str_ptr; - } - string_propobjs_.clear(); - for (auto set_ptr : string_set_propobjs_) { - delete set_ptr; - } - string_set_propobjs_.clear(); - for (auto vec_ptr : string_vec_propobjs_) { - delete vec_ptr; - } - string_vec_propobjs_.clear(); - } - - // The argument object by default requires a parameter - virtual bool requiresParameter(void) { return true; } - - std::string getArgumentName(void) { return getName_(); } - - std::vector getProperties(void) { - std::vector props; - for (auto prop : int_propobjs_) { - props.push_back(prop->getPropertyName()); - } - for (auto prop : double_propobjs_) { - props.push_back(prop->getPropertyName()); - } - for (auto prop : size_t_propobjs_) { - props.push_back(prop->getPropertyName()); - } - for (auto prop : string_propobjs_) { - props.push_back(prop->getPropertyName()); - } - for (auto prop : string_set_propobjs_) { - props.push_back(prop->getPropertyName()); - } - for (auto prop : string_vec_propobjs_) { - props.push_back(prop->getPropertyName()); - } - - if (props.size() == 0) props.push_back("NO_PROPERTIES"); - return props; - } - - std::vector getPropertyOptions(void) { - std::vector ops; - for (auto prop : int_propobjs_) { - auto vec_opt = prop->getPropertyOptions(); - ops.insert(ops.end(), vec_opt.begin(), vec_opt.end()); - } - for (auto prop : double_propobjs_) { - auto vec_opt = prop->getPropertyOptions(); - ops.insert(ops.end(), vec_opt.begin(), vec_opt.end()); - } - for (auto prop : size_t_propobjs_) { - auto vec_opt = prop->getPropertyOptions(); - ops.insert(ops.end(), vec_opt.begin(), vec_opt.end()); - } - for (auto prop : string_propobjs_) { - auto vec_opt = prop->getPropertyOptions(); - ops.insert(ops.end(), vec_opt.begin(), vec_opt.end()); - } - for (auto prop : string_set_propobjs_) { - auto vec_opt = prop->getPropertyOptions(); - ops.insert(ops.end(), vec_opt.begin(), vec_opt.end()); - } - for (auto prop : string_vec_propobjs_) { - auto vec_opt = prop->getPropertyOptions(); - ops.insert(ops.end(), vec_opt.begin(), vec_opt.end()); - } - if (ops.size() == 0) ops.push_back("NO_OPTIONS"); - return ops; - } - - std::map getPropertyValues(void) { - std::map opts_values; - for (auto prop : int_propobjs_) { - auto vec_opt = prop->getPropertyOptions(); - for (auto opt : vec_opt) { - auto value = std::to_string(prop->getPropOption(opt)); - opts_values[opt] = value; - } - } - for (auto prop : double_propobjs_) { - auto vec_opt = prop->getPropertyOptions(); - for (auto opt : vec_opt) { - auto value = std::to_string(prop->getPropOption(opt)); - opts_values[opt] = value; - } - } - for (auto prop : size_t_propobjs_) { - auto vec_opt = prop->getPropertyOptions(); - for (auto opt : vec_opt) { - auto value = std::to_string(prop->getPropOption(opt)); - opts_values[opt] = value; - } - } - for (auto prop : string_propobjs_) { - auto vec_opt = prop->getPropertyOptions(); - for (auto opt : vec_opt) { - auto value = prop->getPropOption(opt); - opts_values[opt] = value; - } - } - for (auto prop : string_set_propobjs_) { - auto vec_opt = prop->getPropertyOptions(); - for (auto opt : vec_opt) { - std::set value_set = prop->getPropOption(opt); - std::string values = ""; - for (auto val : value_set) { - values.append(val); - values.append(" "); - } - trim(values); - opts_values[opt] = values; - } - } - for (auto prop : string_vec_propobjs_) { - auto vec_opt = prop->getPropertyOptions(); - for (auto opt : vec_opt) { - std::vector value_vec = prop->getPropOption(opt); - std::string values = ""; - for (auto val : value_vec) { - values.append(val); - values.append(" "); - } - trim(values); - opts_values[opt] = values; - } - } - return opts_values; - } - - std::string getPropertyValues(std::string property,const std::string & option) { - for (auto prop : int_propobjs_) { - if (property.compare(prop->getPropertyName()) == 0) { - auto vec_opt = prop->getPropertyOptions(); - for (auto opt : vec_opt) { - if (option.compare(opt) == 0) { - return std::to_string(prop->getPropOption(opt)); - } - } - } - } - for (auto prop : double_propobjs_) { - if (property.compare(prop->getPropertyName()) == 0) { - auto vec_opt = prop->getPropertyOptions(); - for (auto opt : vec_opt) { - if (option.compare(opt) == 0) { - return std::to_string(prop->getPropOption(opt)); - } - } - } - } - for (auto prop : size_t_propobjs_) { - if (property.compare(prop->getPropertyName()) == 0) { - auto vec_opt = prop->getPropertyOptions(); - for (auto opt : vec_opt) { - if (option.compare(opt) == 0) { - return std::to_string(prop->getPropOption(opt)); - } - } - } - } - for (auto prop : string_propobjs_) { - if (property.compare(prop->getPropertyName()) == 0) { - auto vec_opt = prop->getPropertyOptions(); - for (auto opt : vec_opt) { - if (option.compare(opt) == 0) { - return prop->getPropOption(opt); - } - } - } - } - for (auto prop : string_set_propobjs_) { - if (property.compare(prop->getPropertyName()) == 0) { - auto vec_opt = prop->getPropertyOptions(); - for (auto opt : vec_opt) { - if (option.compare(opt) == 0) { - std::set value_set = prop->getPropOption(opt); - std::string values = ""; - for (auto val : value_set) { - values.append(val); - values.append(" "); - } - trim(values); - return values; - } - } - } - } - for (auto prop : string_vec_propobjs_) { - if (property.compare(prop->getPropertyName()) == 0) { - auto vec_opt = prop->getPropertyOptions(); - for (auto opt : vec_opt) { - if (option.compare(opt) == 0) { - std::vector value_vec = prop->getPropOption(opt); - std::string values = ""; - for (auto val : value_vec) { - values.append(val); - values.append(" "); - } - trim(values); - return values; - } - } - } - } - - std::string err = - "Unable to recognize property or option " + property + " " + option; - throw std::invalid_argument(err); - } - - // Setup the valid options associated with the parameter - void setArgPropertyOpt(std::string property, std::string option, - const double& val) { - bool setval = false; - for (auto prop : double_propobjs_) { - if (property.compare(prop->getPropertyName()) == 0) { - prop->setPropOption(option, val); - setval = true; - } - } - if (!setval) { - std::string err = - "Argument property: " + property + " with option: " + - "" - "" + - option + " of type double is unrecognized for argument " + getName_(); - throw std::invalid_argument(err); - } - } - - void setArgPropertyOpt(std::string property, std::string option, - const std::set & val) { - bool setval = false; - for (auto prop = string_set_propobjs_.begin(); - prop != string_set_propobjs_.end(); ++prop) { - if (property.compare((*prop)->getPropertyName()) == 0) { - (*prop)->setPropOption(option, val); - setval = true; - } - } - if (!setval) { - std::string err = "Argument property: " + property + " with option: " + - "" - "" + - option + - " of type set is unrecognized for argument " + - "" - "" + - getName_(); - throw std::invalid_argument(err); - } - } - - void setArgPropertyOpt(std::string property, std::string option, - const std::vector & val) { - bool setval = false; - for (auto prop : string_vec_propobjs_) { - if (property.compare(prop->getPropertyName()) == 0) { - prop->setPropOption(option, val); - setval = true; - } - } - if (!setval) { - std::string err = - "Argument property: " + property + " with option: " + - "" - "" + - option + " of type vector is unrecognized for argument " + - "" - "" + - getName_(); - throw std::invalid_argument(err); - } - } - - void setArgPropertyOpt(std::string property,const std::string & option, - const std::string & val) { - bool setval = false; - for (auto prop : string_propobjs_) { - if (property.compare(prop->getPropertyName()) == 0) { - prop->setPropOption(option, val); - setval = true; - } - } - for (auto prop : string_vec_propobjs_) { - if (property.compare(prop->getPropertyName()) == 0) { - std::vector vec_str{val}; - prop->setPropOption(option, vec_str); - setval = true; - } - } - for (auto prop : string_set_propobjs_) { - if (property.compare(prop->getPropertyName()) == 0) { - std::set set_str{val}; - prop->setPropOption(option, set_str); - setval = true; - } - } - if (!setval) { - std::string err = - "Argument property: " + property + " with option: " + - "" - "" + - option + " of type string is unrecognized for argument " + getName_(); - throw std::invalid_argument(err); - } - } - - void setArgPropertyOpt(std::string property, const std::string & option, int val) { - bool setval = false; - for (auto prop : int_propobjs_) { - - if (property.compare(prop->getPropertyName()) == 0) { - prop->setPropOption(option, val); - setval = true; - } - } - if (!setval) { - std::string err = "Argument property: " + property + " with option: " + - "" - "" + - option + " of type int is unrecognized for argument " + - getName_(); - throw std::invalid_argument(err); - } - } - - bool argValid(const S& value) const { - checkValid_(value); - return true; - } - - void postArgCheck(void) { - for (auto prop : int_propobjs_) { - prop->postCheck(); - } - for (auto prop : double_propobjs_) { - prop->postCheck(); - } - for (auto prop : size_t_propobjs_) { - prop->postCheck(); - } - for (auto prop : string_propobjs_) { - prop->postCheck(); - } - for (auto prop : string_set_propobjs_) { - prop->postCheck(); - } - for (auto prop : string_vec_propobjs_) { - prop->postCheck(); - } - } -}; - -} // namespace catnip -#endif // _CATNIP_ARGUMENTOBJECT_HPP diff --git a/src/libcatnip/io/arguments/argumentstring.cpp b/src/libcatnip/io/arguments/argumentstring.cpp deleted file mode 100644 index 059264e..0000000 --- a/src/libcatnip/io/arguments/argumentstring.cpp +++ /dev/null @@ -1,17 +0,0 @@ - -#include "argumentstring.hpp" -#include "properties/propertystring.hpp" -#include "properties/propertystringchoice.hpp" -#include - -using namespace catnip; -using namespace std; - -ArgumentString::ArgumentString(void) { registerProperties_(); } - -void ArgumentString::registerProperties_(void) { - PropertyString* prop_string = new PropertyString; - size_t_propobjs_.push_back(prop_string); - PropertyStringChoice* prop_string_choice = new PropertyStringChoice; - string_set_propobjs_.push_back(prop_string_choice); -} diff --git a/src/libcatnip/io/arguments/argumentstring.hpp b/src/libcatnip/io/arguments/argumentstring.hpp deleted file mode 100644 index f32dedd..0000000 --- a/src/libcatnip/io/arguments/argumentstring.hpp +++ /dev/null @@ -1,21 +0,0 @@ - -#ifndef _CATNIP_ARGUMENT_STRING_HPP -#define _CATNIP_ARGUMENT_STRING_HPP - -#include "argumentobject.hpp" -#include - -namespace catnip { - -class ArgumentString : public ArgumentObject { - private: - std::string getName_(void) const { return "ARGUMENT_STRING"; } - void registerProperties_(void); - - public: - ArgumentString(void); -}; - -} // namespace catnip - -#endif // _CATNIP_ARGUMENT_STRING_HPP diff --git a/src/libcatnip/io/arguments/argumentswitch.cpp b/src/libcatnip/io/arguments/argumentswitch.cpp deleted file mode 100644 index 71ac538..0000000 --- a/src/libcatnip/io/arguments/argumentswitch.cpp +++ /dev/null @@ -1,25 +0,0 @@ - -#include "argumentswitch.hpp" -#include "properties/propertyswitch.hpp" -#include - -using namespace catnip; -using namespace std; - -ArgumentSwitch::ArgumentSwitch(void) { registerProperties_(); } - -void ArgumentSwitch::registerProperties_(void) { - PropertySwitch* prop_switch = new PropertySwitch; - string_propobjs_.push_back(prop_switch); -} - -bool ArgumentSwitch::positive(string val) const { - if (val.compare("ON") == 0 || val.compare("TRUE") == 0 || - val.compare("1") == 0) { - return true; - } else if (val.compare("OFF") == 0 || val.compare("FALSE") == 0 || - val.compare("0") == 0) { - return false; - } - throw invalid_argument("Argument value is unrecognized " + val); -} diff --git a/src/libcatnip/io/arguments/argumentswitch.hpp b/src/libcatnip/io/arguments/argumentswitch.hpp deleted file mode 100644 index d277e2d..0000000 --- a/src/libcatnip/io/arguments/argumentswitch.hpp +++ /dev/null @@ -1,22 +0,0 @@ - -#ifndef _CATNIP_ARGUMENT_SWITCH_HPP -#define _CATNIP_ARGUMENT_SWITCH_HPP - -#include "argumentobject.hpp" -#include - -namespace catnip { -class ArgumentSwitch : public ArgumentObject { - private: - std::string getName_(void) const { return "ARGUMENT_SWITCH"; } - void registerProperties_(void); - - public: - ArgumentSwitch(void); - bool requiresParameter(void) { return false; } - bool positive(int val) const { return ((val == 1) ? true : false); } - bool positive(std::string val) const; -}; - -} // namespace catnip -#endif // _CATNIP_ARGUMENT_SWITCH_HPP diff --git a/src/libcatnip/io/arguments/properties/propertydouble.cpp b/src/libcatnip/io/arguments/properties/propertydouble.cpp deleted file mode 100644 index 28f2a3b..0000000 --- a/src/libcatnip/io/arguments/properties/propertydouble.cpp +++ /dev/null @@ -1,33 +0,0 @@ - -#include "propertydouble.hpp" - -#include - -using namespace catnip; -using namespace std; - -PropertyDouble::PropertyDouble() { - setPropOption_("MIN", numeric_limits::lowest()); - setPropOption_("MAX", numeric_limits::max()); -} - -vector PropertyDouble::getOpts_(void) const { - vector options{"MIN", "MAX"}; - return options; -} - -void PropertyDouble::doubleValid(const double& val) { - if (val < getPropOption("MIN")) { - string err = "The value is smaller than allowed " + to_string(val) + - " the " - "minimum allowed value is " + - to_string(getPropOption("MIN")); - throw invalid_argument(err); - } else if (val > getPropOption("MAX")) { - string err = "The value is greater than allowed " + to_string(val) + - " the " - "maximum allowed value is " + - to_string(getPropOption("MAX")); - throw invalid_argument(err); - } -} diff --git a/src/libcatnip/io/arguments/properties/propertydouble.hpp b/src/libcatnip/io/arguments/properties/propertydouble.hpp deleted file mode 100644 index 284ae90..0000000 --- a/src/libcatnip/io/arguments/properties/propertydouble.hpp +++ /dev/null @@ -1,25 +0,0 @@ - -#ifndef _CATNIP_PROPERTY_DOUBLE_HPP -#define _CATNIP_PROPERTY_DOUBLE_HPP - -#include "propertyobject.hpp" - -namespace catnip { - -class PropertyDouble : public PropertyObject { - private: - void doubleValid(const double& val); - std::string getName_(void) const { return "PROPERTY_DOUBLE"; } - std::vector getOpts_(void) const; - - public: - PropertyDouble(void); - bool propValid(const double& value) { - doubleValid(value); - return true; - } -}; - -} // namespace catnip - -#endif // _CATNIP_PROPERTY_DOUBLE_HPP diff --git a/src/libcatnip/io/arguments/properties/propertyfileexist.cpp b/src/libcatnip/io/arguments/properties/propertyfileexist.cpp deleted file mode 100644 index df1bbbc..0000000 --- a/src/libcatnip/io/arguments/properties/propertyfileexist.cpp +++ /dev/null @@ -1,50 +0,0 @@ - -#include "propertyfileexist.hpp" -#include "../../../string_support.hpp" -#include -#include - -using namespace catnip; -using namespace std; - -PropertyFileExist::PropertyFileExist(void) { - setPropOption_("FILE_MUST_EXIST", 0); - setPropOption_("FILE_DOES_EXIST", 0); -} - -PropertyFileExist::PropertyFileExist(int fileMustExist) { - setPropOption_("FILE_MUST_EXIST", fileMustExist); -} - -vector PropertyFileExist::getOpts_(void) const { - vector options{"FILE_MUST_EXIST", "FILE_DOES_EXIST"}; - return options; -} - -bool PropertyFileExist::fileExist(const string& fileNamePath) const { - struct stat buf; - return (stat(fileNamePath.c_str(), &buf) == 0); -} - -bool PropertyFileExist::propValid(const string& fileNamePath) { - if (getPropOption("FILE_MUST_EXIST")) { - if (!fileExist(fileNamePath)) { - string err = "" + fileNamePath + " does not exist"; - throw invalid_argument(err); - } - setPropOption_("FILE_DOES_EXIST", 1); - } else { - if (fileExist(fileNamePath)) { - setPropOption_("FILE_DOES_EXIST", 1); - } - } - return true; -} - -void PropertyFileExist::postCheck(void) const { - auto must_exist = getPropOption("FILE_MUST_EXIST"); - auto exist = getPropOption("FILE_DOES_EXIST"); - if (must_exist && exist == 0) { - throw runtime_error("A necessary file is missing!"); - } -} diff --git a/src/libcatnip/io/arguments/properties/propertyfileexist.hpp b/src/libcatnip/io/arguments/properties/propertyfileexist.hpp deleted file mode 100644 index 7529004..0000000 --- a/src/libcatnip/io/arguments/properties/propertyfileexist.hpp +++ /dev/null @@ -1,25 +0,0 @@ - -#ifndef _CATNIP_PROPERTY_FILEEXIST_HPP -#define _CATNIP_PROPERTY_FILEEXIST_HPP - -#include "propertyobject.hpp" -#include - -namespace catnip { - -class PropertyFileExist : public PropertyObject { - private: - bool fileExist(const std::string &) const; - std::string getName_(void) const { return "PROPERTY_FILE_EXIST"; } - std::vector getOpts_(void) const; - - public: - explicit PropertyFileExist(void); - PropertyFileExist(int fileMustExist); - bool propValid(const std::string &fileName); - void postCheck(void) const; -}; - -} // namespace catnip - -#endif // _CATNIP_PROPERTY_FILEEXIST_HPP diff --git a/src/libcatnip/io/arguments/properties/propertyfileext.cpp b/src/libcatnip/io/arguments/properties/propertyfileext.cpp deleted file mode 100644 index 670a889..0000000 --- a/src/libcatnip/io/arguments/properties/propertyfileext.cpp +++ /dev/null @@ -1,84 +0,0 @@ - -#include "propertyfileext.hpp" -#include "../../../string_support.hpp" -#include -#include - -using namespace catnip; -using namespace std; - -PropertyFileExt::PropertyFileExt(void) { - set exts_; - exts_.insert("*"); - setPropOption_("ALLOWED_FILE_EXT", exts_); -} - -PropertyFileExt::PropertyFileExt(string ext) { - checkExt(ext); - set exts_; - exts_.insert(ext); - setPropOption_("ALLOWED_FILE_EXT", exts_); -} - -PropertyFileExt::PropertyFileExt(set exts) { - set exts_; - for (auto ext : exts) { - checkExt(ext); - exts_.insert(ext); - } - setPropOption_("ALLOWED_FILE_EXT", exts_); -} - -vector PropertyFileExt::getOpts_(void) const { - vector options{"ALLOWED_FILE_EXT"}; - return options; -} - -void PropertyFileExt::extSupported(const string& ext) const { - checkExt(ext); - auto exts_ = getPropOption("ALLOWED_FILE_EXT"); - for (auto ext_ : exts_) { - if (ext_[0] == '*') { - return; - } else if (ext_.compare(ext) == 0) { - return; - } - } - string err = "The file ext " + ext + " is unsupported"; - throw invalid_argument(err); -} - -void PropertyFileExt::checkExt(const string& ext) const { - if (ext.compare("") == 0) { - return; - } else if (ext[0] == '*') { - return; - } else { - string excess = grabStrBeforeLastOccurance(ext, "."); - if (excess.compare("") != 0) { - throw invalid_argument( - "An extension must be of type '.ext','*','', " - "you have used " + - ext); - } - } - return; -} - -void PropertyFileExt::setPropOption(std::string option, - std::set vars) { - PropertyObject::setPropOption(option, vars); -} - -void PropertyFileExt::setPropOption(std::string option, std::string var) { - set vars; - vars.insert(var); - PropertyObject::setPropOption(option, vars); -} - -bool PropertyFileExt::propValid(const string& fileNamePath) { - string fileName = lastStringInPath(fileNamePath); - string ext = grabStrAfterLastOccuranceInclusive(fileName, "."); - extSupported(ext); - return true; -} diff --git a/src/libcatnip/io/arguments/properties/propertyfileext.hpp b/src/libcatnip/io/arguments/properties/propertyfileext.hpp deleted file mode 100644 index 7cf4b41..0000000 --- a/src/libcatnip/io/arguments/properties/propertyfileext.hpp +++ /dev/null @@ -1,28 +0,0 @@ - -#ifndef _CATNIP_PROPERTY_FILEEXT_HPP -#define _CATNIP_PROPERTY_FILEEXT_HPP - -#include "propertyobject.hpp" -#include - -namespace catnip { - -class PropertyFileExt - : public PropertyObject > { - private: - void checkExt(const std::string &) const; - void extSupported(const std::string &) const; - std::string getName_(void) const { return "PROPERTY_FILE_EXT"; } - std::vector getOpts_(void) const; - - public: - explicit PropertyFileExt(void); - explicit PropertyFileExt(std::string ext); - PropertyFileExt(std::set exts); - bool propValid(const std::string &fileNamePath); - void setPropOption(std::string option, std::string var); - void setPropOption(std::string option, std::set var); -}; - -} // namespace catnip -#endif // _CATNIP_PROPERTY_FILEEXT_HPP diff --git a/src/libcatnip/io/arguments/properties/propertyint.cpp b/src/libcatnip/io/arguments/properties/propertyint.cpp deleted file mode 100644 index e772223..0000000 --- a/src/libcatnip/io/arguments/properties/propertyint.cpp +++ /dev/null @@ -1,33 +0,0 @@ - -#include "propertyint.hpp" - -#include - -using namespace catnip; -using namespace std; - -PropertyInt::PropertyInt() { - setPropOption_("MIN", numeric_limits::min()); - setPropOption_("MAX", numeric_limits::max()); -} - -vector PropertyInt::getOpts_(void) const { - vector options{"MIN", "MAX"}; - return options; -} - -void PropertyInt::intValid(const int& val) const { - if (val < getPropOption("MIN")) { - string err = "The value is smaller than allowed " + to_string(val) + - " the " - "minimum allowed value is " + - to_string(getPropOption("MIN")); - throw invalid_argument(err); - } else if (val > getPropOption("MAX")) { - string err = "The value is greater than allowed " + to_string(val) + - " the " - "maximum allowed value is " + - to_string(getPropOption("MAX")); - throw invalid_argument(err); - } -} diff --git a/src/libcatnip/io/arguments/properties/propertyint.hpp b/src/libcatnip/io/arguments/properties/propertyint.hpp deleted file mode 100644 index 6c20107..0000000 --- a/src/libcatnip/io/arguments/properties/propertyint.hpp +++ /dev/null @@ -1,25 +0,0 @@ - -#ifndef _CATNIP_PROPERTY_INT_HPP -#define _CATNIP_PROPERTY_INT_HPP - -#include "propertyobject.hpp" - -namespace catnip { - -class PropertyInt : public PropertyObject { - private: - void intValid(const int& val) const; - std::string getName_(void) const { return "PROPERTY_INT"; } - std::vector getOpts_(void) const; - - public: - PropertyInt(void); - bool propValid(const int& value) { - intValid(value); - return true; - } -}; - -} // namespace catnip - -#endif // _CATNIP_PROPERTY_INT_HPP diff --git a/src/libcatnip/io/arguments/properties/propertyobject.hpp b/src/libcatnip/io/arguments/properties/propertyobject.hpp deleted file mode 100644 index 584c662..0000000 --- a/src/libcatnip/io/arguments/properties/propertyobject.hpp +++ /dev/null @@ -1,86 +0,0 @@ - -#ifndef _CATNIP_PROPERTY_OBJECT_HPP -#define _CATNIP_PROPERTY_OBJECT_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace catnip { - -template -class PropertyObject { - protected: - // Map key is the option name and the type "int, double etc" - // void * points to the correct value for that type - std::map options_; - - bool propOptionValid_(const std::string &option) const { - for (const auto &opt : options_) { - if (opt.first.compare(option) == 0) return true; - } - return false; - } - - void setPropOption_(const std::string &option, const T &val) { - - if (options_.count(option) == 0) { - T *opt = new T(val); - options_[option] = static_cast(opt); - } else { - T *opt = static_cast(options_[option]); - *opt = val; - } - } - - virtual std::string getName_(void) const { return "UNKNOWN"; } - - virtual std::vector getOpts_(void) const { - std::vector options{"NO_OPTIONS"}; - return options; - } - - public: - virtual ~PropertyObject(void) { - for (auto itr : options_) { - T *opt = static_cast(itr.second); - delete opt; - } - options_.clear(); - } - - virtual bool propValid(const S &value) = 0; - - std::string getPropertyName(void) const { return getName_(); } - - std::vector getPropertyOptions(void) const { return getOpts_(); } - - // Setup the valid options associated with the parameter - void setPropOption(std::string option, const T & val) { - if (!propOptionValid_(option)) { - throw std::invalid_argument("Property option is unrecognized " + option); - } - setPropOption_(option, val); - } - - T getPropOption(const std::string &option) const { - if (!propOptionValid_(option)) { - std::string err = "" + option + - " is an unrecognized property option for " - "property " + - getName_(); - throw std::invalid_argument(err); - } - return *(static_cast(options_.at(option))); - } - - virtual void postCheck(void) const { return; } -}; - -} // namespace catnip -#endif // _CATNIP_PROPERTY_OBJECT_HPP diff --git a/src/libcatnip/io/arguments/properties/propertysisterfile.cpp b/src/libcatnip/io/arguments/properties/propertysisterfile.cpp deleted file mode 100644 index c1df59f..0000000 --- a/src/libcatnip/io/arguments/properties/propertysisterfile.cpp +++ /dev/null @@ -1,153 +0,0 @@ - -#include "propertysisterfile.hpp" -#include "../../../string_support.hpp" -#include -#include - -using namespace catnip; -using namespace std; - -PropertySisterFile::PropertySisterFile(void) { - string var = "NOT_DEFINED"; - vector vec_var{var}; - setPropOption_("ALLOWED_SISTER_FILE_EXT", vec_var); - setPropOption_("SISTER_FILE_NAME", vec_var); - setPropOption_("SISTER_FILE_PATH", vec_var); - setPropOption_("SISTER_FILE_PATH_NAME", vec_var); - vector vec_var2{"false"}; - setPropOption_("SISTER_FILE_EXISTS", vec_var2); -} - -vector PropertySisterFile::getOpts_(void) const { - vector options; - options.push_back("ALLOWED_SISTER_FILE_EXT"); - options.push_back("SISTER_FILE_NAME"); - options.push_back("SISTER_FILE_PATH"); - options.push_back("SISTER_FILE_PATH_NAME"); - options.push_back("SISTER_FILE_EXISTS"); - return options; -} - -bool PropertySisterFile::fileExist(const string& fileNamePath) const { - struct stat buf; - return (stat(fileNamePath.c_str(), &buf) == 0); -} - -void PropertySisterFile::extSupported(const string& ext) const { - checkExt(ext); - auto exts_ = getPropOption("ALLOWED_SISTER_FILE_EXT"); - for (auto ext_ : exts_) { - if (ext_.compare(ext) == 0) { - return; - } - } - string err = "The file ext " + ext + " is unsupported"; - throw invalid_argument(err); -} - -void PropertySisterFile::checkExt(const string& ext) const { - string excess = grabStrBeforeLastOccurance(ext, "."); - if (excess.compare("") != 0) { - throw invalid_argument( - "An extension must be of type '.ext'" - "you have used " + - ext); - } - return; -} - -void PropertySisterFile::setPropOption(std::string option, - const std::string& var) { - - if (option.compare("ALLOWED_SISTER_FILE_EXT") == 0) { - checkExt(var); - vector vec_var{var}; - setPropOption_(option, vec_var); - return; - } - if (option.compare("SISTER_FILE_EXISTS") == 0 || - option.compare("SISTER_FILE_NAME") == 0 || - option.compare("SISTER_FILE_PATH") == 0 || - option.compare("SISTER_FILE_PATH_NAME") == 0) { - throw invalid_argument( - "This option is determined internally you do not have permission to " - "change it"); - } - throw invalid_argument("Unrecognized option value combo " + option + " " + - var); -} - -void PropertySisterFile::setPropOption(std::string option, - vector vec_vars) { - - if (option.compare("ALLOWED_SISTER_FILE_EXT") == 0) { - vector fileNames; - vector filePaths; - vector filePathNames; - vector fileExists; - string notdef = "NOT_DEFINED"; - - for (auto var : vec_vars) { - checkExt(var); - fileNames.push_back(notdef); - filePaths.push_back(notdef); - filePathNames.push_back(notdef); - fileExists.push_back("false"); - } - setPropOption_(option, vec_vars); - return; - } - if (option.compare("SISTER_FILE_EXISTS") == 0 || - option.compare("SISTER_FILE_NAME") == 0 || - option.compare("SISTER_FILE_PATH") == 0 || - option.compare("SISTER_FILE_PATH_NAME") == 0) { - throw invalid_argument( - "This option is determined internally you do not have permission to " - "change it"); - } - - string vars = ""; - for (auto var : vec_vars) { - vars.append(var); - vars.append(" "); - } - trim(vars); - throw invalid_argument("Unrecognized option value combo " + option + " " + - vars); -} - -bool PropertySisterFile::propValid(const string& fileNamePath) { - - string fileName = lastStringInPath(fileNamePath); - string path = getPath(fileNamePath); - - string sisterFileCore = grabStrBeforeLastOccurance(fileName, "."); - auto sister_exts = getPropOption("ALLOWED_SISTER_FILE_EXT"); - - vector fileNames; - vector filePaths; - vector filePathNames; - vector fileExists; - - for (auto sister_ext : sister_exts) { - - if (sister_ext.compare("NOT_DEFINED") != 0) { - string sisterFileName = sisterFileCore + sister_ext; - string sisterPath = path + sisterFileName; - - fileNames.push_back(sisterFileName); - filePaths.push_back(path); - filePathNames.push_back(sisterPath); - if (fileExist(sisterPath)) { - fileExists.push_back("true"); - } else { - fileExists.push_back("false"); - } - } - } - setPropOption_("SISTER_FILE_NAME", fileNames); - setPropOption_("SISTER_FILE_PATH", filePaths); - setPropOption_("SISTER_FILE_PATH_NAME", filePathNames); - setPropOption_("SISTER_FILE_EXISTS", fileExists); - return true; -} diff --git a/src/libcatnip/io/arguments/properties/propertysisterfile.hpp b/src/libcatnip/io/arguments/properties/propertysisterfile.hpp deleted file mode 100644 index b7fdaec..0000000 --- a/src/libcatnip/io/arguments/properties/propertysisterfile.hpp +++ /dev/null @@ -1,27 +0,0 @@ - -#ifndef _CATNIP_PROPERTY_SISTER_FILE_HPP -#define _CATNIP_PROPERTY_SISTER_FILE_HPP - -#include "propertyobject.hpp" -#include - -namespace catnip { - -class PropertySisterFile - : public PropertyObject> { - private: - std::string getName_(void) const { return "PROPERTY_SISTER_FILE"; } - std::vector getOpts_(void) const; - bool fileExist(const std::string &) const; - void extSupported(const std::string &) const; - void checkExt(const std::string &) const; - - public: - PropertySisterFile(void); - void setPropOption(std::string option, const std::string &var); - void setPropOption(std::string option, std::vector var); - bool propValid(const std::string &fileNamePath); -}; - -} // namespace catnip -#endif // _CATNIP_PROPERTY_SISTER_FILE_HPP diff --git a/src/libcatnip/io/arguments/properties/propertystring.cpp b/src/libcatnip/io/arguments/properties/propertystring.cpp deleted file mode 100644 index 93fdcc7..0000000 --- a/src/libcatnip/io/arguments/properties/propertystring.cpp +++ /dev/null @@ -1,32 +0,0 @@ - -#include "propertystring.hpp" -#include - -using namespace catnip; -using namespace std; - -PropertyString::PropertyString(void) { - setPropOption_("MIN_LENGTH", 0); - setPropOption_("MAX_LENGTH", (size_t)-1); -} - -vector PropertyString::getOpts_(void) const { - vector options{"MIN_LENGTH", "MAX_LENGTH"}; - return options; -} - -void PropertyString::stringValid(const string& val) const { - if (val.size() > getPropOption("MAX_LENGTH")) { - string err = "The string is larger than allowed " + val + - " the " - "maximum allowed value is " + - to_string(getPropOption("MAX_LENGTH")); - throw invalid_argument(err); - } else if (val.size() < getPropOption("MIN_LENGTH")) { - string err = "The string is smaller than allowed " + val + - " the " - "maximum allowed value is " + - to_string(getPropOption("MIN_LENGTH")); - throw invalid_argument(err); - } -} diff --git a/src/libcatnip/io/arguments/properties/propertystring.hpp b/src/libcatnip/io/arguments/properties/propertystring.hpp deleted file mode 100644 index e331325..0000000 --- a/src/libcatnip/io/arguments/properties/propertystring.hpp +++ /dev/null @@ -1,24 +0,0 @@ - -#ifndef _CATNIP_PROPERTY_STRING_HPP -#define _CATNIP_PROPERTY_STRING_HPP - -#include "propertyobject.hpp" - -namespace catnip { - -class PropertyString : public PropertyObject { - private: - void stringValid(const std::string& val) const; - std::string getName_(void) const { return "PROPERTY_STRING"; } - std::vector getOpts_(void) const; - - public: - PropertyString(void); - bool propValid(const std::string& value) { - stringValid(value); - return true; - } -}; - -} // namespace catnip -#endif // _CATNIP_PROPERTY_STRING_HPP diff --git a/src/libcatnip/io/arguments/properties/propertystringchoice.cpp b/src/libcatnip/io/arguments/properties/propertystringchoice.cpp deleted file mode 100644 index a8f1116..0000000 --- a/src/libcatnip/io/arguments/properties/propertystringchoice.cpp +++ /dev/null @@ -1,98 +0,0 @@ - -#include "propertystringchoice.hpp" -#include "../../../string_support.hpp" -#include -#include - -using namespace catnip; -using namespace std; - -PropertyStringChoice::PropertyStringChoice(void) { - set set_var1{"false"}; - setPropOption_("STRING_CHOICE_ENFORCED", set_var1); - string str = "NOT_DEFINED"; - set set_var2{str}; - setPropOption_("STRING_CHOICES", set_var2); -} - -vector PropertyStringChoice::getOpts_(void) const { - vector options; - options.push_back("STRING_CHOICE_ENFORCED"); - options.push_back("STRING_CHOICES"); - return options; -} - -void PropertyStringChoice::setPropOption(std::string option, std::string var) { - - if (option.compare("STRING_CHOICE_ENFORCED") == 0) { - if (var.compare("false") == 0 || var.compare("true") == 0) { - set set_var{var}; - setPropOption_(option, set_var); - return; - } else { - throw invalid_argument("The option " + option + - " can only be set to values" - " of true or false you have set it to " + - var); - } - } else if (option.compare("STRING_CHOICES") == 0) { - set set_var{var}; - setPropOption_(option, set_var); - } - throw invalid_argument("Unrecognized option value combo " + option + " " + - var); -} - -void PropertyStringChoice::setPropOption(std::string option, - set set_vars) { - - if (option.compare("STRING_CHOICES") == 0) { - setPropOption_(option, set_vars); - return; - } else if (option.compare("STRING_CHOICE_ENFORCED") == 0) { - if (set_vars.size() > 1) { - string err = ""; - for (auto var : set_vars) { - err.append(var); - err.append(" "); - } - trim(err); - throw invalid_argument( - "Option STRING_CHOICE_ENFORCED only accepts one " - "value either true or false you have passed the following values " + - err); - } - - string var = *(set_vars.begin()); - if (var.compare("false") == 0 || var.compare("true") == 0) { - setPropOption_(option, set_vars); - return; - } else { - throw invalid_argument("The option " + option + - " can only be set to values" - " of true or false you have set it to " + - var); - } - } - string vars = ""; - for (auto var : set_vars) { - vars.append(var); - vars.append(" "); - } - trim(vars); - throw invalid_argument("Unrecognized option value combo " + option + " " + - vars); -} - -bool PropertyStringChoice::propValid(const string& string_choice) { - - set opt_val = getPropOption("STRING_CHOICE_ENFORCED"); - string val = *(opt_val.begin()); - if (val.compare("true") == 0) { - set str_choices = getPropOption("STRING_CHOICES"); - if (str_choices.count(string_choice) > 0) return true; - throw invalid_argument("The value " + string_choice + - " is not a valid option"); - } - return true; -} diff --git a/src/libcatnip/io/arguments/properties/propertystringchoice.hpp b/src/libcatnip/io/arguments/properties/propertystringchoice.hpp deleted file mode 100644 index 580d816..0000000 --- a/src/libcatnip/io/arguments/properties/propertystringchoice.hpp +++ /dev/null @@ -1,24 +0,0 @@ - -#ifndef _CATNIP_PROPERTY_STRING_CHOICE_HPP -#define _CATNIP_PROPERTY_STRING_CHOICE_HPP - -#include "propertyobject.hpp" -#include - -namespace catnip { - -class PropertyStringChoice - : public PropertyObject> { - private: - std::string getName_(void) const { return "PROPERTY_STRING_CHOICE"; } - std::vector getOpts_(void) const; - - public: - PropertyStringChoice(void); - void setPropOption(std::string option, std::string var); - void setPropOption(std::string option, std::set var); - bool propValid(const std::string& string_choice); -}; - -} // namespace catnip -#endif // _CATNIP_PROPERTY_STRING_CHOICE_HPP diff --git a/src/libcatnip/io/arguments/properties/propertyswitch.cpp b/src/libcatnip/io/arguments/properties/propertyswitch.cpp deleted file mode 100644 index 9fa1c90..0000000 --- a/src/libcatnip/io/arguments/properties/propertyswitch.cpp +++ /dev/null @@ -1,40 +0,0 @@ - -#include "propertyswitch.hpp" - -#include - -using namespace catnip; -using namespace std; - -PropertySwitch::PropertySwitch() { setPropOption_("DEFAULT", "OFF"); } - -vector PropertySwitch::getOpts_(void) const { - vector options{"DEFAULT"}; - return options; -} - -void PropertySwitch::switchValid(int val) const { - if (val < 0 || val > 1) { - string err = - "Switches are only allowed to be on or off. By default they " - "are set to off. An integer may be provided to the switch to " - "toggle the behavior, however the integer is only allowed to " - "be a 1 or a 0 you have provided a " + - to_string(val); - throw invalid_argument(err); - } -} - -void PropertySwitch::switchValid(std::string val) const { - if (val.compare("0") != 0 && val.compare("1") != 0 && - val.compare("ON") != 0 && val.compare("OFF") != 0 && - val.compare("TRUE") != 0 && val.compare("FALSE") != 0) { - string err = - "Switches are only allowed to be on or off. By default they " - "are set to off. A string may be provided to the switch to " - "toggle the behavior, however the string is only allowed to " - "be a TRUE/FALSE/ON/OFF you have provided a " + - val; - throw invalid_argument(err); - } -} diff --git a/src/libcatnip/io/arguments/properties/propertyswitch.hpp b/src/libcatnip/io/arguments/properties/propertyswitch.hpp deleted file mode 100644 index dd9535d..0000000 --- a/src/libcatnip/io/arguments/properties/propertyswitch.hpp +++ /dev/null @@ -1,31 +0,0 @@ - -#ifndef _CATNIP_PROPERTY_SWITCH_HPP -#define _CATNIP_PROPERTY_SWITCH_HPP - -#include "propertyobject.hpp" - -namespace catnip { - -class PropertySwitch : public PropertyObject { - private: - std::string getName_(void) const { return "PROPERTY_SWITCH"; } - std::vector getOpts_(void) const; - void propOptionValueSettingValid_(); - void switchValid(int val) const; - void switchValid(std::string val) const; - - public: - PropertySwitch(void); - bool propValid(int value) { - switchValid(value); - return true; - } - bool propValid(const std::string& value) { - switchValid(value); - return true; - } - bool propValid() { return true; } -}; - -} // namespace catnip -#endif // _CATNIP_PROPERTY_SWITCH_HPP diff --git a/src/libcatnip/io/file_readers/filereader.cpp b/src/libcatnip/io/file_readers/filereader.cpp index 1fd77ea..ffdd5f2 100644 --- a/src/libcatnip/io/file_readers/filereader.cpp +++ b/src/libcatnip/io/file_readers/filereader.cpp @@ -24,8 +24,6 @@ void FileReader::read() { close(); } -// Private member functions - void FileReader::open() { if (!fileExist_()) { throw invalid_argument("File " + fileName_ + " does not exist."); @@ -39,6 +37,7 @@ void FileReader::close() { fileOpen_ = false; } +// Private member functions void FileReader::registerSections_() { checkSections_(); } // Basically check that for a given tag both a section reader diff --git a/src/libcatnip/io/file_readers/filereader.hpp b/src/libcatnip/io/file_readers/filereader.hpp index 91d374d..55d2f1d 100644 --- a/src/libcatnip/io/file_readers/filereader.hpp +++ b/src/libcatnip/io/file_readers/filereader.hpp @@ -1,4 +1,4 @@ - +#pragma once #ifndef _CATNIP_FILEREADER_HPP_ #define _CATNIP_FILEREADER_HPP_ diff --git a/src/libcatnip/io/file_readers/logreader.cpp b/src/libcatnip/io/file_readers/logreader.cpp index d5326f9..5db3fdd 100644 --- a/src/libcatnip/io/file_readers/logreader.cpp +++ b/src/libcatnip/io/file_readers/logreader.cpp @@ -7,6 +7,7 @@ #include #include +#include #include "../../log.hpp" #include "../../string_support.hpp" #include "logreader.hpp" @@ -126,6 +127,7 @@ void LogReader::AOFunctionSectionReader(void *ptr) { while (!iss.eof()) { string Tot_Alpha_Beta_Spin; iss >> Tot_Alpha_Beta_Spin; + trim(Tot_Alpha_Beta_Spin); orbVals.push_back(stod(Tot_Alpha_Beta_Spin)); } LR_ptr->orb_[make_pair(atom_num, elemType)][orbType] = orbVals; @@ -165,7 +167,6 @@ void LogReader::AOFunctionSectionReader(void *ptr) { } ++atom_num; - // getline(LR_ptr->fid_,line); if (foundSubStrInStr(line, end_pattern)) { sectionEnd = true; } @@ -194,9 +195,12 @@ void LogReader::OverlapSectionReader(void *ptr) { getline(LR_ptr->fid_, line); istringstream iss(line); iss >> countC; + if( line.find("Kinetic")!=string::npos){ + break; + } int countCint = stoi(countC); if (countCint != (countCoef + 1)) { - endFirstSection = true; + break; } else { ++countCoef; vector row; @@ -214,20 +218,14 @@ void LogReader::OverlapSectionReader(void *ptr) { } // Create a matrix and place all the current values in there - Matrix *mat_S = new Matrix(countCoef, countCoef); + + Eigen::MatrixXd matrix_S(countCoef,countCoef); + for (size_t row_ind = 0; row_ind < first_coefs.size(); ++row_ind) { - vector row = first_coefs.at(row_ind); - size_t col_ind = 1; - for (auto val : row) { - mat_S->set_elem(val, row_ind + 1, col_ind); - // Because diagonally symetric - if (row_ind + 1 != col_ind) { - mat_S->set_elem(val, col_ind, row_ind + 1); - } - ++col_ind; - } + Eigen::Map eigen_row((first_coefs.at(row_ind).data()),first_coefs.at(row_ind).size()); + matrix_S.block(row_ind,0,1,eigen_row.size()) = eigen_row; + matrix_S.block(0,row_ind,eigen_row.size(),1) = eigen_row.transpose(); } - int sectionReads = countCoef / 5; if (countCoef % 5 > 0) { ++sectionReads; @@ -243,19 +241,16 @@ void LogReader::OverlapSectionReader(void *ptr) { istringstream iss(line); string dummy; iss >> dummy; - int localCoefCount = 1; + int localCoefCount = 0; while (!iss.eof()) { string s_coef; iss >> s_coef; string val = grabStrBeforeFirstOccurance(s_coef, "D"); string expon = grabStrAfterFirstOccurance(s_coef, "D"); double value = stod(val) * pow(10.0, stod(expon)); - mat_S->set_elem(value, sectionCoef + 1, - currentSectionStart + localCoefCount); - if ((sectionCoef + 1) != (currentSectionStart + localCoefCount)) { - - mat_S->set_elem(value, currentSectionStart + localCoefCount, - sectionCoef + 1); + matrix_S(sectionCoef,currentSectionStart + localCoefCount) = value; + if ((sectionCoef) != (currentSectionStart + localCoefCount)) { + matrix_S(currentSectionStart + localCoefCount,sectionCoef) = value; } ++localCoefCount; } @@ -265,7 +260,8 @@ void LogReader::OverlapSectionReader(void *ptr) { currentSectionStart += 5; getline(LR_ptr->fid_, line); } - LR_ptr->S_ = mat_S; + + LR_ptr->S_ = matrix_S; LOG("Success reading Overlap coefficients from .log file", 2); return; } @@ -291,7 +287,7 @@ void LogReader::ReadOrbEnergies(const string &orb_type) { auto vec_str = splitStEnergies(line); for (size_t inc = 4; inc < vec_str.size(); inc++) { - OREnergies[orb_type].push_back((double)atof(vec_str.at(inc).c_str())); + OREnergies[orb_type].push_back(stod(vec_str.at(inc))); if (occFound) homoLevel[orb_type]++; } } else { diff --git a/src/libcatnip/io/file_readers/logreader.hpp b/src/libcatnip/io/file_readers/logreader.hpp index 46cde5d..4ec11a4 100644 --- a/src/libcatnip/io/file_readers/logreader.hpp +++ b/src/libcatnip/io/file_readers/logreader.hpp @@ -1,11 +1,14 @@ - +#pragma once #ifndef _CATNIP_LOGREADER_HPP_ #define _CATNIP_LOGREADER_HPP_ +#include +#include #include -#include "../../matrix.hpp" #include "filereader.hpp" + +#include // Gaussian log file reader namespace catnip { @@ -18,9 +21,9 @@ class LogReader : public FileReader { public: explicit LogReader(const std::string &str); orb_cont getOrbitalInfo() const { return orb_; } - Matrix *getOverlapMatrix() const { return S_; } - std::vector getOE(const std::string &orb_type) const { - return OREnergies.at(orb_type); + Eigen::MatrixXd getOverlapMatrix() const { return S_; } + Eigen::VectorXd getOE(const std::string &orb_type) { + return Eigen::Map(OREnergies.at(orb_type).data(),OREnergies.at(orb_type).size()); } int getHOMOLevel(const std::string &orb_type) const { return homoLevel.at(orb_type); @@ -48,7 +51,8 @@ class LogReader : public FileReader { std::map homoLevel; orb_cont orb_; // Overlap matrix - Matrix *S_; + //Matrix *S_; + Eigen::MatrixXd S_; std::map> OREnergies; std::vector> xyz; diff --git a/src/libcatnip/io/file_readers/punreader.cpp b/src/libcatnip/io/file_readers/punreader.cpp index 0b5a92c..0dee70d 100644 --- a/src/libcatnip/io/file_readers/punreader.cpp +++ b/src/libcatnip/io/file_readers/punreader.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -11,6 +12,8 @@ #include "../../string_support.hpp" #include "punreader.hpp" +#include + using namespace catnip; using namespace std; @@ -29,12 +32,12 @@ void PunReader::registerSections_() { FileReader::registerSections_(); } -Matrix *PunReader::getCoefsMatrix(const string &orb_type) { +Eigen::MatrixXd PunReader::getCoefsMatrix(const string &orb_type) { if (coefs.count(orb_type) != 1) { throw invalid_argument("Coefficients for spin " + orb_type + " were not found"); } - return coefs[orb_type]; + return *(coefs[orb_type]); } void PunReader::validFileName_() { @@ -93,8 +96,12 @@ void PunReader::ReadCoef(const string &orb_type) { allCoefsRead = !(foundSubStrInStr(line, orb_type)); } - Matrix *Coefs = new Matrix(v_vec); - coefs[orb_type] = Coefs; + coefs[orb_type] = unique_ptr(new Eigen::MatrixXd(v_vec.size(),v_vec.at(0).size())); + for( size_t row_ind=0; row_ind eigen_vec(v_vec.at(row_ind).data(),v_vec.at(row_ind).size()); + coefs[orb_type]->row(row_ind) = eigen_vec; + } + LOG("Success reading atomic orbital coefficients from .pun file.", 2); } diff --git a/src/libcatnip/io/file_readers/punreader.hpp b/src/libcatnip/io/file_readers/punreader.hpp index 73f8846..af9128d 100644 --- a/src/libcatnip/io/file_readers/punreader.hpp +++ b/src/libcatnip/io/file_readers/punreader.hpp @@ -1,18 +1,19 @@ - +#pragma once #ifndef _CATNIP_PUNREADER_HPP_ #define _CATNIP_PUNREADER_HPP_ +#include #include -#include "../../matrix.hpp" #include "filereader.hpp" +#include // Gaussian fort.7/.pun file reader namespace catnip { class PunReader : public FileReader { public: explicit PunReader(const std::string &str); - Matrix *getCoefsMatrix(const std::string &orb_type); + Eigen::MatrixXd getCoefsMatrix(const std::string &orb_type); bool restrictedShell() { return coefs.size() == 1; } private: @@ -25,7 +26,7 @@ class PunReader : public FileReader { void ReadCoef(const std::string &orb_type); std::vector readGausCoefLine(const std::string &line); - std::map coefs; + std::map> coefs; }; } // namespace catnip diff --git a/src/libcatnip/io/io.cpp b/src/libcatnip/io/io.cpp index 28756bc..9f653fd 100644 --- a/src/libcatnip/io/io.cpp +++ b/src/libcatnip/io/io.cpp @@ -4,15 +4,21 @@ #include #include -#include "../parameters.hpp" -#include "../string_support.hpp" +#include +#include +#include +#include + +#include "parameters.hpp" #include "io.hpp" +#include + using namespace std; namespace catnip { -unique_ptr prepareParser(void) { +unique_ptr prepareParser(void) { // Setup flags vector flag1; @@ -167,6 +173,40 @@ unique_ptr prepareParser(void) { desc = "Print the version"; flag18.push_back(desc); + vector flag19; + flag19.push_back("--all"); + flag19.push_back("-a"); + desc = "Print all transfer integrals, in matrix form"; + flag19.push_back(desc); + + vector flag20; + flag20.push_back("--log"); + flag20.push_back("-l"); + desc = "Provide all .log files and allow catnip to figure the rest out. "; + desc += "\nCaveats\n"; + desc += "1. if the --pun file flag is not used the pun/orb/.7 files must "; + desc += "appear in the same folder as the log files and have the same core "; + desc += "file name as the log file."; + desc += "2. if the --pun file flag is also provided the same number of files "; + desc += "must be provided as is provided with the --log flag, and they must "; + desc += "either be entered in the same order or they must have the same core"; + desc += " file name."; + flag20.push_back(desc); + + vector flag21; + flag21.push_back("--pun"); + flag21.push_back("-p"); + desc = "Provide all .punt/.7/.orb files and allow catnip to figure the rest out. "; + desc += "\nCaveats\n"; + desc += "1. if the --log file flag is not used the .log files must "; + desc += "appear in the same folder as the .pun/.7/.orb files and have the same core "; + desc += "file name as the .pun/.7/.orb file."; + desc += "2. if the --log file flag is also provided the same number of files "; + desc += "must be provided as is provided with the --pun flag, and they must "; + desc += "either be entered in the same order or they must have the same core"; + desc += " file name."; + flag21.push_back(desc); + set> flags; flags.insert(flag1); flags.insert(flag2); @@ -184,35 +224,55 @@ unique_ptr prepareParser(void) { flags.insert(flag16); flags.insert(flag17); flags.insert(flag18); + flags.insert(flag19); + flags.insert(flag20); + flags.insert(flag21); - unique_ptr ArgPars(new ArgumentParser(flags)); + unique_ptr ArgPars(new mamap::ArgumentParser(flags)); // Setup rules for handling flags set exts{".orb", ".7", ".pun"}; string ext_log = ".log"; + { + ArgPars->setFlagArgOpt("--log", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXT, + mamap::Option::ALLOWED_VALUES, ext_log); + ArgPars->setFlagArgOpt("--log", mamap::ArgumentType::FILES, mamap::PropertyType::SISTER_FILE, + mamap::Option::ALLOWED_VALUES, exts); + ArgPars->setFlagArgOpt("--log", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXISTS, + mamap::Option::MUST_EXIST, true); + + ArgPars->setFlagArgOpt("--pun", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXT, + mamap::Option::ALLOWED_VALUES, exts); + ArgPars->setFlagArgOpt("--pun", mamap::ArgumentType::FILES, mamap::PropertyType::SISTER_FILE, + mamap::Option::ALLOWED_VALUES, ext_log); + ArgPars->setFlagArgOpt("--pun", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXISTS, + mamap::Option::MUST_EXIST, true); + } + // Setting up rules guiding pun files { - ArgPars->setFlagArgOpt("--pun_P", "ARGUMENT_FILE", "PROPERTY_FILE_EXT", - "ALLOWED_FILE_EXT", exts); - ArgPars->setFlagArgOpt("--pun_P", "ARGUMENT_FILE", "PROPERTY_SISTER_FILE", - "ALLOWED_SISTER_FILE_EXT", ext_log); - ArgPars->setFlagArgOpt("--pun_P", "ARGUMENT_FILE", "PROPERTY_FILE_EXIST", - "FILE_MUST_EXIST", 0); - - ArgPars->setFlagArgOpt("--pun_1", "ARGUMENT_FILE", "PROPERTY_FILE_EXT", - "ALLOWED_FILE_EXT", exts); - ArgPars->setFlagArgOpt("--pun_1", "ARGUMENT_FILE", "PROPERTY_SISTER_FILE", - "ALLOWED_SISTER_FILE_EXT", ext_log); - ArgPars->setFlagArgOpt("--pun_1", "ARGUMENT_FILE", "PROPERTY_FILE_EXIST", - "FILE_MUST_EXIST", 0); - - ArgPars->setFlagArgOpt("--pun_2", "ARGUMENT_FILE", "PROPERTY_FILE_EXT", - "ALLOWED_FILE_EXT", exts); - ArgPars->setFlagArgOpt("--pun_2", "ARGUMENT_FILE", "PROPERTY_SISTER_FILE", - "ALLOWED_SISTER_FILE_EXT", ext_log); - ArgPars->setFlagArgOpt("--pun_2", "ARGUMENT_FILE", "PROPERTY_FILE_EXIST", - "FILE_MUST_EXIST", 0); + ArgPars->setFlagArgOpt("--pun_P", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXT, + mamap::Option::ALLOWED_VALUES, exts); + ArgPars->setFlagArgOpt("--pun_P", mamap::ArgumentType::FILES, mamap::PropertyType::SISTER_FILE, + mamap::Option::ALLOWED_VALUES, ext_log); + ArgPars->setFlagArgOpt("--pun_P", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXISTS, + mamap::Option::MUST_EXIST, 0); + + ArgPars->setFlagArgOpt("--pun_1", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXT, + mamap::Option::ALLOWED_VALUES, exts); + ArgPars->setFlagArgOpt("--pun_1", mamap::ArgumentType::FILES, mamap::PropertyType::SISTER_FILE, + mamap::Option::ALLOWED_VALUES, ext_log); + ArgPars->setFlagArgOpt("--pun_1", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXISTS, + mamap::Option::MUST_EXIST, 0); + + ArgPars->setFlagArgOpt("--pun_2", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXISTS, + mamap::Option::ALLOWED_VALUES, exts); + ArgPars->setFlagArgOpt("--pun_2", mamap::ArgumentType::FILES, mamap::PropertyType::SISTER_FILE, + mamap::Option::ALLOWED_VALUES, ext_log); + ArgPars->setFlagArgOpt("--pun_2", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXISTS, + mamap::Option::MUST_EXIST, 0); + } set exts_log{".log"}; @@ -221,51 +281,51 @@ unique_ptr prepareParser(void) { // Setting rules guiding log files { - ArgPars->setFlagArgOpt("--log_P", "ARGUMENT_FILE", "PROPERTY_FILE_EXT", - "ALLOWED_FILE_EXT", exts_log); - ArgPars->setFlagArgOpt("--log_P", "ARGUMENT_FILE", "PROPERTY_SISTER_FILE", - "ALLOWED_SISTER_FILE_EXT", exts_other); - ArgPars->setFlagArgOpt("--log_P", "ARGUMENT_FILE", "PROPERTY_FILE_EXIST", - "FILE_MUST_EXIST", 0); - - ArgPars->setFlagArgOpt("--log_1", "ARGUMENT_FILE", "PROPERTY_FILE_EXT", - "ALLOWED_FILE_EXT", exts_log); - ArgPars->setFlagArgOpt("--log_1", "ARGUMENT_FILE", "PROPERTY_SISTER_FILE", - "ALLOWED_SISTER_FILE_EXT", exts_other); - ArgPars->setFlagArgOpt("--log_1", "ARGUMENT_FILE", "PROPERTY_FILE_EXIST", - "FILE_MUST_EXIST", 0); - - ArgPars->setFlagArgOpt("--log_2", "ARGUMENT_FILE", "PROPERTY_FILE_EXT", - "ALLOWED_FILE_EXT", exts_log); - ArgPars->setFlagArgOpt("--log_2", "ARGUMENT_FILE", "PROPERTY_SISTER_FILE", - "ALLOWED_SISTER_FILE_EXT", exts_other); - ArgPars->setFlagArgOpt("--log_2", "ARGUMENT_FILE", "PROPERTY_FILE_EXIST", - "FILE_MUST_EXIST", 0); + ArgPars->setFlagArgOpt("--log_P", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXT, + mamap::Option::ALLOWED_VALUES, exts_log); + ArgPars->setFlagArgOpt("--log_P", mamap::ArgumentType::FILES, mamap::PropertyType::SISTER_FILE, + mamap::Option::ALLOWED_VALUES, exts_other); + ArgPars->setFlagArgOpt("--log_P", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXISTS, + mamap::Option::MUST_EXIST, 0); + + ArgPars->setFlagArgOpt("--log_1", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXT, + mamap::Option::ALLOWED_VALUES, exts_log); + ArgPars->setFlagArgOpt("--log_1", mamap::ArgumentType::FILES, mamap::PropertyType::SISTER_FILE, + mamap::Option::ALLOWED_VALUES, exts_other); + ArgPars->setFlagArgOpt("--log_1", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXISTS, + mamap::Option::MUST_EXIST, 0); + + ArgPars->setFlagArgOpt("--log_2", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXT, + mamap::Option::ALLOWED_VALUES, exts_log); + ArgPars->setFlagArgOpt("--log_2", mamap::ArgumentType::FILES, mamap::PropertyType::SISTER_FILE, + mamap::Option::ALLOWED_VALUES, exts_other); + ArgPars->setFlagArgOpt("--log_2", mamap::ArgumentType::FILES, mamap::PropertyType::FILE_EXISTS, + mamap::Option::MUST_EXIST, 0); } set spin_opts{"Alpha", "Beta"}; // Setting rules guiding spin { - ArgPars->setFlagArgOpt("--spin_P", "ARGUMENT_STRING", - "PROPERTY_STRING_CHOICE", "STRING_CHOICE_ENFORCED", + ArgPars->setFlagArgOpt("--spin_P", mamap::ArgumentType::STRING, + mamap::PropertyType::STRING_CHOICE, mamap::Option::ENFORCED, "true"); - ArgPars->setFlagArgOpt("--spin_P", "ARGUMENT_STRING", - "PROPERTY_STRING_CHOICE", "STRING_CHOICES", + ArgPars->setFlagArgOpt("--spin_P", mamap::ArgumentType::STRING, + mamap::PropertyType::STRING_CHOICE, mamap::Option::ALLOWED_VALUES, spin_opts); - ArgPars->setFlagArgOpt("--spin_1", "ARGUMENT_STRING", - "PROPERTY_STRING_CHOICE", "STRING_CHOICE_ENFORCED", + ArgPars->setFlagArgOpt("--spin_1", mamap::ArgumentType::STRING, + mamap::PropertyType::STRING_CHOICE, mamap::Option::ENFORCED, "true"); - ArgPars->setFlagArgOpt("--spin_1", "ARGUMENT_STRING", - "PROPERTY_STRING_CHOICE", "STRING_CHOICES", + ArgPars->setFlagArgOpt("--spin_1", mamap::ArgumentType::STRING, + mamap::PropertyType::STRING_CHOICE, mamap::Option::ALLOWED_VALUES, spin_opts); - ArgPars->setFlagArgOpt("--spin_2", "ARGUMENT_STRING", - "PROPERTY_STRING_CHOICE", "STRING_CHOICE_ENFORCED", + ArgPars->setFlagArgOpt("--spin_2", mamap::ArgumentType::STRING, + mamap::PropertyType::STRING_CHOICE, mamap::Option::ENFORCED, "true"); - ArgPars->setFlagArgOpt("--spin_2", "ARGUMENT_STRING", - "PROPERTY_STRING_CHOICE", "STRING_CHOICES", + ArgPars->setFlagArgOpt("--spin_2", mamap::ArgumentType::STRING, + mamap::PropertyType::STRING_CHOICE, mamap::Option::ALLOWED_VALUES, spin_opts); ArgPars->setFlagDefaultValue("--spin_P", "Alpha"); @@ -276,18 +336,18 @@ unique_ptr prepareParser(void) { // Setting rules guidling orbital type set orb_opts{"HOMO", "LUMO"}; { - ArgPars->setFlagArgOpt("--orbital_type_1", "ARGUMENT_STRING", - "PROPERTY_STRING_CHOICE", "STRING_CHOICE_ENFORCED", + ArgPars->setFlagArgOpt("--orbital_type_1", mamap::ArgumentType::STRING, + mamap::PropertyType::STRING_CHOICE, mamap::Option::ENFORCED, "true"); - ArgPars->setFlagArgOpt("--orbital_type_1", "ARGUMENT_STRING", - "PROPERTY_STRING_CHOICE", "STRING_CHOICES", + ArgPars->setFlagArgOpt("--orbital_type_1", mamap::ArgumentType::STRING, + mamap::PropertyType::STRING_CHOICE, mamap::Option::ALLOWED_VALUES, orb_opts); - ArgPars->setFlagArgOpt("--orbital_type_2", "ARGUMENT_STRING", - "PROPERTY_STRING_CHOICE", "STRING_CHOICE_ENFORCED", + ArgPars->setFlagArgOpt("--orbital_type_2", mamap::ArgumentType::STRING, + mamap::PropertyType::STRING_CHOICE, mamap::Option::ENFORCED, "true"); - ArgPars->setFlagArgOpt("--orbital_type_2", "ARGUMENT_STRING", - "PROPERTY_STRING_CHOICE", "STRING_CHOICES", + ArgPars->setFlagArgOpt("--orbital_type_2", mamap::ArgumentType::STRING, + mamap::PropertyType::STRING_CHOICE, mamap::Option::ALLOWED_VALUES, orb_opts); ArgPars->setFlagDefaultValue("--orbital_type_1", "HOMO"); @@ -296,24 +356,33 @@ unique_ptr prepareParser(void) { // Set argument allowed values for counterpoise { - ArgPars->setFlagArgOpt("--counter_poise", "ARGUMENT_SWITCH", - "PROPERTY_SWITCH", "DEFAULT", "OFF"); + ArgPars->setFlagArgOpt("--counter_poise", mamap::ArgumentType::SWITCH, + mamap::PropertyType::SWITCH, mamap::Option::VALUE, "OFF"); // By default the flag counter poise is turned off ArgPars->setFlagDefaultValue("--counter_poise", "OFF"); } + // Set argument for allowing printing of all transfer integrals { - ArgPars->setFlagArgOpt("--citation", "ARGUMENT_SWITCH", "PROPERTY_SWITCH", - "DEFAULT", "OFF"); + ArgPars->setFlagArgOpt("--all", mamap::ArgumentType::SWITCH, + mamap::PropertyType::SWITCH, mamap::Option::VALUE, "OFF"); + + // By default the flag counter poise is turned off + ArgPars->setFlagDefaultValue("--all", "OFF"); + } + + { + ArgPars->setFlagArgOpt("--citation", mamap::ArgumentType::SWITCH, mamap::PropertyType::SWITCH, + mamap::Option::VALUE, "OFF"); // By default the flag citation is turned off ArgPars->setFlagDefaultValue("--citation", "OFF"); } { - ArgPars->setFlagArgOpt("--version", "ARGUMENT_SWITCH", "PROPERTY_SWITCH", - "DEFAULT", "OFF"); + ArgPars->setFlagArgOpt("--version", mamap::ArgumentType::SWITCH, mamap::PropertyType::SWITCH, + mamap::Option::VALUE, "OFF"); // By default the flag citation is turned off ArgPars->setFlagDefaultValue("--version", "OFF"); @@ -322,8 +391,8 @@ unique_ptr prepareParser(void) { // Set rules guiding orbital numbers // Use default settings for min and max numbers { - ArgPars->addFlagArg("--orbital_num_1", "ARGUMENT_INT"); - ArgPars->addFlagArg("--orbital_num_2", "ARGUMENT_INT"); + ArgPars->addFlagArg("--orbital_num_1", mamap::ArgumentType::NUMERIC); + ArgPars->addFlagArg("--orbital_num_2", mamap::ArgumentType::NUMERIC); int orb_num = 0; ArgPars->setFlagDefaultValue("--orbital_num_1", orb_num); @@ -332,135 +401,354 @@ unique_ptr prepareParser(void) { return ArgPars; } -unique_ptr prepareParameters(unique_ptr& ArgParse) { +unique_ptr prepareParameters(unique_ptr& ArgParse) { - map flag_arg; - map flag_sister_arg; + map> flag_arg; + map> flag_sister_arg; - vector flags{"--pun_P", "--pun_1", "--pun_2", - "--log_P", "--log_1", "--log_2"}; + vector flags{"--pun_P", "--pun_1", "--pun_2","--pun", + "--log_P", "--log_1", "--log_2","--log"}; - vector flags_sister{"--log_P", "--log_1", "--log_2", - "--pun_P", "--pun_1", "--pun_2"}; + vector flags_sister{"--log_P", "--log_1", "--log_2","--log", + "--pun_P", "--pun_1", "--pun_2","--pun"}; + // Determine if each log or pun file has a sister file, and if it does store + // it in case that particular file it not passed in. for (size_t i = 0; i < flags.size(); ++i) { - auto flag = flags.at(i); - auto flag_sister = flags_sister.at(i); - string argu = "ARGUMENT_FILE"; - string prop = "PROPERTY_FILE_EXIST"; - string opt = "FILE_DOES_EXIST"; - - string fileName; - auto exists = ArgParse->getFlagArgOptValue(flag, argu, prop, opt); - if (exists.compare("1") == 0) { - flag_arg[flag] = ArgParse->getStr(flag); - } - prop = "PROPERTY_SISTER_FILE"; - opt = "SISTER_FILE_EXISTS"; - auto line = ArgParse->getFlagArgOptValue(flag, argu, prop, opt); - opt = "SISTER_FILE_PATH_NAME"; - auto line2 = ArgParse->getFlagArgOptValue(flag, argu, prop, opt); - auto sisters_exist = splitSt(line); - vector sister_file_paths = splitSt(line2); - int countFiles = 0; - for (auto sister_exists : sisters_exist) { - if (sister_exists.compare("true") == 0) { - flag_sister_arg[flag_sister] = sister_file_paths.at(countFiles); + // 1. Get the possible fileNames of the sister files + // When a sister file is calcualted it takes the core file name and + // generates the appropriate substitutes. E.g. if -logs flag is provided + // --logs core.log + // + // then the sister file names will be calculated as + // core.pun + // core.7 + // core.orb + // + // But to determine if any of these files exist we have to get the value + // of the DOES_EXIST option + const std::string & flag = flags.at(i); + const std::string & sister_flag = flags_sister.at(i); + + // Should return a vector of vector of strings + // The first vector is for each argument passed to the flag + // the second vector is the option values associated with each argument + // E.g. for the --pun flag + // + // --log dir1/file1.log dir2/file2.log dir3/file3.log + // + // There are 3 arguments passed to --log + // + // Each argument will have a set of potential sister files associate with + // it + // + // dir1/file1.log : dir1/file1.log dir1/file1.7 dir1/file1.orb + // dir2/file2.log : dir2/file2.log dir2/file2.7 dir2/file2.orb + // dir3/file3.log : dir3/file3.log dir3/file3.7 dir3/file3.orb + auto arg_potential_sister_files = + ArgParse->getFlagArgOptValues>( + flag, + mamap::ArgumentType::FILES, + mamap::PropertyType::SISTER_FILE, + mamap::Option::FILE_PATH_NAME); + + // Does the file passed in as an argument actually exist, using the example + // above + // + // --log dir1/file1.log dir2/file2.log dir3/file3.log + // + // This would check that dir1/file1.log dir2/file2.log and dir3/file3.log + // exists. will return a vector of bools + auto arg_potential_files_exist = + ArgParse->getFlagArgOptValues( + flag, + mamap::ArgumentType::FILES, + mamap::PropertyType::FILE_EXISTS, + mamap::Option::DOES_EXIST); + + // 2. Determine which files exist and choose a suitable substitute + // + // Should return a vector of vectors of bools + auto arg_potential_sister_files_exist = + ArgParse->getFlagArgOptValues>( + flag, + mamap::ArgumentType::FILES, + mamap::PropertyType::SISTER_FILE, + mamap::Option::DOES_EXIST); + + // 3. Get the arguments associated with a particular flag + // Using the example above this would be + // dir1/file1.log dir2/file2.log dir3/file3.log + std::vector file_names = ArgParse->get(flag); + + size_t num_args = ArgParse->getNumArgs(flag); + + for( size_t arg_ind = 0; arg_ind sister_files_exists = + arg_potential_sister_files_exist.at(arg_ind); + // Vector of string, that each potential sister file + // of the argument + std::vector potential_sister_files = + arg_potential_sister_files.at(arg_ind); + + for( size_t k = 0; k Par(new Parameters); - // Read file related flags - if (flag_arg.count("--pun_P") != 0) { - Par->setPunP(flag_arg["--pun_P"]); - } else if (flag_sister_arg.count("--pun_P") != 0) { - Par->setPunP(flag_sister_arg["--pun_P"]); - } else { - throw runtime_error("Unable to find file for flag --pun_P"); - } - if (flag_arg.count("--pun_1") != 0) { - Par->setPun1(flag_arg["--pun_1"]); - } else if (flag_sister_arg.count("--pun_1") != 0) { - Par->setPun1(flag_sister_arg["--pun_1"]); - } else { - throw runtime_error("Unable to find file for flag --pun_1"); - } - if (flag_arg.count("--pun_2") != 0) { - Par->setPun2(flag_arg["--pun_2"]); - } else if (flag_sister_arg.count("--pun_2") != 0) { - Par->setPun2(flag_sister_arg["--pun_2"]); - } else { - throw runtime_error("Unable to find file for flag --pun_2"); + + bool generic_file_pun_input = true; + bool generic_file_log_input = true; + // Run file related checks + + // 1. Check that: + // --pun_P + // --pun_1 + // --pun_2 + // + // are not also submitted with --pun, which should be mutually exclusive + if ( flag_arg.count("--pun_P") || + flag_arg.count("--pun_1") || + flag_arg.count("--pun_2") ) { + generic_file_pun_input = false; + if ( flag_arg.count("--pun")) { + throw runtime_error("Cannot specify (--pun_P, --pun_1, --pun_2) options " + "as well as --pun. These options are mutually exclusive"); + } } - if (flag_arg.count("--log_P") != 0) { - Par->setLogP(flag_arg["--log_P"]); - } else if (flag_sister_arg.count("--log_P") != 0) { - Par->setLogP(flag_sister_arg["--log_P"]); - } else { - throw runtime_error("Unable to find file for flag --log_P"); + + // 2. Check that: + // --log_P + // --log_1 + // --log_2 + // + // are not also submitted with --log, which should be mutually exclusive + if ( flag_arg.count("--log_P") || + flag_arg.count("--log_1") || + flag_arg.count("--log_2") ) { + generic_file_log_input = false; + if ( flag_arg.count("--log")) { + throw runtime_error("Cannot specify (--log_P, --log_1, --log_2) options " + "as well as --log. These options are mutually exclusive"); + } } - if (flag_arg.count("--log_1") != 0) { - Par->setLog1(flag_arg["--log_1"]); - } else if (flag_sister_arg.count("--log_1") != 0) { - Par->setLog1(flag_sister_arg["--log_1"]); + + + size_t num_logs =0; + size_t num_puns =0; + + // 3. Using the dimer flags + // --pun_P + // --pun_1 + // --pun_2 + // + // Check that the files were found, if the pun flags were not + // found attempt to generate the file from a sister file. + if ( generic_file_pun_input == false ){ + if (flag_arg.count("--pun_P") != 0) { + Par->setPunP(flag_arg.at("--pun_P").at(0)); + } else if (flag_sister_arg.count("--pun_P") != 0) { + Par->setPunP(flag_sister_arg.at("--pun_P").at(0)); + } else { + throw runtime_error("Unable to find file for flag --pun_P"); + } + if (flag_arg.count("--pun_1") != 0) { + Par->setPun1(flag_arg.at("--pun_1").at(0)); + } else if (flag_sister_arg.count("--pun_1") != 0) { + Par->setPun1(flag_sister_arg.at("--pun_1").at(0)); + } else { + throw runtime_error("Unable to find file for flag --pun_1"); + } + if (flag_arg.count("--pun_2") != 0) { + Par->setPun2(flag_arg.at("--pun_2").at(0)); + } else if (flag_sister_arg.count("--pun_2") != 0) { + Par->setPun2(flag_sister_arg.at("--pun_2").at(0)); + } else { + throw runtime_error("Unable to find file for flag --pun_2"); + } } else { - throw runtime_error("Unable to find file for flag --log_1"); + // 4. Using the generic flag pun + // Check that files were passed in with the pun flag if not attempt + // to use sister files that were generated by looking at the log files + if (flag_arg.count("--pun") != 0) { + Par->setPuns(flag_arg.at("--pun")); + num_puns = flag_arg.at("--pun").size(); + } else if (flag_sister_arg.count("--pun") != 0) { + Par->setPuns(flag_sister_arg.at("--pun")); + num_puns = flag_sister_arg.at("--pun").size(); + } else { + throw runtime_error("Unable to find file for flag --pun"); + } + } - if (flag_arg.count("--log_2") != 0) { - Par->setLog2(flag_arg["--log_2"]); - } else if (flag_sister_arg.count("--log_2") != 0) { - Par->setLog2(flag_sister_arg["--log_2"]); + + if( generic_file_log_input == false ){ + if (flag_arg.count("--log_P") != 0) { + Par->setLogP(flag_arg.at("--log_P").at(0)); + } else if (flag_sister_arg.count("--log_P") != 0) { + Par->setLogP(flag_sister_arg.at("--log_P").at(0)); + } else { + throw runtime_error("Unable to find file for flag --log_P"); + } + if (flag_arg.count("--log_1") != 0) { + Par->setLog1(flag_arg.at("--log_1").at(0)); + } else if (flag_sister_arg.count("--log_1") != 0) { + Par->setLog1(flag_sister_arg.at("--log_1").at(0)); + } else { + throw runtime_error("Unable to find file for flag --log_1"); + } + if (flag_arg.count("--log_2") != 0) { + Par->setLog2(flag_arg.at("--log_2").at(0)); + } else if (flag_sister_arg.count("--log_2") != 0) { + Par->setLog2(flag_sister_arg.at("--log_2").at(0)); + } else { + throw runtime_error("Unable to find file for flag --log_2"); + } } else { - throw runtime_error("Unable to find file for flag --log_2"); + // 4. Using the generic flag log + // Check that files were passed in with the pun flag if not attempt + // to use sister files that were generated by looking at the pun files + if (flag_arg.count("--log") != 0) { + Par->setLogs(flag_arg.at("--log")); + num_logs = flag_arg.at("--log").size(); + } else if (flag_sister_arg.count("--log") != 0) { + Par->setLogs(flag_sister_arg.at("--log")); + num_logs = flag_sister_arg.at("--log").size(); + } else { + throw runtime_error("Unable to find file for flag --log"); + } + } - // Read spin related flags, do not need if statement because default values - // are defined - Par->setSpinP(ArgParse->getStr("--spin_P")); - Par->setSpin1(ArgParse->getStr("--spin_1")); - Par->setSpin2(ArgParse->getStr("--spin_2")); - // Determine if we are doing a counterpoise calculation - Par->setCounterPoise(ArgParse->getInt("--counter_poise")); - Par->setCitation(ArgParse->getInt("--citation")); - // Read Orbital related flags - { - string orb_typ_1 = ArgParse->getStr("--orbital_type_1"); - Par->setOrbType1(orb_typ_1); - if (orb_typ_1.compare("HOMO") == 0) { - int MO = ArgParse->getInt("--orbital_num_1"); - if (MO > 0) { - throw invalid_argument("HOMO orbital must be 0 or a negative number"); + // If we are using the generic file options --pun and --log and both flags + // are provided the flags must have an equal number of arguments, otherwise + // it becomes impossible to match the appropriate log file with the + // appropriate pun file + // + // E.g. I can't have + // + // --pun File1.pun File3.pun --log File1.log File2,log File3.log + // + // Because I don't know which pun file is missing + // + // The file names passed to these flags must be in order as well + // + // --pun File1.pun File3.pun File2.pun --log File1.log File2.log File3.log + // + // Will not work because I will not be able to identify that File2 and File3 + // are not associated with each other the input must look like this + // + // --pun file1.pun file2.pun file3.pun --log file1.log file2.log file3.log + // + // though it does not matter the order they are passed in E.g. this is ok + // + // --pun file2.pun file3.pun file1.pun --log file2.log file3.log file1.log + // + // As long as the order is consistent between --log and --pun flags + if ( generic_file_log_input && generic_file_pun_input) { + + if(num_logs != num_puns ) { + std::string error_msg = "There must be an equal number of log and pun files"; + error_msg += "\nThe following files have been detected\n\nLogs .log :"; + for ( std::string & log_file : Par->getLogs() ) { + error_msg += log_file + "\n"; } - Par->setOrbNum1(MO); - } else if (orb_typ_1.compare("LUMO") == 0) { - int MO = ArgParse->getInt("--orbital_num_1"); - if (MO < 0) { - throw invalid_argument("LUMO orbital must be 0 or a positive number"); + error_msg += "\n\nPuns pun/.7/.orb :"; + for ( std::string & pun_file : Par->getPuns() ) { + error_msg += pun_file + "\n"; } - Par->setOrbNum1(MO); + throw std::runtime_error(error_msg); } } - { - string orb_typ_2 = ArgParse->getStr("--orbital_type_2"); - Par->setOrbType2(orb_typ_2); - if (orb_typ_2.compare("HOMO") == 0) { - int MO = ArgParse->getInt("--orbital_num_2"); - if (MO > 0) { - throw invalid_argument("HOMO orbital must be 0 or a negative number"); + // If --pun or --log flags are used then non of the other flags are + // appropriate + if( generic_file_pun_input || generic_file_log_input ) { + if( ArgParse->getNumArgs("--spin_P") != 0){ + throw std::runtime_error("--spin_P command cannot be used with the --pun and --log flags"); + } + if( ArgParse->getNumArgs("--spin_1") != 0){ + throw std::runtime_error("--spin_1 command cannot be used with the --pun and --log flags"); + } + if( ArgParse->getNumArgs("--spin_2") != 0){ + throw std::runtime_error("--spin_2 command cannot be used with the --pun and --log flags"); + } + if( ArgParse->getNumArgs("--orbital_type_1") != 0){ + throw std::runtime_error("--orbital_type_1 command cannot be used with the --pun and --log flags"); + } + if( ArgParse->getNumArgs("--orbital_type_2") != 0){ + throw std::runtime_error("--orbital_type_2 command cannot be used with the --pun and --log flags"); + } + if( ArgParse->getNumArgs("--orbital_num_1") != 0){ + throw std::runtime_error("--orbital_num_1 command cannot be used with the --pun and --log flags"); + } + if( ArgParse->getNumArgs("--orbital_num_2") != 0){ + throw std::runtime_error("--orbital_num_2 command cannot be used with the --pun and --log flags"); + } + } else { + // Read spin related flags, do not need if statement because default values + // are defined + Par->setSpinP(ArgParse->get("--spin_P").at(0)); + Par->setSpin1(ArgParse->get("--spin_1").at(0)); + Par->setSpin2(ArgParse->get("--spin_2").at(0)); + + // Read Orbital related flags + { + string orb_typ_1 = ArgParse->get("--orbital_type_1").at(0); + Par->setOrbType1(orb_typ_1); + if (orb_typ_1.compare("HOMO") == 0) { + int MO = ArgParse->get("--orbital_num_1").at(0); + if (MO > 0) { + throw invalid_argument("HOMO orbital must be 0 or a negative number"); + } + Par->setOrbNum1(MO); + } else if (orb_typ_1.compare("LUMO") == 0) { + int MO = ArgParse->get("--orbital_num_1").at(0); + if (MO < 0) { + throw invalid_argument("LUMO orbital must be 0 or a positive number"); + } + Par->setOrbNum1(MO); } - Par->setOrbNum2(MO); - } else if (orb_typ_2.compare("LUMO") == 0) { - int MO = ArgParse->getInt("--orbital_num_2"); - if (MO < 0) { - throw invalid_argument("LUMO orbital must be 0 or a positive number"); + } + + { + string orb_typ_2 = ArgParse->get("--orbital_type_2").at(0); + Par->setOrbType2(orb_typ_2); + if (orb_typ_2.compare("HOMO") == 0) { + int MO = ArgParse->get("--orbital_num_2").at(0); + if (MO > 0) { + throw invalid_argument("HOMO orbital must be 0 or a negative number"); + } + Par->setOrbNum2(MO); + } else if (orb_typ_2.compare("LUMO") == 0) { + int MO = ArgParse->get("--orbital_num_2").at(0); + if (MO < 0) { + throw invalid_argument("LUMO orbital must be 0 or a positive number"); + } + Par->setOrbNum2(MO); } - Par->setOrbNum2(MO); } } + // Determine if we are doing a counterpoise calculation + Par->setCounterPoise((ArgParse->get("--counter_poise")).at(0)); + Par->setPrintSwitch(ArgParse->get("--all").at(0)); + Par->setCitation(ArgParse->get("--citation").at(0)); return Par; } diff --git a/src/libcatnip/io/io.hpp b/src/libcatnip/io/io.hpp index ce57b8e..6bc829a 100644 --- a/src/libcatnip/io/io.hpp +++ b/src/libcatnip/io/io.hpp @@ -1,20 +1,22 @@ #ifndef _CATNIP_IO_HPP #define _CATNIP_IO_HPP -#include "../matrix.hpp" #include "../parameters.hpp" -#include "argumentparser.hpp" #include #include #include #include #include +namespace mamap { + class ArgumentParser; +} + namespace catnip { -std::unique_ptr prepareParser(void); +std::unique_ptr prepareParser(void); std::unique_ptr prepareParameters( - std::unique_ptr& ArgParse); + std::unique_ptr& ArgParse); } // namespace catnip diff --git a/src/libcatnip/matrix.cpp b/src/libcatnip/matrix.cpp index b206b70..cd000db 100644 --- a/src/libcatnip/matrix.cpp +++ b/src/libcatnip/matrix.cpp @@ -1,173 +1,14 @@ -#include -#include -#include -#include + #include #include -#include #include #include +#include #include "matrix.hpp" using namespace std; - -namespace catnip { - -Matrix Matrix_diag(const Matrix &mat) { - - if (mat.get_cols() > 1 && mat.get_rows() > 1) { - throw invalid_argument( - "ERROR Matrix_diag can only create a diagonal " - "matrix from a vector.\n"); - } - - if (mat.get_shel() > 1) { - throw invalid_argument( - "ERROR Matrix_diag cannot create diagonal matrix " - "from a 3d matrix, it must be passed a vector.\n"); - } - - if (mat.get_cols() > mat.get_rows()) { - int len = mat.get_cols(); - Matrix mat2(len, len); - for (int i = 1; i <= len; i++) { - double val = mat.get_elem(1, i); - mat2.set_elem(val, i, i); - } - return mat2; - } else { - int len = mat.get_rows(); - Matrix mat2(len, len); - for (int i = 1; i <= len; i++) { - double val = mat.get_elem(i, 1); - mat2.set_elem(val, i, i); - } - return mat2; - } -} - -Matrix Matrix_copy(const Matrix &mat) { - - Matrix mat2(mat.get_rows(), mat.get_cols(), mat.get_shel()); - - int i; - int j; - int k; - double val; - - for (i = 1; i <= mat.get_rows(); i++) { - for (j = 1; j <= mat.get_cols(); j++) { - for (k = 1; k <= mat.get_shel(); k++) { - val = mat.get_elem(i, j, k); - mat2.set_elem(val, i, j, k); - } - } - } - - return mat2; -} - -Matrix Matrix_concatenate_rows(Matrix mat1,const Matrix & mat2) { - - // For this function to work both mat1 and mat2 must have - // the same number of columns and shelves - - if (mat1.get_cols() != mat2.get_cols()) { - std::cerr << "ERROR to concatenate the rows mat1 and mat2 must\n"; - std::cerr << " have the same number of cols!\n"; - Matrix m; - return m; - } - - if (mat1.get_shel() != mat2.get_shel()) { - std::cerr << "ERROR to concatenate the rows mat1 and mat2 must\n"; - std::cerr << " have the same number of shelves!\n"; - Matrix m; - return m; - } - - int totalrows; - int rowsMat1 = mat1.get_rows(); - totalrows = rowsMat1 + mat2.get_rows(); - Matrix mat3(totalrows, mat1.get_cols(), mat1.get_shel()); - - int i; - int j; - int k; - double val; - - for (i = 1; i <= mat1.get_rows(); i++) { - for (j = 1; j <= mat1.get_cols(); j++) { - for (k = 1; k <= mat1.get_shel(); k++) { - val = mat1.get_elem(i, j, k); - mat3.set_elem(val, i, j, k); - } - } - } - - for (i = 1; i <= mat2.get_rows(); i++) { - for (j = 1; j <= mat2.get_cols(); j++) { - for (k = 1; k <= mat2.get_shel(); k++) { - val = mat2.get_elem(i, j, k); - mat3.set_elem(val, i + rowsMat1, j, k); - } - } - } - - return mat3; -} - -Matrix Matrix_concatenate_cols(const Matrix &mat1, const Matrix &mat2) { - - // For this function to work both mat1 and mat2 must have - // the same number of columns and shelves - - if (mat1.get_rows() != mat2.get_rows()) { - std::cerr << "ERROR to concatenate the cols mat1 and mat2 must\n"; - std::cerr << " have the same number of rows!\n"; - Matrix m; - return m; - } - - if (mat1.get_shel() != mat2.get_shel()) { - std::cerr << "ERROR to concatenate the rows mat1 and mat2 must\n"; - std::cerr << " have the same number of shelves!\n"; - Matrix m; - return m; - } - - int totalcols; - int colsMat1 = mat1.get_cols(); - totalcols = colsMat1 + mat2.get_cols(); - Matrix mat3(mat1.get_rows(), totalcols, mat1.get_shel()); - - int i; - int j; - int k; - double val; - - for (i = 1; i <= mat1.get_rows(); i++) { - for (j = 1; j <= mat1.get_cols(); j++) { - for (k = 1; k <= mat1.get_shel(); k++) { - val = mat1.get_elem(i, j, k); - mat3.set_elem(val, i, j, k); - } - } - } - - for (i = 1; i <= mat2.get_rows(); i++) { - for (j = 1; j <= mat2.get_cols(); j++) { - for (k = 1; k <= mat2.get_shel(); k++) { - val = mat2.get_elem(i, j, k); - mat3.set_elem(val, i, j + colsMat1, k); - } - } - } - - return mat3; -} - +namespace catnip { string double_tos(double f, int nd) { ostringstream ostr; int tens = stod("1" + string(nd, '0')); @@ -175,772 +16,65 @@ string double_tos(double f, int nd) { return ostr.str(); } -std::ostream &operator<<(std::ostream &out, Matrix &mat) { - out << "Matrix Attributes\n"; - out << "rows " << mat.get_rows(); - out << "\ncols " << mat.get_cols(); - out << "\nshel " << mat.get_shel(); - int i; - int j; - int k; - for (k = 1; k <= mat.get_shel(); k++) { - out << "\nShelf " << k << "\n\t"; - - for (j = 1; j <= mat.get_cols(); j++) { - out << "Col " << j << "\t"; - } - out << "\n"; - for (i = 1; i <= mat.get_rows(); i++) { - out << "Row " << i << "\t"; - for (j = 1; j <= mat.get_cols(); j++) { - out << mat.get_elem(i, j) << "\t"; - } - out << "\n"; - } - } - return out; -} - -Matrix &operator*(const Matrix &mat1, const Matrix &mat2) { - - if (mat1.get_shel() != 1 || mat2.get_shel() != 1) { - printf( - "ERROR Matrix_Multiply only allowed for 2d nxm matrix not 3d nxmxl\n"); - exit(1); - } - if (mat1.get_cols() != mat2.get_rows()) { - printf("ERROR Matrix_Multiply only allowed for nxm by lxn matrices\n"); - printf(" second matrix must have same number of colums as first\n"); - printf(" matrix has number of rows\n"); - exit(1); - } - - Matrix *mat3 = new Matrix(mat1.get_rows(), mat2.get_cols()); - - int i; - int j; - int k; - double sum; - - for (i = 1; i <= mat1.get_rows(); i++) { - for (j = 1; j <= mat2.get_cols(); j++) { - sum = 0; - for (k = 1; k <= mat1.get_cols(); k++) { - sum += (mat1.get_elem(i, k)) * (mat2.get_elem(k, j)); - } - (*mat3).set_elem(sum, i, j); - } - } - return *mat3; -} - -} // namespace catnip - -using namespace catnip; - -Matrix::Matrix() { - rows = 1; - cols = 1; - shel = 1; - elem = new double[rows * cols]; - elem[0] = 0; -} - -Matrix::Matrix(vector v_data) { - rows = v_data.size(); - cols = 1; - shel = 1; - elem = new double[rows * cols]; - - int r = 1; - int c = 1; - for (auto val : v_data) { - elem[(r - 1) * cols + c - 1] = val; - ++r; - } -} - -Matrix::Matrix(vector v_data) { - rows = v_data.size(); - cols = 1; - shel = 1; - elem = new double[rows * cols]; - - int r = 1; - int c = 1; - for (auto val : v_data) { - elem[(r - 1) * cols + c - 1] = static_cast(val); - ++r; - } -} - -Matrix::Matrix(vector> vv_data) { - rows = vv_data.size(); - cols = vv_data.at(0).size(); - shel = 1; - elem = new double[rows * cols]; - elem = new double[rows * cols]; - - int r = 1; - for (auto v : vv_data) { - int c = 1; - if (static_cast(v.size()) != cols) { - throw invalid_argument( - "vector> not consistent " - "in matrix constructor "); - } - for (auto val : v) { - elem[(r - 1) * cols + c - 1] = val; - ++c; - } - ++r; - } -} - -Matrix::Matrix(const int r) { - if (r < 0) { - cerr << "ERROR rows of matrix must be greater than or equal to 0" << endl; - cerr << " you have r " << r << endl; - exit(1); - } - if (r == 0) { - rows = 0; - cols = 0; - shel = 0; - elem = nullptr; - } else { - rows = r; - cols = 1; - shel = 1; - - elem = new double[rows]; - for (int i = 1; i <= rows; i++) { - elem[i - 1] = 0; - } - } -} - -Matrix::Matrix(const int r, const int c) { - if (r < 1) { - printf("ERROR negative number of rows submitted to Matrix\n"); - exit(1); - } else if (c < 1) { - printf("ERROR negative number of cols submitted to Matrix\n"); - exit(1); - } - rows = r; - cols = c; - shel = 1; - elem = new double[rows * cols]; - for (int i = 1; i <= rows; i++) { - for (int j = 1; j <= cols; j++) { - elem[(i - 1) * cols + j - 1] = 0; - } - } -} - -Matrix::Matrix(const int r, const int c, const int s) { - if (r < 1) { - printf("ERROR negative number of rows submitted to Matrix\n"); - exit(1); - } else if (c < 1) { - printf("ERROR negative number of cols submitted to Matrix\n"); - exit(1); - } else if (s < 1) { - printf("ERROR negative number of shelves submitted to Matrix\n"); - exit(1); - } - rows = r; - cols = c; - shel = s; - elem = new double[rows * cols * shel]; - for (int i = 1; i <= rows; i++) { - for (int j = 1; j <= cols; j++) { - for (int k = 1; k <= shel; k++) { - elem[(i - 1) * cols * shel + (j - 1) * shel + k - 1] = 0; - } - } - } -} - -int Matrix::resize(int r, int c) { - - if (r < 1) { - printf("ERROR must resize row to a value of 1 or greater\n"); - exit(1); - } - if (c < 1) { - printf("ERROR must resize column to a value of 1 or greater\n"); - exit(1); - } +vector matchRow(const Eigen::MatrixXd & mat1, const Eigen::MatrixXd & mat2, const int sf) { - double *temp; - temp = new double[r * c]; - - // adding values from old matrix to new - if (r <= rows) { - for (int i = 1; i <= r; i++) { - if (c <= cols) { - for (int j = 1; j <= c; j++) { - temp[(i - 1) * c * 1 + (j - 1) * 1 + 1 - 1] = elem[index(i, j, 1)]; - } - } else { - for (int j = 1; j <= c; j++) { - if (j <= cols) { - temp[(i - 1) * c * 1 + (j - 1) * 1 + 1 - 1] = elem[index(i, j, 1)]; - } else { - temp[(i - 1) * c * 1 + (j - 1) * 1 + 1 - 1] = 0; - } - } - } - } - } else { - for (int i = 1; i <= r; i++) { - if (c <= cols) { - for (int j = 1; j <= c; j++) { - if (i <= rows) { - temp[(i - 1) * c * 1 + (j - 1) * 1 + 1 - 1] = elem[index(i, j, 1)]; - } else { - temp[(i - 1) * c * 1 + (j - 1) * 1 + 1 - 1] = 0; - } - } - } else { - for (int j = 1; j <= c; j++) { - if (i <= rows && j <= cols) { - temp[(i - 1) * c * 1 + (j - 1) * 1 + 1 - 1] = elem[index(i, j, 1)]; - } else { - temp[(i - 1) * c * 1 + (j - 1) * 1 + 1 - 1] = 0; - } - } - } - } - } - - delete elem; - rows = r; - cols = c; - shel = 1; - elem = temp; - - return 0; -} - -Matrix &Matrix::operator=(const Matrix &m) { - this->resize(m.get_rows(), m.get_cols()); - - for (int i = 1; i <= m.get_rows(); ++i) { - for (int j = 1; j <= m.get_cols(); ++j) { - this->set_elem(m.get_elem(i, j), i, j); - } - } - return *this; -} - -int Matrix::index(const int r, const int c, const int s) const { - return (r - 1) * cols * shel + (c - 1) * shel + s - 1; -} - -void Matrix::set_row(vector row, int r) { - - if (get_cols() != static_cast(row.size())) { - throw invalid_argument("vector is not the same size as matrix"); - } - - for (int j = 1; j <= get_cols(); j++) { - if (r <= rows) { - elem[index(r, j, 1)] = row.at(j - 1); - } else { - elem[index(r, j, 1)] = 0; - } - } -} - -void Matrix::set_col(vector col, int c) { - - if (get_cols() != static_cast(col.size())) { - throw invalid_argument("vector is not the same size as matrix"); - } - for (int i = 1; i <= get_rows(); ++i) { - if (c <= cols) { - elem[index(i, c, 1)] = col.at(i - 1); - } else { - elem[index(i, c, 1)] = 0; - } - } -} - -void Matrix::set_rows(int r) { - if (r < 0) { - printf("ERROR negative number submitted to set_rows\n"); - exit(1); - } - if (r > rows) { - - double *temp = new double[r * cols * shel]; - for (int i = 1; i <= r; i++) { - for (int j = 1; j <= cols; j++) { - for (int k = 1; k <= shel; k++) { - if (r <= rows) { - temp[index(i, j, k)] = elem[index(i, j, k)]; - } else { - temp[index(i, j, k)] = 0; - } - } - } - } - delete elem; - rows = r; - elem = temp; - } else if (r < rows) { - - double *temp = new double[r * cols * shel]; - printf("WARNING reducing matrix rows below previous value\n"); - printf("could lose data in the process\n"); - for (int i = 1; i <= r; i++) { - for (int j = 1; j <= cols; j++) { - for (int k = 1; k <= shel; k++) { - temp[index(i, j, k)] = elem[index(i, j, k)]; - } - } - } - delete elem; - rows = r; - elem = temp; - } -} - -vector Matrix::get_col(int c) const{ - vector col_data; - for (int i = 1; i <= rows; i++) { - col_data.push_back(elem[index(i, c, 1)]); - } - return col_data; -} - -vector Matrix::get_row(int r) const { - vector row_data; - for (int i = 1; i <= cols; i++) { - row_data.push_back(elem[index(r, i, 1)]); - } - return row_data; -} - -void Matrix::set_cols(int c) { - if (c < 0) { - printf("ERROR negative number submitted to set_cols\n"); - exit(1); - } - - if (c > cols) { - - double *temp = new double[rows * c * shel]; - for (int i = 1; i <= rows; i++) { - for (int j = 1; j <= c; j++) { - for (int k = 1; k <= shel; k++) { - if (c <= cols) { - temp[index(i, j, k)] = elem[index(i, j, k)]; - } else { - temp[index(i, j, k)] = 0; - } - } - } - } - delete elem; - cols = c; - elem = temp; - } else if (c < cols) { - - double *temp = new double[rows * c * shel]; - printf("WARNING reducing matrix cols below previous value\n"); - printf("could lose data in the process\n"); - for (int i = 1; i <= rows; i++) { - for (int j = 1; j <= c; j++) { - for (int k = 1; k <= shel; k++) { - temp[index(i, j, k)] = elem[index(i, j, k)]; - } - } - } - delete elem; - cols = c; - elem = temp; - } -} - -void Matrix::set_shel(int s) { - if (s < 0) { - printf("ERROR negative number submitted to set_shel\n"); - exit(1); - } - if (s > shel) { - - double *temp = new double[rows * cols * s]; - for (int i = 1; i <= rows; i++) { - for (int j = 1; j <= cols; j++) { - for (int k = 1; k <= s; k++) { - if (s <= shel) { - temp[index(i, j, k)] = elem[index(i, j, k)]; - } else { - temp[index(i, j, k)] = 0; - } - } - } - } - delete elem; - shel = s; - elem = temp; - } else if (s < shel) { - - double *temp = new double[rows * cols * s]; - printf("WARNING reducing matrix shel below previous value\n"); - printf("could lose data in the process\n"); - for (int i = 1; i <= rows; i++) { - for (int j = 1; j <= cols; j++) { - for (int k = 1; k <= s; k++) { - temp[index(i, j, k)] = elem[index(i, j, k)]; - } - } - } - delete elem; - shel = s; - elem = temp; - } -} - -void Matrix::set_elem(double val) { elem[0] = val; } - -void Matrix::set_elem(double val, int r) { - if (r > rows) { - printf( - "ERROR r value is greater than rows in set_elem(double val, int r)\n"); - exit(1); - } else if (r < 1) { - printf( - "ERROR r value is less than or equal to 0 in set_elem(double val, int " - "r)\n"); - exit(1); - }; - - elem[index(r, 1, 1)] = val; -} - -void Matrix::set_elem(double val, int r, int c) { - if (r > rows) { - printf( - "ERROR r value is greater than rows in set_elem(double val, int r, int " - "c)\n"); - exit(1); - } else if (r < 1) { - printf( - "ERROR r value is less than or equal to 0 in set_elem(double val, int " - "r, int c)\n"); - exit(1); - }; - if (c > cols) { - printf( - "ERROR c value is greater than rows in set_elem(double val, int r, int " - "c)\n"); - exit(1); - } else if (c < 1) { - printf( - "ERROR c value is less than or equal to 0 in set_elem(double val, int " - "r, int c)\n"); - exit(1); - }; - - elem[index(r, c, 1)] = val; -} - -void Matrix::set_elem(double val, int r, int c, int s) { - if (r > rows) { - printf( - "ERROR r value is greater than rows in set_elem(double val, int r, int " - "c, int s)\n"); - exit(1); - } else if (r < 1) { - printf( - "ERROR r value is less than or equal to 0 in set_elem(double val, int " - "r, int c, int s)\n"); - exit(1); - }; - if (c > cols) { - printf( - "ERROR c value is greater than rows in set_elem(double val, int r, int " - "c, int s)\n"); - exit(1); - } else if (c < 1) { - printf( - "ERROR c value is less than or equal to 0 in set_elem(double val, int " - "r, int c, int s)\n"); - exit(1); - }; - if (s > shel) { - printf( - "ERROR s value is greater than rows in set_elem(double val, int r, int " - "c, int s)\n"); - exit(1); - } else if (s < 1) { - printf( - "ERROR s value is less than or equal to 0 in set_elem(double val, int " - "r, int c, int s)\n"); - exit(1); - }; - - elem[index(r, c, s)] = val; -} - -int Matrix::get_rows() const { return rows; } - -int Matrix::get_cols() const { return cols; } - -int Matrix::get_shel() const { return shel; } - -int Matrix::total_elem() { return rows * cols * shel; } - -double Matrix::get_elem() const { return elem[0]; } - -double Matrix::get_elem(const int r) const { - if (r < 1) { - printf("ERROR get_elem(int r): 0 or negative row submitted\n"); - exit(1); - } else if (r > rows) { - printf( - "ERROR get_elem(int r): row value larger than the scope of the " - "Matrix\n"); - exit(1); - } - return elem[index(r, 1, 1)]; -} - -double Matrix::get_elem(const int r, const int c) const { - if (r < 1) { - printf("ERROR get_elem(int r, int c): 0 or negative row submitted\n"); - exit(1); - } else if (r > rows) { - printf( - "ERROR get_elem(int r, int c): row value larger than the scope of the " - "Matrix\n"); - exit(1); - } else if (c < 1) { - printf("ERROR get_elem(int r, int c): 0 or negative col submitted\n"); - exit(1); - } else if (c > cols) { - printf( - "ERROR get_elem(int r, int c): col value larger than the scope of the " - "Matrix\n"); - exit(1); - } - return elem[index(r, c, 1)]; -} - -double *Matrix::get_elem_ptr(const int r, const int c) const { - return &elem[index(r, c, 1)]; -} - -double Matrix::get_elem(const int r, const int c, const int s) const { - if (r < 1) { - printf( - "ERROR get_elem(int r, int c, int s): 0 or negative row submitted\n"); - exit(1); - } else if (r > rows) { - printf( - "ERROR get_elem(int r, int c, int s): row value larger than the scope " - "of the Matrix\n"); - exit(1); - } else if (c < 1) { - printf( - "ERROR get_elem(int r, int c, int s): 0 or negative col submitted\n"); - exit(1); - } else if (c > cols) { - printf( - "ERROR get_elem(int r, int c, int s): col value larger than the scope " - "of the Matrix\n"); - exit(1); - } else if (s < 1) { - printf( - "ERROR get_elem(int r, int c, int s): 0 or negative shelf submitted\n"); - exit(1); - } else if (s > shel) { - printf( - "ERROR get_elem(int r, int c, int s): shelf value larger than the " - "scope of the Matrix\n"); - exit(1); - } - return elem[index(r, c, s)]; -} - -void Matrix::swap_row(int r_from, int r_to) { - if (r_from == r_to) return; - - vector row_f = get_row(r_from); - vector row_t = get_row(r_to); - set_row(row_f, r_to); - set_row(row_t, r_from); -} - -void Matrix::swap_col(int c_from, int c_to) { - if (c_from == c_to) return; - - vector col_f = get_col(c_from); - vector col_t = get_col(c_to); - set_col(col_f, c_to); - set_col(col_t, c_from); -} - -void Matrix::move_row(int r_from, int r_to) { - - if (r_from == r_to) return; - - // Shift all rows down - vector row = get_row(r_from); - // Shift all values down - if (r_from < r_to) { - for (int r = r_from; r < r_to; r++) { - for (int c = 1; c <= get_cols(); c++) { - set_elem(get_elem(r + 1, c), r, c); - } - } - } else { - for (int r = r_from; r >= (r_to + 1); r--) { - for (int c = 1; c <= get_cols(); c++) { - set_elem(get_elem(r - 1, c), r, c); - } - } - } - // Insert the row we took out - this->set_row(row, r_to); -} - -void Matrix::move_col(int c_from, int c_to) { - - if (c_from == c_to) return; - - // Shift all rows down - vector col = get_col(c_from); - // Shift all values down - if (c_from < c_to) { - for (int c = c_from; c < c_to; c++) { - for (int r = 1; r <= get_rows(); r++) { - set_elem(get_elem(r, c + 1), r, c); - } - } - } else { - for (int c = c_from; c >= (c_to + 1); c--) { - for (int r = 1; r <= get_rows(); r++) { - set_elem(get_elem(r, c - 1), r, c); - } - } - } - // Insert the row we took out - set_col(col, c_to); -} - -vector Matrix::matchRow(const Matrix & mat, int sf) { - if (mat.get_shel() != 1 || this->get_shel() != 1) { - cerr << "ERROR shel should be 1" << endl; - exit(1); - } - if (mat.get_cols() != this->get_cols()) { + if (mat1.cols() != mat2.cols()) { throw invalid_argument( "match function only works when matrices have same number of columns"); } - vector m_vec(this->get_rows(), -1); + vector m_vec(mat1.rows(), -1); - for (int i = 1; i <= get_rows(); ++i) { - for (int ii = 1; ii <= mat.get_rows(); ++ii) { + for (int i = 0; i < mat1.rows(); ++i) { + for (int ii = 0; ii < mat2.rows(); ++ii) { bool match = true; - for (int j = 1; j <= get_cols(); ++j) { - string val1 = double_tos(get_elem(i, j), sf); - string val2 = double_tos(mat.get_elem(ii, j), sf); + for (int j = 0; j < mat1.cols(); ++j) { + string val1 = double_tos(mat1(i, j), sf); + string val2 = double_tos(mat2(ii, j), sf); if (val1.compare(val2) != 0) { match = false; break; } } - if (match) m_vec.at(i - 1) = ii; + if (match) m_vec.at(i) = ii; } } return m_vec; } -vector Matrix::matchCol(const Matrix &mat, const int sf) const { - if (mat.get_shel() != 1 || this->get_shel() != 1) { - cerr << "ERROR shel should be 1" << endl; - exit(1); - } - if (mat.get_rows() != this->get_rows()) { +vector matchCol(const Eigen::MatrixXd & mat1, + const Eigen::MatrixXd &mat2, + const int sf) { + + if (mat1.rows() != mat2.rows()) { throw invalid_argument( "match function only works when matrices have same number of rows"); } - vector m_vec(this->get_cols(), -1); + vector m_vec(mat1.cols(), -1); - for (int i = 1; i <= get_cols(); ++i) { - for (int ii = 1; ii <= mat.get_cols(); ++ii) { + for (int i = 0; i < mat1.cols(); ++i) { + for (int ii = 0; ii < mat2.cols(); ++ii) { bool match = true; - for (int j = 1; j <= get_rows(); ++j) { - string val1 = double_tos(get_elem(j, i), sf); - string val2 = double_tos(mat.get_elem(j, ii), sf); + for (int j = 0; j < mat1.rows(); ++j) { + string val1 = double_tos(mat1(j, i), sf); + string val2 = double_tos(mat2(j, ii), sf); if (val1.compare(val2) != 0) { match = false; break; } } - if (match) m_vec.at(i - 1) = ii; + if (match) m_vec.at(i) = ii; } } return m_vec; } -Matrix Matrix::invert() const{ - - if (this->get_shel() != 1) { - printf("ERROR Matrix_Invert only allowed for 1d and 2d arrays not 3d\n"); - exit(1); - } - - Matrix *mat2 = new Matrix(this->get_cols(), this->get_rows()); - - for (int i = 1; i <= this->get_rows(); i++) { - for (int j = 1; j <= this->get_cols(); j++) { - double val = this->get_elem(i, j); - (*mat2).set_elem(val, j, i); - } - } - return *mat2; -} - -Matrix Matrix::getRow(int R) const{ - - if (this->get_rows() < R) { - printf("ERROR Matrix_getRow cannot return R %d", R); - printf(" because mat has only %d rows\n.", this->get_rows()); - exit(1); - } - - Matrix mat2(1, this->get_cols(), this->get_shel()); +Eigen::MatrixXd convert(vector> coords){ - for (int j = 1; j <= this->get_cols(); j++) { - for (int k = 1; k <= this->get_shel(); k++) { - double val = this->get_elem(R, j, k); - mat2.set_elem(val, 1, j, k); - } + Eigen::MatrixXd coord_mat(coords.size(),coords.at(0).size()); + for ( size_t row_ind = 0; row_ind < coords.size();++row_ind){ + coord_mat.row(row_ind) = Eigen::Map(coords.at(row_ind).data(),coords.at(row_ind).size()); } - return mat2; + return coord_mat; } -Matrix Matrix::getCol(int C) const { - - if (this->get_cols() < C) { - printf("ERROR Matrix_getCol cannot return C %d", C); - printf(" because mat has only %d cols\n.", this->get_cols()); - exit(1); - } - Matrix mat2(this->get_cols(), 1, this->get_shel()); - - for (int i = 1; i <= this->get_rows(); i++) { - for (int k = 1; k <= this->get_shel(); k++) { - double val = this->get_elem(i, C, k); - mat2.set_elem(val, i, 1, k); - } - } - return mat2; } diff --git a/src/libcatnip/matrix.hpp b/src/libcatnip/matrix.hpp index cce1c3e..c236385 100644 --- a/src/libcatnip/matrix.hpp +++ b/src/libcatnip/matrix.hpp @@ -1,100 +1,51 @@ -#ifndef _CATNIP_Matrix_HPP -#define _CATNIP_Matrix_HPP -#include -#include -#include - -namespace catnip { - -class Matrix { - private: - int rows; - int cols; - int shel; - double *elem; - - public: - // constructors - explicit Matrix(void); - explicit Matrix(std::vector); - explicit Matrix(std::vector); - explicit Matrix(std::vector>); - explicit Matrix(const int r); - Matrix(const int r, const int c); - Matrix(const int r, const int c, const int s); - - Matrix &operator=(const Matrix &m); - // manipulators - void set_rows(int r); - void set_cols(int c); - void set_shel(int s); - void set_row(std::vector row, int r); - void set_col(std::vector col, int c); - int resize(int r, int c); - void set_elem(double val); - void set_elem(double val, int r); - void set_elem(double val, int r, int c); - void set_elem(double val, int r, int c, int s); - // accessors - int index(const int r, const int c, const int s) const; - int get_rows() const; - int get_cols() const; - int get_shel() const; - int total_elem(); - double get_elem() const; - double get_elem(const int r) const; - double get_elem(const int r, const int c) const; - double get_elem(const int r, const int c, const int s) const; - double *get_elem_ptr(const int r, const int c) const; - std::vector get_col(int c) const; - std::vector get_row(int r) const; - - // WARNING This is not a swap row operation - // All rows are shifted to make way - // for the new row/col. 'r_from' is moved to 'r_to' while - // all rows are appropriately shifted to make this happen. - void move_row(int r_from, int r_to); - void move_col(int c_from, int c_to); - // The intial and final row/col simply change places - // none of the rows and cols other than the ones swapped - // are affected - void swap_row(int r_from, int r_to); - void swap_col(int c_from, int c_to); +#ifndef MATRIX_HELPER_HPP +#define MATRIX_HELPER_HPP - Matrix getCol(int c) const; - Matrix getRow(int r) const; - // Basically switches the rows and columns - Matrix invert(void) const; - // Responsible for matching the rows between two matrices they do not need - // Returns which row in the current matrix matches which row in the one - // passed in, -1 means there is no match - // sf is the number of significant figures that will be checked to ensure - // the same value - std::vector matchRow(const Matrix & mat, int sf); - std::vector matchCol(const Matrix &mat, const int sf) const; -}; - -std::ostream &operator<<(std::ostream &out, Matrix &mat); - -Matrix &operator*(const Matrix &mat1, const Matrix &mat2); - -// Takes a vector and diagonalized the -// vector in a 2 dimensional matrix where -// everything but the diagonal is assigned -// a 0 -Matrix Matrix_diag(const Matrix &mat); - -// Copies a matrix and returns the new -// matrix -Matrix Matrix_copy(const Matrix &mat); - -// Add two matrices together to create a third -// mat1 will always appear above mat2 in the rows -// of the matrix that is returned. -Matrix Matrix_concatenate_rows(Matrix mat1,const Matrix & mat2); -Matrix Matrix_concatenate_cols(const Matrix &mat1, const Matrix &mat2); +#include +#include -} // namespace catnip +namespace catnip { -#endif // _CATNIP_Matrix_HPP + /** + * Responsible for matching the rows between two matrices Returns which row + * in matrix 1 matches which row in matrix 2, -1 means there is no match sf + * is the number of significant figures that will be checked to ensure the + * same value. + * + * E.g. + * + * Matrix 1 + * + * 1.0 0.0 0.0 + * 0.0 3.0 0.0 + * 0.0 2.5 1.0 + * 0.0 0.0 5.0 + * 6.0 0.0 0.0 + * + * Matrix 2 + * + * 1.0 0.0 0.0 + * 8.0 8.0 8.0 + * 0.0 0.0 5.0 + * + * The vector returned would return + * + * vector matched rows + * 0 + * -1 // indicates no match + * 3 + **/ + std::vector matchRow( + const Eigen::MatrixXd &mat1, + const Eigen::MatrixXd &mat2, + const int sig_fig); + + std::vector matchCol( + const Eigen::MatrixXd &mat1, + const Eigen::MatrixXd &mat2, + const int sig_fig); + + Eigen::MatrixXd convert(std::vector> coords); +} // namespace catnip +#endif // MATRIX_HELPER_HPP diff --git a/src/libcatnip/organizer.hpp b/src/libcatnip/organizer.hpp new file mode 100644 index 0000000..fa992d5 --- /dev/null +++ b/src/libcatnip/organizer.hpp @@ -0,0 +1,29 @@ +#pragma once +#ifndef _CATNIP_ORGANIZER_HPP +#define _CATNIP_ORGANIZER_HPP + + +#include +#include +#include +#include +#include +#include + +//#include "matrix.hpp" +#include + +namespace catnip { + + /** + * @brief The purpose of this class is to be able to organize basis functions + * with the correct atoms in a molecule + */ + class Organizer { + + + public: + void unscramble(AtomGroupContainer cont); + }; +} // namespace catnip +#endif // _CATNIP_ORGANIZER_HPP diff --git a/src/libcatnip/parameters.cpp b/src/libcatnip/parameters.cpp index c43617b..c92b7c3 100644 --- a/src/libcatnip/parameters.cpp +++ b/src/libcatnip/parameters.cpp @@ -25,6 +25,18 @@ void Parameters::setLogP(const string& logP) { throw invalid_argument("log file has wrong extension"); logP_ = logP; } + +void Parameters::setLogs(std::vector logs) { + logs_.clear(); + logs_.reserve(logs.size()); + for( const std::string & log : logs ) { + string ext = lastN(log, 4); + if (ext.compare(".log")) + throw invalid_argument("log file has wrong extension"); + logs_.push_back(log); + } +} + void Parameters::setPun1(const string& pun1) { string ext = lastN(pun1, 4); if (ext.compare(".pun")) @@ -43,3 +55,17 @@ void Parameters::setPunP(const string& punP) { throw invalid_argument("pun file has wrong extension"); punP_ = punP; } + +void Parameters::setPuns(std::vector puns) { + puns_.clear(); + puns_.reserve(puns.size()); + for( const std::string & pun : puns ) { + string ext = lastN(pun, 4); + if (ext.compare(".pun")) + throw invalid_argument("pun file has wrong extension"); + puns_.push_back(pun); + } +} + + + diff --git a/src/libcatnip/parameters.hpp b/src/libcatnip/parameters.hpp index 1664717..1b4893a 100644 --- a/src/libcatnip/parameters.hpp +++ b/src/libcatnip/parameters.hpp @@ -3,6 +3,7 @@ #define _CATNIP_PARAMETERS_HPP_ #include +#include namespace catnip { @@ -11,10 +12,14 @@ class Parameters { std::string log1_; std::string log2_; std::string logP_; + std::string pun1_; std::string pun2_; std::string punP_; + std::vector puns_; + std::vector logs_; + std::string spinP; std::string spin1; std::string spin2; @@ -29,7 +34,7 @@ class Parameters { bool citation; bool counterPoise; - + bool all; public: Parameters() : log1_(""), @@ -47,14 +52,18 @@ class Parameters { orb_numP(0), orb_num1(0), orb_num2(0), - counterPoise(false){}; + counterPoise(false), + all(false) {}; std::string getLog1() const { return log1_; } std::string getLog2() const { return log2_; } std::string getLogP() const { return logP_; } + std::vector getLogs() const { return logs_; } + std::string getPun1() const { return pun1_; } std::string getPun2() const { return pun2_; } std::string getPunP() const { return punP_; } + std::vector getPuns() const { return puns_; } std::string getSpinP() const { return spinP; } std::string getSpin1() const { return spin1; } @@ -68,14 +77,18 @@ class Parameters { int getOrbNum1() const { return orb_num1; } int getOrbNum2() const { return orb_num2; } bool getCounterPoise() const { return counterPoise; } + bool getPrintSwitch() const { return all; } bool getCitation() const { return citation; } void setLog1(const std::string& log1); void setLog2(const std::string& log2); void setLogP(const std::string& logP); + void setLogs(std::vector logs); + void setPun1(const std::string& pun1); void setPun2(const std::string& pun2); void setPunP(const std::string& punP); + void setPuns(std::vector puns); void setSpinP(const std::string& spin) { spinP = spin; } void setSpin1(const std::string& spin) { spin1 = spin; } @@ -89,6 +102,7 @@ class Parameters { void setOrbNum1(const int& num) { orb_num1 = num; } void setOrbNum2(const int& num) { orb_num2 = num; } void setCounterPoise(bool cp) { counterPoise = cp; } + void setPrintSwitch(bool print_all) { all = print_all; } void setCitation(bool cite) { citation = cite; } }; diff --git a/src/libcatnip/qc_functions.cpp b/src/libcatnip/qc_functions.cpp index 963c6fd..4132711 100644 --- a/src/libcatnip/qc_functions.cpp +++ b/src/libcatnip/qc_functions.cpp @@ -1,8 +1,10 @@ #include #include #include +#include #include #include +#include // For accumulate #include #include #include @@ -14,110 +16,293 @@ #include "matrix.hpp" #include "qc_functions.hpp" -using namespace std; - +#include +#include namespace catnip { -unordered_map> findRank(Matrix &Orb_E_Alpha, - Matrix &Orb_E_Beta) { - - vector> all; - - auto m_a = Orb_E_Alpha.getCol(1); - - for (int ind = 1; ind <= m_a.get_rows(); ind++) { - auto val = m_a.get_elem(ind); - pair pr(val, "Alpha"); - all.push_back(pr); - } - - if (Orb_E_Beta.get_cols() > 0) { - auto m_b = Orb_E_Beta.getCol(1); - - for (int ind = 1; ind <= m_b.get_rows(); ind++) { - auto val = m_b.get_elem(ind); - pair pr(val, "Beta"); - all.push_back(pr); - } - } - // Sort the vectors - sort(all.begin(), all.end(), - [](const pair &P1, const pair &P2) - -> bool { return P1.first < P2.first; }); - // Now that they are sorted we are going to update the ranks - int rank = 1; - - unordered_map> rank_map; - - for (auto pr : all) { - rank_map[rank] = pr; - rank++; - } - return rank_map; -} - + using namespace std; +/* // Essentially calculates the transfer integral -double calculate_transfer_integral(const Matrix & mat_1_Coef, const Matrix & mat_2_Coef, - Matrix mat_P_Coef,const Matrix & mat_S, - const Matrix &mat_P_OE, bool counterPoise_) { +void TransferComplex::calculate_transfer_integral_() { - Matrix mat_1_Coefinv = mat_1_Coef.invert(); - Matrix mat_2_Coefinv = mat_2_Coef.invert(); - Matrix mat_P_Coefinv = mat_P_Coef.invert(); - - Matrix zetaA; - Matrix zetaB; + auto dimension = mat_1_Coef.cols()+mat_2_Coef.cols(); + Eigen::MatrixXd zetaA(mat_1_Coef.rows(),dimension); + Eigen::MatrixXd zetaB(mat_2_Coef.rows(),dimension); if (counterPoise_) { + LOG("Creating zeta matrices from coefficients assuming counterpoise", 2); - zetaA = (mat_1_Coefinv); - zetaB = (mat_2_Coefinv); + zetaA = mat_1_Coef; + zetaB = mat_2_Coef; } else { LOG("Creating zeta matrices from coefficients", 2); - Matrix zerosA(mat_1_Coefinv.get_rows(), 1, mat_1_Coefinv.get_shel()); - Matrix zerosB(mat_2_Coefinv.get_rows(), 1, mat_2_Coefinv.get_shel()); - zetaA = Matrix_concatenate_rows(mat_1_Coefinv, zerosB); - zetaB = Matrix_concatenate_rows(zerosA, mat_2_Coefinv); + zetaA << mat_1_Coef, Eigen::MatrixXd::Zero(mat_1_Coef.rows(),mat_2_Coef.cols()); + zetaB << Eigen::MatrixXd::Zero(mat_2_Coef.rows(),mat_1_Coef.cols()), mat_2_Coef; } - Matrix zetaAinv = zetaA.invert(); - Matrix zetaBinv = zetaB.invert(); - - LOG("Creating intermediate matrix", 3); - Matrix Inter = mat_S * mat_P_Coefinv; LOG("Creating gamma and beta matrices", 2); - Matrix gammaA = zetaAinv * Inter; - Matrix gammaB = zetaBinv * Inter; + Eigen::MatrixXd gammaA = zetaA * mat_S * mat_P_Coef.transpose(); + Eigen::MatrixXd gammaB = zetaB * mat_S * mat_P_Coef.transpose(); - Matrix gammaA_inv = gammaA.invert(); - Matrix gammaB_inv = gammaB.invert(); + assert(gammaA.cols() == gammaB.cols() && "Column count between gamma A and B must be consistent"); + Eigen::MatrixXd gamma(gammaA.rows()+gammaB.rows(),gammaA.cols()); + gamma << gammaA, gammaB; - LOG("Calculating S_AB", 2); - Matrix S_AB = gammaB * gammaA_inv; + LOG("Calculating S_MO", 2); + S_MO.resize(dimension,dimension); + S_MO = gamma * gamma.transpose(); + + Eigen::SelfAdjointEigenSolver eigen_solver(S_MO); + Eigen::MatrixXd S_MO_inv_sqrt = eigen_solver.operatorInverseSqrt(); + + Hamiltonian.resize(mat_S.rows(),mat_S.cols()); + Hamiltonian = gamma * vec_P_OE.asDiagonal() * gamma.transpose(); + + Hamiltonian_eff = S_MO_inv_sqrt * Hamiltonian * S_MO_inv_sqrt; +} + +void TransferComplex::printTransferIntegral( + const map &orbitaltype, + const map &orbnum) const { + + string HOMO_OR_LUMO_A = orbitaltype.at("mon1"); + int MO_A = orbnum.at("mon1"); + if (HOMO_OR_LUMO_A.compare("HOMO") == 0) { + if (MO_A > 0) { + throw invalid_argument( + "Having specified HOMO the MO_A" + " value is in reference to the HOMO and must be a negative number"); + } + // Number of orbitals that are choices + if (MO_A <= (-1 * HOMO_A_)) { + string err = "You are trying to access HOMO" + to_string(MO_A) + + " but there " + "are only " + + to_string(HOMO_A_) + " HOMO orbitals"; + throw invalid_argument(err); + } + } else if (HOMO_OR_LUMO_A.compare("LUMO") == 0) { + if (MO_A < 0) { + throw invalid_argument( + "Having specified LUMO the MO_A" + " value is in reference to the LUMO and must be a positive number"); + } + int allowed_LUMO = mat_1_Coef.rows() - HOMO_A_; + if (MO_A >= allowed_LUMO) { + string err = "You are trying to access LUMO+" + to_string(MO_A) + + " but there " + "are only " + + to_string(allowed_LUMO) + " LUMO orbitals"; + throw invalid_argument(err); + } + } else { + throw invalid_argument("orbitals must be referred to as HOMO or LUMO"); + } + + string HOMO_OR_LUMO_B = orbitaltype.at("mon2"); + int MO_B = orbnum.at("mon2"); + if (HOMO_OR_LUMO_B.compare("HOMO") == 0) { + if (MO_B > 0) { + throw invalid_argument( + "Having specified HOMO the MO_B" + " value is in reference to the HOMO and must be a negative number"); + } + if (MO_B <= (-1 * HOMO_B_)) { + string err = "You are trying to access HOMO" + to_string(MO_B) + + " but there " + "are only " + + to_string(HOMO_B_) + " HOMO orbitals"; + throw invalid_argument(err); + } + } else if (HOMO_OR_LUMO_B.compare("LUMO") == 0) { + if (MO_B < 0) { + throw invalid_argument( + "Having specified LUMO the MO_B" + " value is in reference to the LUMO and must be a positive number"); + } + int allowed_LUMO = mat_2_Coef.rows() - HOMO_B_; + if (MO_B >= allowed_LUMO) { + string err = "You are trying to access LUMO+" + to_string(MO_B) + + " but there " + "are only " + + to_string(allowed_LUMO) + " LUMO orbitals"; + throw invalid_argument(err); + } + } else { + throw invalid_argument("orbitals must be referred to as HOMO or LUMO"); + } - Matrix Energy = Matrix_diag(mat_P_OE); - Matrix J_AB = gammaB * (Energy * gammaA_inv); + printTransferIntegral_( + pair(HOMO_OR_LUMO_A,MO_A), + pair(HOMO_OR_LUMO_B,MO_B)); +} +// Find the transfer integral between two orbitals. +// pair string - Either HOMO or LUMO +// int - is the orbital number HOMO-3 LUMO+5 +void TransferComplex::printTransferIntegral_( + const pair& orbital1, + const pair& orbital2) const { + + int offset = mat_1_Coef.rows(); + int orbital1_num = 0; + int orbital2_num = 0; + if(orbital1.first.compare("HOMO")==0){ + assert(orbitalValid_(orbital1)==true); + orbital1_num = orbital1.second + HOMO_A_-1; + }else if(orbital1.first.compare("LUMO")==0){ + assert(orbitalValid_(orbital1)==true); + orbital1_num = orbital1.second + HOMO_A_; + } + if(orbital2.first.compare("HOMO")==0){ + assert(orbitalValid_(orbital2)==true); + orbital2_num = offset+orbital2.second + HOMO_B_-1; + }else if(orbital2.first.compare("LUMO")==0){ + assert(orbitalValid_(orbital2)==true); + orbital2_num = offset+orbital2.second + HOMO_B_; + } + double J_ab = Hamiltonian(orbital1_num,orbital2_num); + double e_a = Hamiltonian(orbital1_num,orbital1_num); + double e_b = Hamiltonian(orbital2_num,orbital2_num); + double S_ab = S_MO(orbital1_num,orbital2_num); + + cout << "\nPre-Orthonormalization" << endl; + cout << "J_ab " << J_ab * hartreeToeV << " eV\n"; + cout << "e_a " << e_a * hartreeToeV << " eV\n"; + cout << "e_b " << e_b * hartreeToeV << " eV\n"; + cout << "S_ab " << S_ab << "\n" << endl; + + cout << "Single Orbital DIPRO" << endl; + double J_ab_single = (J_ab - 0.5*(e_a+e_b)*S_ab)/(1-pow(S_ab,2.0)); + double e_a_single = 0.5*((e_a+e_b)-2*J_ab*S_ab+(e_a-e_b)*pow(1-pow(S_ab,2.0),0.5))/(1-pow(S_ab,2.0)); + double e_b_single = 0.5*((e_a+e_b)-2*J_ab*S_ab-(e_a-e_b)*pow(1-pow(S_ab,2.0),0.5))/(1-pow(S_ab,2.0)); + cout << "J_ab_eff_single " << J_ab_single * hartreeToeV << " eV\n"; + cout << "e_a_eff_single " << e_a_single * hartreeToeV << " eV\n"; + cout << "e_b_eff_single " << e_b_single * hartreeToeV << " eV\n" << endl; + + cout << "All Orbital DIPRO" << endl; + double J_eff = Hamiltonian_eff(orbital1_num,orbital2_num); + double e_a_eff = Hamiltonian_eff(orbital1_num,orbital1_num); + double e_b_eff = Hamiltonian_eff(orbital2_num,orbital2_num); + cout << "J_ab_eff_all " << J_eff * hartreeToeV << " eV\n"; + cout << "e_a_eff_all " << e_a_eff * hartreeToeV << " eV\n"; + cout << "e_b_eff_all " << e_b_eff * hartreeToeV << " eV\n" << endl; - Matrix e_B = gammaB * (Energy * gammaB_inv); - Matrix e_A = gammaA * (Energy * gammaA_inv); +} - double J_ab = J_AB.get_elem(1, 1); - double e_b = e_B.get_elem(1, 1); - double e_a = e_A.get_elem(1, 1); - double S_ab = S_AB.get_elem(1, 1); +void TransferComplex::printAll() const { - double J_eff = (J_ab - 1 / ((double)2) * (e_b + e_a) * S_ab); - J_eff = J_eff / ((double)(1 - pow(S_ab, 2))); + int column_width = 14; + cout << "Effective Hamiltonian" << endl; - cout << "J_ab " << J_ab * hartreeToeV << " eV\n"; - cout << "e_a " << e_a * hartreeToeV << " eV\n"; - cout << "e_b " << e_b * hartreeToeV << " eV\n"; - cout << "S_ab " << S_ab << "\n"; - cout << "J_eff " << J_eff * hartreeToeV << " eV\n"; + int col_offset = mat_1_Coef.cols(); + int start_col = 0; + int end_col = 5; + while(start_colHamiltonian.cols()){ + end_col = Hamiltonian.cols(); + } + for(int orbital_num = start_col;orbital_num=col_offset && orbital_num<(HOMO_B_+col_offset))){ + if(orbital_num=HOMO_A_ && orbital_num(col_offset+HOMO_B_)){ + if(orbital_num=col_offset && orbital_num<(HOMO_B_+col_offset))){ + if(orbital_num & orbital) const{ + int HOMO_AB = HOMO_A_+HOMO_B_; + int LUMO_AB = HOMO_AB+1; + if(orbital.first.compare("HOMO")==0){ + if(orbital.second>0){ + cerr << "HOMO orbital number is not negative or 0" << endl; + return false; + } + if(orbital.second>HOMO_AB){ + cerr << "HOMO orbital does not exst " << orbital.second << " "<< HOMO_AB << endl; + return false; + } + }else if(orbital.first.compare("LUMO")==0){ + if(orbital.second<0){ + cerr << "LUMO orbital number is not positive or 0" << endl; return false; + } + if(orbital.second>(Hamiltonian_eff.rows()-LUMO_AB)){ + cerr << "LUMO orbital does not exst " << orbital.second << endl; + return false; + } + } + return true; +} +// Split a matrix up into a list of smaller matrices. The matrix can be split // in columns or in rows. The number of rows/cols in each smaller matrix is // held in the vector subMatrixDimension // @@ -136,36 +321,35 @@ double calculate_transfer_integral(const Matrix & mat_1_Coef, const Matrix & mat // 1 2 3 // 3 4 5 // -list splitMatrixIntoList(const vector &subMatrixDimension, - const Matrix *const mat, - const string &ColRowSplit) { +list splitMatrixIntoList( + const vector &subMatrixDimension, + const Eigen::MatrixXd mat, + const string &ColRowSplit) { - list list_matrix; + list list_matrix; int num_sub_matrices = subMatrixDimension.size(); if (ColRowSplit.compare("Columns") == 0) { int col = 0; - for (auto i = 1; i <= num_sub_matrices; ++i) { - Matrix *mat_new = - new Matrix(mat->get_rows(), subMatrixDimension.at(i - 1)); - for (auto k = 1; k <= mat->get_rows(); ++k) { - for (auto j = 1; j <= subMatrixDimension.at(i - 1); ++j) { - mat_new->set_elem(mat->get_elem(k, col + j), k, j); + for (int i = 0; i < num_sub_matrices; ++i) { + Eigen::MatrixXd mat_new(mat.rows(), subMatrixDimension.at(i)); + for (auto k = 0; k < mat.rows(); ++k) { + for (auto j = 0; j < subMatrixDimension.at(i); ++j) { + mat_new(k,j) = mat(k, col + j); } } - col += subMatrixDimension.at(i - 1); + col += subMatrixDimension.at(i); list_matrix.push_back(mat_new); } } else if (ColRowSplit.compare("Rows") == 0) { int row = 0; - for (auto i = 1; i <= num_sub_matrices; ++i) { - Matrix *mat_new = - new Matrix(subMatrixDimension.at(i - 1), mat->get_cols()); - for (auto k = 1; k <= mat->get_cols(); ++k) { - for (auto j = 1; j <= subMatrixDimension.at(i - 1); ++j) { - mat_new->set_elem(mat->get_elem(row + j, k), j, k); + for (auto i = 0; i < num_sub_matrices; ++i) { + Eigen::MatrixXd mat_new(subMatrixDimension.at(i), mat.cols()); + for (auto k = 0; k < mat.cols(); ++k) { + for (auto j = 0; j < subMatrixDimension.at(i); ++j) { + mat_new(j,k) = mat(row + j, k); } } - row += subMatrixDimension.at(i - 1); + row += subMatrixDimension.at(i); list_matrix.push_back(mat_new); } } else { @@ -174,7 +358,7 @@ list splitMatrixIntoList(const vector &subMatrixDimension, return list_matrix; } -list splitCoefsUpByAtoms(const vector & basisFuncP, Matrix *Coefs, +list splitCoefsUpByAtoms(const vector & basisFuncP, Eigen::MatrixXd Coefs, const string & ColRow) { return splitMatrixIntoList(basisFuncP, Coefs, ColRow); } @@ -189,55 +373,56 @@ list splitCoefsUpByAtoms(const vector & basisFuncP, Matrix *Coefs // the wrong result. // // For instance say we have a matrix -// 1 row1 -// 2 row2 -// 3 row3 -// 4 row4 +// index 1 | row 1 +// index 2 | row 2 +// index 3 | row 3 +// index 4 | row 4 // // where: -// Row 1 needs to be at row 3 -// Row 4 needs to be at row 1 -// Row 2 needs to be at row 2 -// Row 3 needs to be at row 4 +// Row 1 needs to be at index 3 +// Row 4 needs to be at index 1 +// Row 2 needs to be at index 2 +// Row 3 needs to be at index 4 // // If we simply looked at our first instance of the matrix shown above // and came up with the following swaps -// Swap row 1 with row 3 -// Swap row 4 with row 1 -// Swap row 2 with row 2 -// Swap row 3 with row 4 +// Swap row 1 with index 3 +// Swap row 4 with index 1 +// Swap row 2 with index 2 +// Swap row 3 with index 4 // // First swap -// 1 row3 -// 2 row2 -// 3 row1 -// 4 row4 +// index 1 row3 +// index 2 row2 +// index 3 row1 +// index 4 row4 // // Second swap -// 1 row4 -// 2 row2 -// 3 row1 -// 4 row3 +// index 1 row4 +// index 2 row2 +// index 3 row1 +// index 4 row3 // // Third swap does nothing // Fourth swap -// 1 row4 -// 2 row2 -// 3 row3 -// 4 row1 +// index 1 row4 +// index 2 row2 +// index 3 row3 +// index 4 row1 // // When what we really wanted was -// 1 row4 -// 2 row2 -// 3 row1 -// 4 row3 +// index 1 row4 +// index 2 row2 +// index 3 row1 +// index 4 row3 // // Notice the row3 and row1 are in the wrong place // The instructions should be rewritten -// Swap row 1 with row 3 -// Swap row 4 with row 3 -// Swap row 2 with row 2 - no swap -// Swap row 3 with row 3 - no swap +// Swap row 1 with index 3 +// Swap row 4 with index 3 +// Swap row 2 with index 2 - no swap +// Swap row 3 with index 3 - no swap +// void refreshSwapOrder(vector> &monBmatch, vector> &monAmatch) { @@ -325,81 +510,128 @@ void refreshSwapOrder(vector> &monAmatch) { return; } +// To replace both refreshSwapOrder and updateSwapLists +// instead of figuring out a proper order for swapping we will simply start +// with a new link list of the same size and place the coefficents in that +// new list +Eigen::MatrixXd createSortedCoefMatrix(vector> & mon_match_ind, list & atom_mat_coefs){ + + // Actually lets use a vector of pointers to the matrices that are in the list + vector mat_ptrs; + // Error checking + if(atom_mat_coefs.size()==0){ + throw std::runtime_error("ERROR cannot create sorted coef matrix, there are atomically partitioned matrices to build the full sorted coef matrix from."); + } + + int cols = atom_mat_coefs.front().cols(); + for ( list::iterator coef_ptr = atom_mat_coefs.begin(); + coef_ptr != atom_mat_coefs.end(); + ++coef_ptr ){ + if(coef_ptr->cols()!=cols){ + throw std::runtime_error("ERROR cannot created sorted coef matrix from atomically partitioned matrices with varying number of columns."); + } + } + // End of error checking + + // Count the total number of rows in each atomically partitioned coef matrix + vector rows_per_mat; + for ( list::iterator coef_ptr = atom_mat_coefs.begin(); + coef_ptr != atom_mat_coefs.end(); + ++coef_ptr ){ + rows_per_mat.push_back(coef_ptr->rows()); + } + + int initial_value = 0; + int total_rows = std::accumulate(rows_per_mat.begin(),rows_per_mat.end(), initial_value); + + // Determine the offset of each row to each index + std::map row_to_index_offset; + int offset = 0; + for ( std::pair & row_ind : mon_match_ind ){ + row_to_index_offset.at(row_ind.first) = offset; + offset+= rows_per_mat.at(row_ind.second); + } + + Eigen::MatrixXd sorted_atom_mat_coefs + + + +} // The above function determines the appropriate sequence of swaps this function // then actually implements the swaps by exchanging the matrices in the list. void updateSwapLists(vector> &monBmatch, vector> &monAmatch, - list &p_atom_mat_coef) { + list &p_atom_mat_coef) { for (auto p : monBmatch) { if (p.first != p.second) { auto it = p_atom_mat_coef.begin(); - Matrix *temp = *(next(it, p.first - 1)); - *(next(it, p.first - 1)) = *(next(it, p.second - 1)); - *(next(it, p.second - 1)) = temp; + Eigen::MatrixXd temp = *(next(it, p.first)); + *(next(it, p.first)) = *(next(it, p.second)); + *(next(it, p.second)) = temp; } } for (auto p : monAmatch) { if (p.first != p.second) { auto it = p_atom_mat_coef.begin(); - Matrix *temp = *(next(it, p.first - 1)); - *(next(it, p.first - 1)) = *(next(it, p.second - 1)); - *(next(it, p.second - 1)) = temp; + Eigen::MatrixXd temp = *(next(it, p.first)); + *(next(it, p.first)) = *(next(it, p.second)); + *(next(it, p.second)) = temp; } } return; } void updateSwapLists(vector> &monAmatch, - list &atom_mat_coef) { + list &atom_mat_coef) { for (auto p : monAmatch) { if (p.first != p.second) { auto it = atom_mat_coef.begin(); - Matrix *temp = *(next(it, p.first - 1)); - *(next(it, p.first - 1)) = *(next(it, p.second - 1)); - *(next(it, p.second - 1)) = temp; + Eigen::MatrixXd & temp = *(next(it, p.first)); + *(next(it, p.first)) = *(next(it, p.second)); + *(next(it, p.second)) = temp; } } return; } -Matrix *mergeListOfMatrices(list &matrix_list, const int rows, +Eigen::MatrixXd mergeListOfMatrices(list &matrix_list, const int rows, const int cols, const string &ColRowMerge) { - Matrix *full_matrix = new Matrix(rows, cols); + Eigen::MatrixXd full_matrix(rows, cols); if (ColRowMerge.compare("Columns") == 0) { int col = 0; for (auto it = matrix_list.begin(); it != matrix_list.end(); ++it) { - Matrix *mat_ptr = *it; - int row = 1; + Eigen::MatrixXd mat = *it; + int row = 0; if (col > cols) throw runtime_error("Your new matrix is not large enough"); - for (auto i = 1; i <= mat_ptr->get_rows(); ++i) { + for (auto i = 0; i < mat.rows(); ++i) { if (row > rows) throw runtime_error("Your new matrix is not large enough"); - for (auto j = 1; j <= mat_ptr->get_cols(); ++j) { - full_matrix->set_elem(mat_ptr->get_elem(i, j), row, j + col); + for (auto j = 0; j < mat.cols(); ++j) { + full_matrix(row,j+col) = mat(i, j); } ++row; } - col += mat_ptr->get_cols(); + col += mat.cols(); } } else if (ColRowMerge.compare("Rows") == 0) { int row = 0; for (auto it = matrix_list.begin(); it != matrix_list.end(); ++it) { - Matrix *mat_ptr = *it; - int col = 1; + Eigen::MatrixXd mat = *it; + int col = 0; if (row > rows) throw runtime_error("Your new matrix is not large enough"); - for (auto j = 1; j <= mat_ptr->get_cols(); ++j) { + for (auto j = 0; j < mat.cols(); ++j) { if (col > cols) throw runtime_error("Your new matrix is not large enough"); - for (auto i = 1; i <= mat_ptr->get_rows(); ++i) { - full_matrix->set_elem(mat_ptr->get_elem(i, j), row + i, col); + for (auto i = 0; i < mat.rows(); ++i) { + full_matrix(row + i, col) = mat(i, j); } ++col; } - row += mat_ptr->get_rows(); + row += mat.rows(); } } else { throw invalid_argument("Unrecognized merge type for list of matrices"); @@ -408,23 +640,97 @@ Matrix *mergeListOfMatrices(list &matrix_list, const int rows, } // This function -Matrix *createNewMatrix(list &p_atom_mat_coef, int rows, int cols, +Eigen::MatrixXd createNewMatrix(list &p_atom_mat_coef, int rows, int cols, const string &ColRow) { return mergeListOfMatrices(p_atom_mat_coef, rows, cols, ColRow); } // unscramble the coefficients -Matrix *unscramble_Coef(const std::vector &matchDimerA, - const std::vector &matchDimerB, - const std::vector &basisFuncP, Matrix *dimerCoef) { +//Eigen::MatrixXd unscramble_Coef( +// const std::vector &matchDimerA, +// const std::vector &matchDimerB, +// const std::vector &basisFuncP, +// const Eigen::MatrixXd & dimerCoef) { +// +// // Let's reduce the complexity of the problem by instead of working +// // with the basis functions lets just work with the atoms. We can do +// // this by treating all the basis functions associated with a single +// // atom as a block. +// +// list p_atom_mat_coef = +// splitCoefsUpByAtoms(basisFuncP, dimerCoef, "Columns"); +// +// // Place all of monomer A atom basis functions on the left side of the +// // matrix and all of B monomer atom basis functions on the right side +// // of the dimer matrix +// // First int is the col in the dimer the atom should be at +// // Second int is the col in the dimer the atom is presently at +// +// vector> monAmatch; +// for (unsigned i = 0; i < matchDimerA.size(); ++i) { +// pair pr(i, matchDimerA.at(i)); +// monAmatch.push_back(pr); +// } +// vector> monBmatch; +// for (unsigned i = 0; i < matchDimerB.size(); ++i) { +// pair pr(i + monAmatch.size(), matchDimerB.at(i)); +// monBmatch.push_back(pr); +// } +// +// refreshSwapOrder(monBmatch, monAmatch); +// updateSwapLists(monBmatch, monAmatch, p_atom_mat_coef); +// +// Eigen::MatrixXd dimerCoef_new = createNewMatrix( +// p_atom_mat_coef, dimerCoef.rows(), dimerCoef.cols(), "Columns"); +// +// return dimerCoef_new; +//} +// +//// unscramble the coefficients +//Eigen::MatrixXd unscramble_Coef( +// const std::vector &matchDimerB, +// const std::vector &basisFuncB, +// const Eigen::MatrixXd &Coef) { +// +// // Let's reduce the complexity of the problem by instead of working +// // with the basis functions lets just work with the atoms. We can do +// // this by treating all the basis functions associated with a single +// // atom as a block. +// +// list atom_mat_coef = +// splitCoefsUpByAtoms(basisFuncB, Coef, "Columns"); +// +// // Place all of monomer A atom basis functions on the left side of the +// // matrix and all of B monomer atom basis functions on the right side +// // of the matrix +// // First int is the col in the dimer the atom should be at +// // Second int is the col in the dimer the atom is presently at +// +// vector> monBmatch; +// for (unsigned i = 0; i < matchDimerB.size(); ++i) { +// pair pr(i, matchDimerB.at(i)); +// monBmatch.push_back(pr); +// } +// +// refreshSwapOrder(monBmatch); +// updateSwapLists(monBmatch, atom_mat_coef); +// Eigen::MatrixXd Coef_new = createNewMatrix(atom_mat_coef, Coef.rows(), +// Coef.cols(), "Columns"); +// return Coef_new; +//} + +Eigen::MatrixXd unscrambleCoef( + const std::vector> &match_mon_complex, + const std::vector &basis_functions_complex, + const Eigen::MatrixXd & complex_coefs) { // Let's reduce the complexity of the problem by instead of working // with the basis functions lets just work with the atoms. We can do // this by treating all the basis functions associated with a single // atom as a block. - list p_atom_mat_coef = - splitCoefsUpByAtoms(basisFuncP, dimerCoef, "Columns"); + list complex_coef_block = + splitCoefsUpByAtoms(basis_functions_complex, complex_coefs, "Columns"); // Place all of monomer A atom basis functions on the left side of the // matrix and all of B monomer atom basis functions on the right side @@ -432,101 +738,79 @@ Matrix *unscramble_Coef(const std::vector &matchDimerA, // First int is the col in the dimer the atom should be at // Second int is the col in the dimer the atom is presently at - vector> monAmatch; - for (unsigned i = 1; i <= matchDimerA.size(); ++i) { - pair pr(i, matchDimerA.at(i - 1)); - monAmatch.push_back(pr); - } - vector> monBmatch; - for (unsigned i = 1; i <= matchDimerB.size(); ++i) { - pair pr(i + monAmatch.size(), matchDimerB.at(i - 1)); - monBmatch.push_back(pr); +// vector> monBmatch; +// for (unsigned i = 0; i < matchDimerB.size(); ++i) { +// pair pr(i, matchDimerB.at(i)); +// monBmatch.push_back(pr); +// } + + vector>> mon_match_index; + unsigned new_index = 0; + for ( const vector & monomer_rows : match_mon_complex){ + vector> mon_matching_index_row; + for( const int & row_index : monomer_rows ){ + pair pr(new_index,row_index); + mon_matching_index_row.push_back(pr); + } + mon_match_index.push_back(mon_matching_index_row); } - refreshSwapOrder(monBmatch, monAmatch); - updateSwapLists(monBmatch, monAmatch, p_atom_mat_coef); - Matrix *dimerCoef_new = createNewMatrix( - p_atom_mat_coef, dimerCoef->get_rows(), dimerCoef->get_cols(), "Columns"); - return dimerCoef_new; -} - -// unscramble the coefficients -Matrix *unscramble_Coef(const std::vector &matchDimerB, - const std::vector &basisFuncB, Matrix *Coef) { - - // Let's reduce the complexity of the problem by instead of working - // with the basis functions lets just work with the atoms. We can do - // this by treating all the basis functions associated with a single - // atom as a block. + //refreshSwapOrder(monBmatch); +// refreshSwapOrder(mon_match_index); + // updateSwapLists(monBmatch, atom_mat_coef); + Eigen::MatrixXd Coef_new = createNewMatrix(atom_mat_coef, Coef.rows(), + Coef.cols(), "Columns"); + return Coef_new; - list atom_mat_coef = - splitCoefsUpByAtoms(basisFuncB, Coef, "Columns"); - // Place all of monomer A atom basis functions on the left side of the - // matrix and all of B monomer atom basis functions on the right side - // of the matrix - // First int is the col in the dimer the atom should be at - // Second int is the col in the dimer the atom is presently at - - vector> monBmatch; - for (unsigned i = 1; i <= matchDimerB.size(); ++i) { - pair pr(i, matchDimerB.at(i - 1)); - monBmatch.push_back(pr); - } - - refreshSwapOrder(monBmatch); - updateSwapLists(monBmatch, atom_mat_coef); - Matrix *Coef_new = createNewMatrix(atom_mat_coef, Coef->get_rows(), - Coef->get_cols(), "Columns"); - return Coef_new; } - // Similar to the above function but we will be moving both the rows // and columns -Matrix *unscramble_S(const std::vector &matchDimerA, - const std::vector &matchDimerB, - const std::vector &basisFuncP, Matrix *S) { +Eigen::MatrixXd unscramble_S( + const std::vector &matchDimerA, + const std::vector &matchDimerB, + const std::vector &basisFuncP, + Eigen::MatrixXd S) { - Matrix *S_new; + Eigen::MatrixXd S_new(S.rows(),S.cols()); { - list p_atom_mat_S = splitCoefsUpByAtoms(basisFuncP, S, "Columns"); - + list p_atom_mat_S = splitCoefsUpByAtoms(basisFuncP, S, "Columns"); vector> monAmatch; - for (unsigned i = 1; i <= matchDimerA.size(); ++i) { - pair pr(i, matchDimerA.at(i - 1)); + for (unsigned i = 0; i < matchDimerA.size(); ++i) { + pair pr(i, matchDimerA.at(i)); monAmatch.push_back(pr); } vector> monBmatch; - for (unsigned i = 1; i <= matchDimerB.size(); ++i) { - pair pr(i + monAmatch.size(), matchDimerB.at(i - 1)); + for (unsigned i = 0; i < matchDimerB.size(); ++i) { + pair pr(i + monAmatch.size(), matchDimerB.at(i)); monBmatch.push_back(pr); } refreshSwapOrder(monBmatch, monAmatch); updateSwapLists(monBmatch, monAmatch, p_atom_mat_S); S_new = - createNewMatrix(p_atom_mat_S, S->get_rows(), S->get_cols(), "Columns"); + createNewMatrix(p_atom_mat_S, S.rows(), S.cols(), "Columns"); } S = S_new; { - list p_atom_mat_S = splitCoefsUpByAtoms(basisFuncP, S, "Rows"); + list p_atom_mat_S = splitCoefsUpByAtoms(basisFuncP, S, "Rows"); vector> monAmatch; - for (unsigned i = 1; i <= matchDimerA.size(); ++i) { - pair pr(i, matchDimerA.at(i - 1)); + for (unsigned i = 0; i < matchDimerA.size(); ++i) { + pair pr(i, matchDimerA.at(i)); monAmatch.push_back(pr); } vector> monBmatch; - for (unsigned i = 1; i <= matchDimerB.size(); ++i) { - pair pr(i + monAmatch.size(), matchDimerB.at(i - 1)); + for (unsigned i = 0; i < matchDimerB.size(); ++i) { + pair pr(i + monAmatch.size(), matchDimerB.at(i)); monBmatch.push_back(pr); } refreshSwapOrder(monBmatch, monAmatch); updateSwapLists(monBmatch, monAmatch, p_atom_mat_S); - S_new = createNewMatrix(p_atom_mat_S, S->get_rows(), S->get_cols(), "Rows"); + S_new = createNewMatrix(p_atom_mat_S, S.rows(), S.cols(), "Rows"); } // Return the correctly swapped dimerCoef @@ -536,228 +820,186 @@ Matrix *unscramble_S(const std::vector &matchDimerA, // Same as the above function but here we are assuming counterpoise correction // is being used and thus we do not need to match with both monomer A and // monomer B but only need to match with A. -Matrix *unscramble_S(const std::vector &matchDimerA, - const std::vector &basisFuncP, Matrix *S) { +Eigen::MatrixXd unscramble_S( + const std::vector &matchDimerA, + const std::vector &basisFuncP, + Eigen::MatrixXd S) { - Matrix *S_new; + Eigen::MatrixXd S_new(S.rows(),S.cols()); { - list p_atom_mat_S = splitCoefsUpByAtoms(basisFuncP, S, "Columns"); + list p_atom_mat_S = splitCoefsUpByAtoms(basisFuncP, S, "Columns"); vector> monAmatch; - for (unsigned i = 1; i <= matchDimerA.size(); ++i) { - pair pr(i, matchDimerA.at(i - 1)); + for (unsigned i = 0; i < matchDimerA.size(); ++i) { + pair pr(i, matchDimerA.at(i)); monAmatch.push_back(pr); } refreshSwapOrder(monAmatch); updateSwapLists(monAmatch, p_atom_mat_S); S_new = - createNewMatrix(p_atom_mat_S, S->get_rows(), S->get_cols(), "Columns"); + createNewMatrix(p_atom_mat_S, S.rows(), S.cols(), "Columns"); } S = S_new; { - list p_atom_mat_S = splitCoefsUpByAtoms(basisFuncP, S, "Rows"); + list p_atom_mat_S = splitCoefsUpByAtoms(basisFuncP, S, "Rows"); vector> monAmatch; - for (unsigned i = 1; i <= matchDimerA.size(); ++i) { - pair pr(i, matchDimerA.at(i - 1)); + for (unsigned i = 0; i < matchDimerA.size(); ++i) { + pair pr(i, matchDimerA.at(i)); monAmatch.push_back(pr); } refreshSwapOrder(monAmatch); updateSwapLists(monAmatch, p_atom_mat_S); - S_new = createNewMatrix(p_atom_mat_S, S->get_rows(), S->get_cols(), "Rows"); + S_new = createNewMatrix(p_atom_mat_S, S.rows(), S.cols(), "Rows"); } // Return the correctly swapped dimerCoef return S_new; } -} // namespace catnip - -using namespace catnip; -TransferComplex::TransferComplex(Matrix *mat1Coef, Matrix *mat2Coef, - Matrix *matPCoef, std::pair MOs1, - std::pair MOs2, Matrix *matS, - Matrix *matPOE, bool cp) { +//TransferComplex::TransferComplex( +// const Eigen::MatrixXd & mat1Coef, +// const Eigen::MatrixXd & mat2Coef, +// const Eigen::MatrixXd & matPCoef, +// const int HOMO_A, +// const int HOMO_B, +// const Eigen::MatrixXd & matS, +// const Eigen::VectorXd & vecPOE, bool cp) { +// +TransferComplex::TransferComplex(const Parameters params) : params_(params) { - unscrambled = false; - counterPoise_ = cp; + unscrambled_ = false; +// counterPoise_ = cp; // Consistency check - if (matS->get_cols() != matPCoef->get_cols()) { + if (params_.S_AO.cols() != params_.mat_complex.cols()) { throw invalid_argument( "The overlap matrix must have the same number " "of basis functions as the dimer"); } - if (cp) { - if (mat1Coef->get_cols() != matPCoef->get_cols()) { - throw invalid_argument( - "Counter poise correction requires that the" - " monomers have the same number of coefficients as the dimer. " - "Your monomer 1 does not"); - } - if (mat2Coef->get_cols() != matPCoef->get_cols()) { - throw invalid_argument( - "Counter poise correction requires that the" - " monomers have the same number of coefficients as the dimer. " - "Your monomer 2 does not"); + //if (cp) { + if (params_.counter_poise) { + int monomer_number = 1; + for ( const Eigen::MatrixXd & mat : params_.mat_monomers){ + if(params_.mat_complex.cols() != mat.cols()){ + throw invalid_argument( + "Counter poise correction requires that the" + " monomers have the same number of coefficients as the complex. " + "Your monomer " + std::to_string(monomer_number) +" does not"); + } + ++monomer_number; } +// if (mat1Coef.cols() != matPCoef.cols()) { +// throw invalid_argument( +// "Counter poise correction requires that the" +// " monomers have the same number of coefficients as the dimer. " +// "Your monomer 1 does not"); +// } +// if (mat2Coef.cols() != matPCoef.cols()) { +// throw invalid_argument( +// "Counter poise correction requires that the" +// " monomers have the same number of coefficients as the dimer. " +// "Your monomer 2 does not"); +// } } else { - int total_cols = mat1Coef->get_cols() + mat2Coef->get_cols(); - - if (total_cols > matPCoef->get_cols()) { + /// If not counter poise the sum of the cols should equal the same number as is in the complex +// int total_cols = mat1Coef.cols() + mat2Coef.cols(); + int total_cols = 0; + for ( const Eigen::MatrixXd & mat : params_.mat_monomers){ + total_cols+=mat.cols(); + } + + //if (total_cols > matPCoef.cols()) { + if (total_cols > params_.mat_complex.cols()) { throw invalid_argument( - "Counter poise has not been specified and your " - "monomers have more basis function cols than your dimer"); + "Counter poise has not been specified and the total number of " + "basis functions in your monomers is more than the number of basis " + "functions in your complex."); + }else if(total_cols < params_.complex_coefs.cols()){ + throw invalid_argument( + "Counter poise has not been specified and the total number of " + "basis functions in your monomers is less than the number of basis " + "functions in your complex."); } } - - mat_1_Coef = mat1Coef; - mat_2_Coef = mat2Coef; - mat_P_Coef = matPCoef; - Orbs1 = MOs1; - Orbs2 = MOs2; - mat_S = matS; - mat_P_OE = matPOE; +// +// mat_1_Coef.resize(mat1Coef.rows(),mat1Coef.cols()); +// mat_1_Coef = mat1Coef; +// mat_2_Coef.resize(mat2Coef.rows(),mat2Coef.cols()); +// mat_2_Coef = mat2Coef; +// mat_P_Coef.resize(matPCoef.rows(),matPCoef.cols()); +// mat_P_Coef = matPCoef; +// HOMO_A_ = HOMO_A; +// HOMO_B_ = HOMO_B; +// mat_S.resize(matS.rows(),matS.cols()); +// mat_S = matS; +// vec_P_OE.resize(vecPOE.size()); +// vec_P_OE = vecPOE; } -void TransferComplex::unscramble(const Matrix &coord_1_mat, - const Matrix &coord_2_mat, - const Matrix &coord_P_mat, - const std::vector &basisP, +//void TransferComplex::unscramble(const Eigen::MatrixXd &coord_1_mat, +// const Eigen::MatrixXd &coord_2_mat, +// const Eigen::MatrixXd &coord_P_mat, +// const std::vector &basisP, +// const std::vector &basis2) { +// +void TransferComplex::unscramble(const vector &coord_monomers, + const Eigen::MatrixXd &coord_complex, + const std::vector &basis_complex, const std::vector &basis2) { - - unscrambled = true; + unscrambled_ = true; const int sig_fig = 4; // If dealing with counter poise correction may also need to unscramble // the basis functions of the monomers if (counterPoise_) { - vector match_1_2 = coord_1_mat.matchCol(coord_2_mat, sig_fig); + vector match_1_2 = matchCol(coord_1_mat,coord_2_mat, sig_fig); LOG("Counter Poise unscrambling matrix 2 with respect to matrix 1", 2); - auto unscrambled_2_Coef = unscramble_Coef(match_1_2, basis2, mat_2_Coef); + Eigen::MatrixXd unscrambled_2_Coef = unscramble_Coef(match_1_2, basis2, mat_2_Coef); this->mat_2_Coef = unscrambled_2_Coef; - vector match_1_P = coord_1_mat.matchCol(coord_P_mat, sig_fig); + vector match_1_P = matchCol(coord_1_mat,coord_P_mat, sig_fig); - auto unscrambled_P_Coef = unscramble_Coef(match_1_P, basisP, mat_P_Coef); + this->mat_P_Coef = unscramble_Coef(match_1_P, basisP, mat_P_Coef); - this->mat_P_Coef = unscrambled_P_Coef; - - auto unscrambled_S = unscramble_S(match_1_P, basisP, mat_S); - - this->mat_S = unscrambled_S; + this->mat_S = unscramble_S(match_1_P, basisP, mat_S); } else { - // Stores the rows in P that match 1 - vector match_1_P = coord_1_mat.matchCol(coord_P_mat, sig_fig); - + vector> match_mon_complex; + for ( const Eigen::MatrixXd & coord_mon : coord_monomers){ + // Returns each of the rows in complex that match each of the monomers + match_mon_complex.push_back(matchCol(coord_mon,coord_complex, sig_fig)); + } // Stores the rows in P that match 2 - vector match_2_P = coord_2_mat.matchCol(coord_P_mat, sig_fig); + //vector match_2_P = matchCol(coord_2_mat,coord_P_mat, sig_fig); LOG("Unscrambling dimer matrix with respect to matrix 1 and 2", 2); - auto unscrambled_P_Coef = - unscramble_Coef(match_1_P, match_2_P, basisP, mat_P_Coef); - - this->mat_P_Coef = unscrambled_P_Coef; - - auto unscrambled_S = unscramble_S(match_1_P, match_2_P, basisP, mat_S); - - this->mat_S = unscrambled_S; + //this->mat_P_Coef = + // unscramble_Coef(match_1_P, match_2_P, basisP, mat_P_Coef); + this->params_.complex_coefs = unscrambleCoef(match_mon_complex,basis_complex,complex_coefs); +// this->mat_S = unscramble_S(match_1_P, match_2_P, basisP, mat_S); + } } } -double TransferComplex::calcJ(const map &orbitaltype, - const map &orbnum) { +void TransferComplex::calcJ() { - if (unscrambled == false) { - cerr << "WARNING unable to automatically line up basis functions of" + if (unscrambled_ == false) { + cerr << "\nWARNING unable to automatically line up basis functions of" " monomers with dimers, you better make sure they correctly" " line up or run the calculations again with the correct " "flag pop=full" << endl; } - Matrix mat1coef; - Matrix mat2coef; - - string HOMO_OR_LUMO = orbitaltype.at("mon1"); - int MO = orbnum.at("mon1"); - if (HOMO_OR_LUMO.compare("HOMO") == 0) { - if (MO > 0) { - throw invalid_argument( - "Having specified HOMO the MO" - " value is in reference to the HOMO and must be a negative number"); - } - // Number of orbitals that are choices - if (MO <= (-1 * Orbs1.second)) { - string err = "You are trying to access HOMO" + to_string(MO) + - " but there " - "are only " + - to_string(Orbs1.second) + " HOMO orbitals"; - throw invalid_argument(err); - } - mat1coef = mat_1_Coef->getRow(Orbs1.second + MO); - } else if (HOMO_OR_LUMO.compare("LUMO") == 0) { - if (MO < 0) { - throw invalid_argument( - "Having specified LUMO the MO" - " value is in reference to the LUMO and must be a positive number"); - } - int allowed_LUMO = Orbs1.first - Orbs1.second; - if (MO >= allowed_LUMO) { - string err = "You are trying to access LUMO+" + to_string(MO) + - " but there " - "are only " + - to_string(allowed_LUMO) + " LUMO orbitals"; - throw invalid_argument(err); - } - mat1coef = mat_1_Coef->getRow(Orbs1.second + MO + 1); - } else { - throw invalid_argument("orbitals must be referred to as HOMO or LUMO"); - } - - HOMO_OR_LUMO = orbitaltype.at("mon2"); - MO = orbnum.at("mon2"); - if (HOMO_OR_LUMO.compare("HOMO") == 0) { - if (MO > 0) { - throw invalid_argument( - "Having specified HOMO the MO" - " value is in reference to the HOMO and must be a negative number"); - } - if (MO <= (-1 * Orbs2.second)) { - string err = "You are trying to access HOMO" + to_string(MO) + - " but there " - "are only " + - to_string(Orbs2.second) + " HOMO orbitals"; - throw invalid_argument(err); - } - mat2coef = mat_2_Coef->getRow(Orbs2.second + MO); - } else if (HOMO_OR_LUMO.compare("LUMO") == 0) { - if (MO < 0) { - throw invalid_argument( - "Having specified LUMO the MO" - " value is in reference to the LUMO and must be a positive number"); - } - int allowed_LUMO = Orbs2.first - Orbs2.second; - if (MO >= allowed_LUMO) { - string err = "You are trying to access LUMO+" + to_string(MO) + - " but there " - "are only " + - to_string(allowed_LUMO) + " LUMO orbitals"; - throw invalid_argument(err); - } - mat2coef = mat_2_Coef->getRow(Orbs2.second + MO + 1); - } else { - throw invalid_argument("orbitals must be referred to as HOMO or LUMO"); - } - - return calculate_transfer_integral(mat1coef, mat2coef, *mat_P_Coef, *mat_S, - *mat_P_OE, counterPoise_); + calculate_transfer_integral_(); } +*/ +} // namespace catnip diff --git a/src/libcatnip/qc_functions.hpp b/src/libcatnip/qc_functions.hpp index e8bc1a6..ba25bcc 100644 --- a/src/libcatnip/qc_functions.hpp +++ b/src/libcatnip/qc_functions.hpp @@ -1,3 +1,4 @@ +#pragma once #ifndef _CATNIP_QC_FUNCTIONS_HPP #define _CATNIP_QC_FUNCTIONS_HPP @@ -7,82 +8,166 @@ #include #include -#include "matrix.hpp" +//#include "matrix.hpp" +#include namespace catnip { class TransferComplex { - private: - Matrix* mat_1_Coef; - Matrix* mat_2_Coef; - Matrix* mat_P_Coef; - // Stores the number of Molecular orbitals - // and the HOMO for both monomer 1 and 2 - std::pair Orbs1; - std::pair Orbs2; - Matrix* mat_S; - Matrix* mat_P_OE; - // If unscrambaling is required - bool unscrambled; - bool counterPoise_; - - public: - TransferComplex(Matrix* mat1Coef, Matrix* mat2Coef, Matrix* matPCoef, - std::pair MOs1, std::pair MOs2, - Matrix* matS, Matrix* matPOE, bool cp); - - void unscramble(const Matrix& coord_1_mat, const Matrix& coord_2_mat, - const Matrix& coord_P_mat, const std::vector& basisP, - const std::vector& basis2); - - // Orbital type and a map of the corresponding number - // E.g. - // orbital type orbital number - // "mon1" "LUMO" "mon1" -3 - // "mon2" "HOMO" "mon2" 0 - // - // monomer1 LUMO-3 - // monomer2 HOMO - double calcJ(const std::map& orbitaltype, - const std::map& orbitalnum); -}; - -std::unordered_map> findRank( - Matrix& Orb_E_Alpha, Matrix& Orb_E_Beta); -double calculate_transfer_integral(const Matrix & mat_1_Coef, const Matrix & mat_2_Coef, - Matrix mat_P_Coef,const Matrix & mat_S, - const Matrix& mat_P_OE, bool counterPoise_); + public: + + struct Parameters { + const std::vector monomers_coefs; + const Eigen::MatrixXd complex_coefs; + /// Location of each of the homo_orbitals in each of the monomers + const std::vector homo_orbitals; + //HOMO_A; + //const int HOMO_B; + /// Atomic Orbital overlap matrix + const Eigen::MatrixXd S_AO; + const Eigen::VectorXd complex_orbital_energies; + /// Counter poise flag + bool counter_poise = false; + /// Calculate all couplings + bool calculate_all = false; + }; + + TransferComplex( + const Parameters params + /*const Eigen::MatrixXd & mat1Coef, + const Eigen::MatrixXd & mat2Coef, + const Eigen::MatrixXd & matPCoef, + const int HOMO_A, + const int HOMO_B, + const Eigen::MatrixXd & matS, + const Eigen::VectorXd & vecPOE, + bool cp*/); + + void unscramble( + const Eigen::MatrixXd& coord_1_mat, + const Eigen::MatrixXd& coord_2_mat, + const Eigen::MatrixXd& coord_P_mat, + const std::vector& basisP, + const std::vector& basis2); + + // Orbital type and a map of the corresponding number + // E.g. + // orbital type orbital number + // "mon1" "LUMO" "mon1" -3 + // "mon2" "HOMO" "mon2" 0 + // + // monomer1 LUMO-3 + // monomer2 HOMO + void calcJ(); + + /** + * \brief Print the transfer integral specified + **/ + void printTransferIntegral( + const std::map & orbital_type, + const std::map & orbnum) const; + + /** + * \brief Print All info in matrix form + **/ + void printAll() const; + + private: + + Parameters params_; +// Eigen::MatrixXd mat_1_Coef; +// Eigen::MatrixXd mat_2_Coef; +// Eigen::MatrixXd mat_P_Coef; + + /** + * \brief basis function overlap matrix + **/ + //Eigen::MatrixXd mat_S; + /** + * \brief Molecular orbital overlap matrix + **/ + Eigen::MatrixXd S_MO_; + + /** + * \brief Non orthonormalized Hamiltonian matrix + **/ + Eigen::MatrixXd Hamiltonian_; + + /** + * \brief Orthonormalized Hamiltonian Matrix + **/ + Eigen::MatrixXd Hamiltonian_eff_; + + //int HOMO_A_; + //int HOMO_B_; + + //Eigen::RowVectorXd vec_P_OE; + // If unscrambaling is required + bool unscrambled_; + //bool counterPoise_; + /* + * \brief Determine if the provided orbital is valid + **/ + bool orbitalValid_(const std::pair & orbital) const; + + void calculate_transfer_integral_(); + + void printTransferIntegral_(const std::pair & Orbital1, + const std::pair & Orbital2) const; +}; // Reorganize the dimer coefficients to match up with the monomers -Matrix organize_P_Coef(std::vector matchDimerA, +Eigen::MatrixXd organize_P_Coef(std::vector matchDimerA, std::vector matchDimerB, std::vector basisFuncA, std::vector basisFuncB, - std::vector basisFuncDimer, Matrix dimerCoef); + std::vector basisFuncDimer, Eigen::MatrixXd dimerCoef); // Unscramble the coefficients of the dimer matrix // Assumes that the match vectors describe swaps looking at a single // instance of the dimerCoef matrix -Matrix* unscramble_Coef(const std::vector& matchDimerA, - const std::vector& matchDimerB, - const std::vector& basisFuncDimer, - Matrix* dimerCoef); - -Matrix* unscramble_Coef(const std::vector& matchDimerA, - const std::vector& basisFuncDimer, Matrix* dimerCoef); +Eigen::MatrixXd unscramble_Coef( + const std::vector& matchDimerA, + const std::vector& matchDimerB, + const std::vector& basisFuncDimer, + const Eigen::MatrixXd & dimerCoef) { + Eigen::MatrixXd m; + return m; +} + +Eigen::MatrixXd unscramble_Coef( + const std::vector& matchDimerA, + const std::vector& basisFuncDimer, + const Eigen::MatrixXd & dimerCoef){ + Eigen::MatrixXd m; + return m; +} // Reorganize the dimer overlap matrix to line up with the monomer // coefficients. -Matrix* unscramble_S(const std::vector& matchDimerA, - const std::vector& matchDimerB, - const std::vector& basisFuncDimer, Matrix* S); - -Matrix* unscramble_S(const std::vector& matchDimerA, - const std::vector& basisFuncDimer, Matrix* S); - -Matrix* unscramble_OE(std::vector matchDimerA, - std::vector matchDimerB, - std::vector basisFuncDimer, Matrix* OE); - +/** + * + * Note S must not be a reference because it is altered during the unscrambling + **/ +Eigen::MatrixXd unscramble_S( + const std::vector& matchDimerA, + const std::vector& matchDimerB, + const std::vector& basisFuncDimer, + Eigen::MatrixXd S) { + Eigen::MatrixXd m; + return m; +} + +/** + * + * Note S must not be a reference because it is altered during the unscrambling + **/ +Eigen::MatrixXd unscramble_S( + const std::vector& matchDimerA, + const std::vector& basisFuncDimer, + Eigen::MatrixXd S){ + Eigen::MatrixXd m; + return m; +} } // namespace catnip #endif // _CATNIP_QC_FUNCTIONS_HPP diff --git a/src/libcatnip/size_type.hpp b/src/libcatnip/size_type.hpp new file mode 100644 index 0000000..7a4f4ce --- /dev/null +++ b/src/libcatnip/size_type.hpp @@ -0,0 +1,9 @@ +#pragma once +#ifndef _CATNIP_SIZE_TYPE_HPP +#define _CATNIP_SIZE_TYPE_HPP + +namespace catnip { + using Size = long int; +}; +#endif // _CATNIP_SIZE_TYPE_HPP + diff --git a/src/libcatnip/string_support.cpp b/src/libcatnip/string_support.cpp index 1c082e2..2414586 100644 --- a/src/libcatnip/string_support.cpp +++ b/src/libcatnip/string_support.cpp @@ -91,6 +91,12 @@ string firstN(string input, int n) { return input.substr(0, n); } string cut_beg(string input, int n) { return input.substr(n, input.size()); } +// Converts to uppercase +std::string to_upper(std::string input) { + std::for_each(input.begin(),input.end(), ::toupper); + return input; +} + // trim from both ends (in place) void trim(string &s) { ltrim_(s); diff --git a/src/libcatnip/string_support.hpp b/src/libcatnip/string_support.hpp index 6e7ba24..45af310 100644 --- a/src/libcatnip/string_support.hpp +++ b/src/libcatnip/string_support.hpp @@ -29,6 +29,9 @@ std::string firstN(std::string input, int n); std::string cut_beg(std::string input, int n); +// Converts a string to an upper case version +std::string to_upper(std::string input); + // trim from both ends (in place) void trim(std::string &s); diff --git a/src/libcatnip/swap_engine.cpp b/src/libcatnip/swap_engine.cpp new file mode 100644 index 0000000..1c6ef44 --- /dev/null +++ b/src/libcatnip/swap_engine.cpp @@ -0,0 +1,203 @@ + +// Local private includes +#include "swap_engine.hpp" + +#include "atom.hpp" +#include "atom_group.hpp" +#include "basis_map.hpp" +#include "size_type.hpp" + +// Standard includes +#include + +namespace catnip { + + + /** + * @brief Serves as scracth space + * + * Can store two rows at a time, the order they are loaded and unloaded is + * FIFO - first in first out + */ + class Scratch { + private: + Eigen::MatrixXd scratch_; + int size_; + bool empty_ = true; + public: + Scratch(int size) : size_(size) { + scratch_ = Eigen::MatrixXd::Zero(1,size_); + } + + bool empty() const noexcept { return empty_; } + + void loadFromRow(const Eigen::MatrixXd & mat, int row){ + for ( int i = 0; i < size_ ; ++i ){ + scratch_(0, i) = mat(row,i); + } + empty_ = false; + } + + void loadFromCol(const Eigen::MatrixXd & mat, int col){ + for ( int i = 0; i < size_ ; ++i ){ + scratch_(0, i) = mat(i,col); + } + empty_ = false; + } + void unloadToCol(Eigen::MatrixXd & mat, int col) { + for ( int i = 0; i < size_ ; ++i ){ + mat(i,col) = scratch_(0, i); + } + empty_ = true; + } + void unloadToRow(Eigen::MatrixXd & mat, int row) { + for ( int i = 0; i < size_ ; ++i ){ + mat(row, i) = scratch_(0, i); + } + empty_ = true; + } + + }; + + // Swaps rows columns and keeps up with how future swaps should be updated + SwapEngine::SwapEngine(BasisMap basis_map) { + + size_ = 0; + // The with the largest index will tell us the size we need to allocate + for ( std::pair> grp_rows : basis_map.row_col_final ){ + size_t max_value = *(std::max_element(grp_rows.second.begin(), grp_rows.second.end())); + size_ = std::max( max_value+1 , size_ ); + } + + // Want to order these + // 4 + // 3 + // 1 + // 2 + + // How can we order + // 4 <-> 2 2 <-> 3 3 <-> 1 + // + // > 2 > 3 > 1 + // 3 2 2 + // 1 1 3 + // 4 4 4 + // + + // Already have enough information to calculate the correct swap order + // Note the order of swaps is important. + for ( std::pair> & group_row : basis_map.row_col_current ){ + int group_ind = group_row.first; + size_t index = 0; + + assert(group_row.second.size()>0 && "ERROR a component has no rows."); + do { + int current_row_in_complex = group_row.second.at(index); + int final_row_in_complex = basis_map.row_col_final[group_ind].at(index); + + + if ( current_row_in_complex != final_row_in_complex ){ + // Row that currently occupies the location where the current row should + // go + auto group_and_row_ind = basis_map.findLocation(final_row_in_complex); + int replacement_row = basis_map.row_col_current[group_and_row_ind.first].at(group_and_row_ind.second); + std::pair swap(replacement_row, current_row_in_complex); + + // Final row location needs to be pointed to the starting row + basis_map.row_col_current[group_ind].at(index) = replacement_row; + basis_map.row_col_current[group_and_row_ind.first].at(group_and_row_ind.second) = current_row_in_complex; + + swap_order_.push_back(swap); + } else { + ++index; + } + } while (index < group_row.second.size()); + } + } + // This method of swapping was chosen to keep the memory footprint + // reasonable. + // Will correctly sort the rows and columns of the matrix + void SwapEngine::arrange(Eigen::MatrixXd & mat) { + + // Check that matrix is square + if( mat.rows() != mat.cols() ) { + throw std::runtime_error("Can only arrange square matrices"); + } + if( mat.rows() != static_cast(size_) ) { + throw std::runtime_error("Scratch space, swap procedure is not " + "consistent with the matrix."); + } + + arrangeRows(mat); + // Repeat for columns + arrangeCols(mat); + } + + void SwapEngine::arrangeCols(Eigen::MatrixXd & mat) { + // Check that matrix is square + if( mat.rows() != mat.cols() ) { + throw std::runtime_error("Can only arrange square matrices"); + } + if( mat.rows() != static_cast(size_) ) { + throw std::runtime_error("Scratch space, swap procedure is not " + "consistent with the matrix."); + } + arrangeCols_(mat); + } + + void SwapEngine::arrangeCols_(Eigen::MatrixXd & mat) { + + Scratch scratch(size_); + for ( size_t swap_ind = 0; swap_ind < swap_order_.size(); ++swap_ind ){ + + auto swap = swap_order_.at(swap_ind); + if (scratch.empty() ) { + scratch.loadFromCol(mat, swap.first); + } + // Write too the first instance + mat.col(swap.first) = mat.col(swap.second); + // If the next swap involves the row we just loaded don't bother writing + // it back into mat just keep it in scratch + if ( swap_ind + 1 < swap_order_.size() ){ + if( swap_order_.at(swap_ind+1).first == swap.second ) continue; + } + scratch.unloadToCol(mat, swap.second); + } + } + + void SwapEngine::arrangeRows(Eigen::MatrixXd & mat) { + // Check that matrix is square + if( mat.rows() != mat.cols() ) { + throw std::runtime_error("Can only arrange square matrices"); + } + if( mat.rows() != static_cast(size_) ) { + std::string error_msg = "Scratch space, swap procedure is not " + "consistent with the matrix. Rows in matrix " + + std::to_string(mat.rows()) + " size of scratch space " + + std::to_string(size_); + throw std::runtime_error(error_msg); + } + arrangeRows_(mat); + } + + void SwapEngine::arrangeRows_(Eigen::MatrixXd & mat) { + + Scratch scratch(size_); + for ( size_t swap_ind = 0; swap_ind < swap_order_.size(); ++swap_ind ){ + + auto swap = swap_order_.at(swap_ind); + if (scratch.empty() ) { + scratch.loadFromRow(mat, swap.first); + } + // Write too the first instance + mat.row(swap.first) = mat.row(swap.second); + // If the next swap involves the row we just loaded don't bother writing + // it back into mat just keep it in scratch + if ( swap_ind + 1 < swap_order_.size() ){ + if( swap_order_.at(swap_ind+1).first == swap.second ) continue; + } + scratch.unloadToRow(mat, swap.second); + } + + } +} // namespace catnip diff --git a/src/libcatnip/swap_engine.hpp b/src/libcatnip/swap_engine.hpp new file mode 100644 index 0000000..b230c0f --- /dev/null +++ b/src/libcatnip/swap_engine.hpp @@ -0,0 +1,31 @@ +#pragma once +#ifndef _CATNIP_SWAP_ENGINE_HPP +#define _CATNIP_SWAP_ENGINE_HPP + +#include "atom.hpp" +#include "atom_group.hpp" +#include "basis_map.hpp" +#include "size_type.hpp" + +namespace catnip { + + // Swaps rows columns and keeps up with how future swaps should be updated + class SwapEngine { + private: + size_t size_; + std::vector> swap_order_; + + void arrangeRows_(Eigen::MatrixXd & mat); + void arrangeCols_(Eigen::MatrixXd & mat); + public: + SwapEngine(BasisMap basis_map); + + void arrange(Eigen::MatrixXd & mat); + void arrangeRows(Eigen::MatrixXd & mat); + void arrangeCols(Eigen::MatrixXd & mat); + }; + + +} // namespace catnip + +#endif // _CATNIP_SWAP_ENGINE_HPP diff --git a/src/libcatnip/transfer_complex.cpp b/src/libcatnip/transfer_complex.cpp new file mode 100644 index 0000000..8c4e9da --- /dev/null +++ b/src/libcatnip/transfer_complex.cpp @@ -0,0 +1,1024 @@ + +// Local private includes +#include "transfer_complex.hpp" + +#include "atom.hpp" +#include "atom_group.hpp" +#include "basis_map.hpp" +#include "swap_engine.hpp" + +namespace catnip { + + void TransferComplex::unscramble(AtomSystem atom_sys) { + // We should figure out how all the rows and columns should be + // rearranged before moving any of the coefficients in the matrix + BasisMap basis_map = BasisMap(std::move(atom_sys)); + + size_t total_basis = atom_sys.getTotalBasisFunctions(GroupType::Component); + size_t total_basis_comp = atom_sys.getTotalBasisFunctions(GroupType::Complex); + + // If the total number of basis functions in the components is greater than + // the total number of basis functions in the complex, throw an error + if(total_basis != total_basis_comp) { + throw std::runtime_error("Sum of basis functions in components does not equal the number of basis functions in the complex"); + } + + auto swap_eng = SwapEngine(basis_map); + + //swap_eng.arrange(*(params_->complex_coefs)); + //swap_eng.arrange(*(params_->S_AO)); + +// auto dimension = mat_1_Coef.cols()+mat_2_Coef.cols(); +// Eigen::MatrixXd zetaA(mat_1_Coef.rows(),dimension); +// Eigen::MatrixXd zetaB(mat_2_Coef.rows(),dimension); +// if (params_->counter_poise) { +// +// } else { +// +// } + } + + void TransferComplex::calcJ() {}; +// using namespace std; +/* +// Essentially calculates the transfer integral +void TransferComplex::calculate_transfer_integral_() { + + auto dimension = mat_1_Coef.cols()+mat_2_Coef.cols(); + Eigen::MatrixXd zetaA(mat_1_Coef.rows(),dimension); + Eigen::MatrixXd zetaB(mat_2_Coef.rows(),dimension); + if (counterPoise_) { + + LOG("Creating zeta matrices from coefficients assuming counterpoise", 2); + zetaA = mat_1_Coef; + zetaB = mat_2_Coef; + } else { + LOG("Creating zeta matrices from coefficients", 2); + zetaA << mat_1_Coef, Eigen::MatrixXd::Zero(mat_1_Coef.rows(),mat_2_Coef.cols()); + zetaB << Eigen::MatrixXd::Zero(mat_2_Coef.rows(),mat_1_Coef.cols()), mat_2_Coef; + } + + LOG("Creating gamma and beta matrices", 2); + Eigen::MatrixXd gammaA = zetaA * mat_S * mat_P_Coef.transpose(); + Eigen::MatrixXd gammaB = zetaB * mat_S * mat_P_Coef.transpose(); + + assert(gammaA.cols() == gammaB.cols() && "Column count between gamma A and B must be consistent"); + Eigen::MatrixXd gamma(gammaA.rows()+gammaB.rows(),gammaA.cols()); + gamma << gammaA, gammaB; + + LOG("Calculating S_MO", 2); + S_MO.resize(dimension,dimension); + S_MO = gamma * gamma.transpose(); + + Eigen::SelfAdjointEigenSolver eigen_solver(S_MO); + Eigen::MatrixXd S_MO_inv_sqrt = eigen_solver.operatorInverseSqrt(); + + Hamiltonian.resize(mat_S.rows(),mat_S.cols()); + Hamiltonian = gamma * vec_P_OE.asDiagonal() * gamma.transpose(); + + Hamiltonian_eff = S_MO_inv_sqrt * Hamiltonian * S_MO_inv_sqrt; +} + +void TransferComplex::printTransferIntegral( + const map &orbitaltype, + const map &orbnum) const { + + string HOMO_OR_LUMO_A = orbitaltype.at("mon1"); + int MO_A = orbnum.at("mon1"); + if (HOMO_OR_LUMO_A.compare("HOMO") == 0) { + if (MO_A > 0) { + throw invalid_argument( + "Having specified HOMO the MO_A" + " value is in reference to the HOMO and must be a negative number"); + } + // Number of orbitals that are choices + if (MO_A <= (-1 * HOMO_A_)) { + string err = "You are trying to access HOMO" + to_string(MO_A) + + " but there " + "are only " + + to_string(HOMO_A_) + " HOMO orbitals"; + throw invalid_argument(err); + } + } else if (HOMO_OR_LUMO_A.compare("LUMO") == 0) { + if (MO_A < 0) { + throw invalid_argument( + "Having specified LUMO the MO_A" + " value is in reference to the LUMO and must be a positive number"); + } + int allowed_LUMO = mat_1_Coef.rows() - HOMO_A_; + if (MO_A >= allowed_LUMO) { + string err = "You are trying to access LUMO+" + to_string(MO_A) + + " but there " + "are only " + + to_string(allowed_LUMO) + " LUMO orbitals"; + throw invalid_argument(err); + } + } else { + throw invalid_argument("orbitals must be referred to as HOMO or LUMO"); + } + + string HOMO_OR_LUMO_B = orbitaltype.at("mon2"); + int MO_B = orbnum.at("mon2"); + if (HOMO_OR_LUMO_B.compare("HOMO") == 0) { + if (MO_B > 0) { + throw invalid_argument( + "Having specified HOMO the MO_B" + " value is in reference to the HOMO and must be a negative number"); + } + if (MO_B <= (-1 * HOMO_B_)) { + string err = "You are trying to access HOMO" + to_string(MO_B) + + " but there " + "are only " + + to_string(HOMO_B_) + " HOMO orbitals"; + throw invalid_argument(err); + } + } else if (HOMO_OR_LUMO_B.compare("LUMO") == 0) { + if (MO_B < 0) { + throw invalid_argument( + "Having specified LUMO the MO_B" + " value is in reference to the LUMO and must be a positive number"); + } + int allowed_LUMO = mat_2_Coef.rows() - HOMO_B_; + if (MO_B >= allowed_LUMO) { + string err = "You are trying to access LUMO+" + to_string(MO_B) + + " but there " + "are only " + + to_string(allowed_LUMO) + " LUMO orbitals"; + throw invalid_argument(err); + } + } else { + throw invalid_argument("orbitals must be referred to as HOMO or LUMO"); + } + + printTransferIntegral_( + pair(HOMO_OR_LUMO_A,MO_A), + pair(HOMO_OR_LUMO_B,MO_B)); +} +// Find the transfer integral between two orbitals. +// pair string - Either HOMO or LUMO +// int - is the orbital number HOMO-3 LUMO+5 +void TransferComplex::printTransferIntegral_( + const pair& orbital1, + const pair& orbital2) const { + + int offset = mat_1_Coef.rows(); + int orbital1_num = 0; + int orbital2_num = 0; + if(orbital1.first.compare("HOMO")==0){ + assert(orbitalValid_(orbital1)==true); + orbital1_num = orbital1.second + HOMO_A_-1; + }else if(orbital1.first.compare("LUMO")==0){ + assert(orbitalValid_(orbital1)==true); + orbital1_num = orbital1.second + HOMO_A_; + } + if(orbital2.first.compare("HOMO")==0){ + assert(orbitalValid_(orbital2)==true); + orbital2_num = offset+orbital2.second + HOMO_B_-1; + }else if(orbital2.first.compare("LUMO")==0){ + assert(orbitalValid_(orbital2)==true); + orbital2_num = offset+orbital2.second + HOMO_B_; + } + double J_ab = Hamiltonian(orbital1_num,orbital2_num); + double e_a = Hamiltonian(orbital1_num,orbital1_num); + double e_b = Hamiltonian(orbital2_num,orbital2_num); + double S_ab = S_MO(orbital1_num,orbital2_num); + + cout << "\nPre-Orthonormalization" << endl; + cout << "J_ab " << J_ab * hartreeToeV << " eV\n"; + cout << "e_a " << e_a * hartreeToeV << " eV\n"; + cout << "e_b " << e_b * hartreeToeV << " eV\n"; + cout << "S_ab " << S_ab << "\n" << endl; + + cout << "Single Orbital DIPRO" << endl; + double J_ab_single = (J_ab - 0.5*(e_a+e_b)*S_ab)/(1-pow(S_ab,2.0)); + double e_a_single = 0.5*((e_a+e_b)-2*J_ab*S_ab+(e_a-e_b)*pow(1-pow(S_ab,2.0),0.5))/(1-pow(S_ab,2.0)); + double e_b_single = 0.5*((e_a+e_b)-2*J_ab*S_ab-(e_a-e_b)*pow(1-pow(S_ab,2.0),0.5))/(1-pow(S_ab,2.0)); + cout << "J_ab_eff_single " << J_ab_single * hartreeToeV << " eV\n"; + cout << "e_a_eff_single " << e_a_single * hartreeToeV << " eV\n"; + cout << "e_b_eff_single " << e_b_single * hartreeToeV << " eV\n" << endl; + + cout << "All Orbital DIPRO" << endl; + double J_eff = Hamiltonian_eff(orbital1_num,orbital2_num); + double e_a_eff = Hamiltonian_eff(orbital1_num,orbital1_num); + double e_b_eff = Hamiltonian_eff(orbital2_num,orbital2_num); + cout << "J_ab_eff_all " << J_eff * hartreeToeV << " eV\n"; + cout << "e_a_eff_all " << e_a_eff * hartreeToeV << " eV\n"; + cout << "e_b_eff_all " << e_b_eff * hartreeToeV << " eV\n" << endl; + +} + +void TransferComplex::printAll() const { + + int column_width = 14; + cout << "Effective Hamiltonian" << endl; + + int col_offset = mat_1_Coef.cols(); + int start_col = 0; + int end_col = 5; + while(start_colHamiltonian.cols()){ + end_col = Hamiltonian.cols(); + } + for(int orbital_num = start_col;orbital_num=col_offset && orbital_num<(HOMO_B_+col_offset))){ + if(orbital_num=HOMO_A_ && orbital_num(col_offset+HOMO_B_)){ + if(orbital_num=col_offset && orbital_num<(HOMO_B_+col_offset))){ + if(orbital_num & orbital) const{ + int HOMO_AB = HOMO_A_+HOMO_B_; + int LUMO_AB = HOMO_AB+1; + if(orbital.first.compare("HOMO")==0){ + if(orbital.second>0){ + cerr << "HOMO orbital number is not negative or 0" << endl; + return false; + } + if(orbital.second>HOMO_AB){ + cerr << "HOMO orbital does not exst " << orbital.second << " "<< HOMO_AB << endl; + return false; + } + }else if(orbital.first.compare("LUMO")==0){ + if(orbital.second<0){ + cerr << "LUMO orbital number is not positive or 0" << endl; return false; + } + if(orbital.second>(Hamiltonian_eff.rows()-LUMO_AB)){ + cerr << "LUMO orbital does not exst " << orbital.second << endl; + return false; + } + } + return true; +} +// Split a matrix up into a list of smaller matrices. The matrix can be split +// in columns or in rows. The number of rows/cols in each smaller matrix is +// held in the vector subMatrixDimension +// +// E.g. Given the matrix +// +// 1 2 3 +// 3 4 5 +// +// subMatrixDimension = { 2 1 } +// +// And I split by cols +// +// list contain +// +// matrix 1 matrix 2 +// 1 2 3 +// 3 4 5 +// +list splitMatrixIntoList( + const vector &subMatrixDimension, + const Eigen::MatrixXd mat, + const string &ColRowSplit) { + + list list_matrix; + int num_sub_matrices = subMatrixDimension.size(); + if (ColRowSplit.compare("Columns") == 0) { + int col = 0; + for (int i = 0; i < num_sub_matrices; ++i) { + Eigen::MatrixXd mat_new(mat.rows(), subMatrixDimension.at(i)); + for (auto k = 0; k < mat.rows(); ++k) { + for (auto j = 0; j < subMatrixDimension.at(i); ++j) { + mat_new(k,j) = mat(k, col + j); + } + } + col += subMatrixDimension.at(i); + list_matrix.push_back(mat_new); + } + } else if (ColRowSplit.compare("Rows") == 0) { + int row = 0; + for (auto i = 0; i < num_sub_matrices; ++i) { + Eigen::MatrixXd mat_new(subMatrixDimension.at(i), mat.cols()); + for (auto k = 0; k < mat.cols(); ++k) { + for (auto j = 0; j < subMatrixDimension.at(i); ++j) { + mat_new(j,k) = mat(row + j, k); + } + } + row += subMatrixDimension.at(i); + list_matrix.push_back(mat_new); + } + } else { + throw invalid_argument("Unrecognized string tag provided"); + } + return list_matrix; +} + +list splitCoefsUpByAtoms(const vector & basisFuncP, Eigen::MatrixXd Coefs, + const string & ColRow) { + return splitMatrixIntoList(basisFuncP, Coefs, ColRow); +} + +// The purpose of this function is to ensure that swapping occurs correctly +// The following example explains in more detail what this is meant to do +// Now if we have a matrix in a specific state and want to swap the rows +// we can not simply list all the rows that need to be changed and then make +// the changes. +// +// We have to figure out how to swap rows sequentially without ending up with +// the wrong result. +// +// For instance say we have a matrix +// index 1 | row 1 +// index 2 | row 2 +// index 3 | row 3 +// index 4 | row 4 +// +// where: +// Row 1 needs to be at index 3 +// Row 4 needs to be at index 1 +// Row 2 needs to be at index 2 +// Row 3 needs to be at index 4 +// +// If we simply looked at our first instance of the matrix shown above +// and came up with the following swaps +// Swap row 1 with index 3 +// Swap row 4 with index 1 +// Swap row 2 with index 2 +// Swap row 3 with index 4 +// +// First swap +// index 1 row3 +// index 2 row2 +// index 3 row1 +// index 4 row4 +// +// Second swap +// index 1 row4 +// index 2 row2 +// index 3 row1 +// index 4 row3 +// +// Third swap does nothing +// Fourth swap +// index 1 row4 +// index 2 row2 +// index 3 row3 +// index 4 row1 +// +// When what we really wanted was +// index 1 row4 +// index 2 row2 +// index 3 row1 +// index 4 row3 +// +// Notice the row3 and row1 are in the wrong place +// The instructions should be rewritten +// Swap row 1 with index 3 +// Swap row 4 with index 3 +// Swap row 2 with index 2 - no swap +// Swap row 3 with index 3 - no swap +// +void refreshSwapOrder(vector> &monBmatch, + vector> &monAmatch) { + + // Because matrix B appears at the top of our full matrix e.g. + // + // [ B ] + // [ A ] + // + // When sorting out the swap order we need to cycle through elements in B and + // see where they appear in both the B and A matrix + // + // B -> [ B ] + // B -> [ A ] + // + for (auto pr_ptr = monBmatch.begin(); pr_ptr != monBmatch.end(); ++pr_ptr) { + auto pr = *pr_ptr; + + int row1was = pr.first; + int row1is = pr.second; + auto pr_ptr_temp = pr_ptr; + pr_ptr_temp++; + while (pr_ptr_temp != monBmatch.end()) { + pr_ptr_temp = find_if( + pr_ptr_temp, monBmatch.end(), + [row1was](const pair &p) { return row1was == p.second; }); + if (pr_ptr_temp != monBmatch.end()) { + pr_ptr_temp->second = row1is; + } + } + pr_ptr_temp = monAmatch.begin(); + while (pr_ptr_temp != monAmatch.end()) { + pr_ptr_temp = find_if( + pr_ptr_temp, monAmatch.end(), + [row1was](const pair &p) { return row1was == p.second; }); + if (pr_ptr_temp != monAmatch.end()) { + pr_ptr_temp->second = row1is; + } + } + } + // Here we have already looked at the rows in B and they are up to date but + // we still need to make sure the rows in A are swapped in the appropriate + // order + // + // [ B ] + // A -> [ A ] + // + for (auto pr_ptr = monAmatch.begin(); pr_ptr != monAmatch.end(); ++pr_ptr) { + auto pr = *pr_ptr; + int row1was = pr.first; + int row1is = pr.second; + if (row1was != row1is) { + auto pr_ptr_temp = pr_ptr; + pr_ptr_temp++; + while (pr_ptr_temp != monAmatch.end()) { + pr_ptr_temp = find_if( + pr_ptr_temp, monAmatch.end(), + [row1was](const pair &p) { return row1was == p.second; }); + if (pr_ptr_temp != monAmatch.end()) { + pr_ptr_temp->second = row1is; + } + } + } + } + return; +} + +void refreshSwapOrder(vector> &monAmatch) { + + for (auto pr_ptr = monAmatch.begin(); pr_ptr != monAmatch.end(); ++pr_ptr) { + auto pr = *pr_ptr; + + int row1was = pr.first; + int row1is = pr.second; + auto pr_ptr_temp = pr_ptr; + pr_ptr_temp++; + while (pr_ptr_temp != monAmatch.end()) { + pr_ptr_temp = find_if( + pr_ptr_temp, monAmatch.end(), + [row1was](const pair &p) { return row1was == p.second; }); + if (pr_ptr_temp != monAmatch.end()) { + pr_ptr_temp->second = row1is; + } + } + } + return; +} + +// To replace both refreshSwapOrder and updateSwapLists +// instead of figuring out a proper order for swapping we will simply start +// with a new link list of the same size and place the coefficents in that +// new list +Eigen::MatrixXd createSortedCoefMatrix(vector> & mon_match_ind, list & atom_mat_coefs){ + + // Actually lets use a vector of pointers to the matrices that are in the list + vector mat_ptrs; + // Error checking + if(atom_mat_coefs.size()==0){ + throw std::runtime_error("ERROR cannot create sorted coef matrix, there are atomically partitioned matrices to build the full sorted coef matrix from."); + } + + int cols = atom_mat_coefs.front().cols(); + for ( list::iterator coef_ptr = atom_mat_coefs.begin(); + coef_ptr != atom_mat_coefs.end(); + ++coef_ptr ){ + if(coef_ptr->cols()!=cols){ + throw std::runtime_error("ERROR cannot created sorted coef matrix from atomically partitioned matrices with varying number of columns."); + } + } + // End of error checking + + // Count the total number of rows in each atomically partitioned coef matrix + vector rows_per_mat; + for ( list::iterator coef_ptr = atom_mat_coefs.begin(); + coef_ptr != atom_mat_coefs.end(); + ++coef_ptr ){ + rows_per_mat.push_back(coef_ptr->rows()); + } + + int initial_value = 0; + int total_rows = std::accumulate(rows_per_mat.begin(),rows_per_mat.end(), initial_value); + + // Determine the offset of each row to each index + std::map row_to_index_offset; + int offset = 0; + for ( std::pair & row_ind : mon_match_ind ){ + row_to_index_offset.at(row_ind.first) = offset; + offset+= rows_per_mat.at(row_ind.second); + } + + Eigen::MatrixXd sorted_atom_mat_coefs + + + +} +// The above function determines the appropriate sequence of swaps this function +// then actually implements the swaps by exchanging the matrices in the list. +void updateSwapLists(vector> &monBmatch, + vector> &monAmatch, + list &p_atom_mat_coef) { + + for (auto p : monBmatch) { + if (p.first != p.second) { + auto it = p_atom_mat_coef.begin(); + Eigen::MatrixXd temp = *(next(it, p.first)); + *(next(it, p.first)) = *(next(it, p.second)); + *(next(it, p.second)) = temp; + } + } + for (auto p : monAmatch) { + if (p.first != p.second) { + auto it = p_atom_mat_coef.begin(); + Eigen::MatrixXd temp = *(next(it, p.first)); + *(next(it, p.first)) = *(next(it, p.second)); + *(next(it, p.second)) = temp; + } + } + return; +} +void updateSwapLists(vector> &monAmatch, + list &atom_mat_coef) { + + for (auto p : monAmatch) { + if (p.first != p.second) { + auto it = atom_mat_coef.begin(); + Eigen::MatrixXd & temp = *(next(it, p.first)); + *(next(it, p.first)) = *(next(it, p.second)); + *(next(it, p.second)) = temp; + } + } + return; +} + +Eigen::MatrixXd mergeListOfMatrices(list &matrix_list, const int rows, + const int cols, const string &ColRowMerge) { + + Eigen::MatrixXd full_matrix(rows, cols); + if (ColRowMerge.compare("Columns") == 0) { + int col = 0; + for (auto it = matrix_list.begin(); it != matrix_list.end(); ++it) { + Eigen::MatrixXd mat = *it; + int row = 0; + if (col > cols) + throw runtime_error("Your new matrix is not large enough"); + for (auto i = 0; i < mat.rows(); ++i) { + if (row > rows) + throw runtime_error("Your new matrix is not large enough"); + for (auto j = 0; j < mat.cols(); ++j) { + full_matrix(row,j+col) = mat(i, j); + } + ++row; + } + col += mat.cols(); + } + } else if (ColRowMerge.compare("Rows") == 0) { + int row = 0; + for (auto it = matrix_list.begin(); it != matrix_list.end(); ++it) { + Eigen::MatrixXd mat = *it; + int col = 0; + if (row > rows) + throw runtime_error("Your new matrix is not large enough"); + for (auto j = 0; j < mat.cols(); ++j) { + if (col > cols) + throw runtime_error("Your new matrix is not large enough"); + for (auto i = 0; i < mat.rows(); ++i) { + full_matrix(row + i, col) = mat(i, j); + } + ++col; + } + row += mat.rows(); + } + } else { + throw invalid_argument("Unrecognized merge type for list of matrices"); + } + return full_matrix; +} + +// This function +Eigen::MatrixXd createNewMatrix(list &p_atom_mat_coef, int rows, int cols, + const string &ColRow) { + return mergeListOfMatrices(p_atom_mat_coef, rows, cols, ColRow); +} + +// unscramble the coefficients +//Eigen::MatrixXd unscramble_Coef( +// const std::vector &matchDimerA, +// const std::vector &matchDimerB, +// const std::vector &basisFuncP, +// const Eigen::MatrixXd & dimerCoef) { +// +// // Let's reduce the complexity of the problem by instead of working +// // with the basis functions lets just work with the atoms. We can do +// // this by treating all the basis functions associated with a single +// // atom as a block. +// +// list p_atom_mat_coef = +// splitCoefsUpByAtoms(basisFuncP, dimerCoef, "Columns"); +// +// // Place all of monomer A atom basis functions on the left side of the +// // matrix and all of B monomer atom basis functions on the right side +// // of the dimer matrix +// // First int is the col in the dimer the atom should be at +// // Second int is the col in the dimer the atom is presently at +// +// vector> monAmatch; +// for (unsigned i = 0; i < matchDimerA.size(); ++i) { +// pair pr(i, matchDimerA.at(i)); +// monAmatch.push_back(pr); +// } +// vector> monBmatch; +// for (unsigned i = 0; i < matchDimerB.size(); ++i) { +// pair pr(i + monAmatch.size(), matchDimerB.at(i)); +// monBmatch.push_back(pr); +// } +// +// refreshSwapOrder(monBmatch, monAmatch); +// updateSwapLists(monBmatch, monAmatch, p_atom_mat_coef); +// +// Eigen::MatrixXd dimerCoef_new = createNewMatrix( +// p_atom_mat_coef, dimerCoef.rows(), dimerCoef.cols(), "Columns"); +// +// return dimerCoef_new; +//} +// +//// unscramble the coefficients +//Eigen::MatrixXd unscramble_Coef( +// const std::vector &matchDimerB, +// const std::vector &basisFuncB, +// const Eigen::MatrixXd &Coef) { +// +// // Let's reduce the complexity of the problem by instead of working +// // with the basis functions lets just work with the atoms. We can do +// // this by treating all the basis functions associated with a single +// // atom as a block. +// +// list atom_mat_coef = +// splitCoefsUpByAtoms(basisFuncB, Coef, "Columns"); +// +// // Place all of monomer A atom basis functions on the left side of the +// // matrix and all of B monomer atom basis functions on the right side +// // of the matrix +// // First int is the col in the dimer the atom should be at +// // Second int is the col in the dimer the atom is presently at +// +// vector> monBmatch; +// for (unsigned i = 0; i < matchDimerB.size(); ++i) { +// pair pr(i, matchDimerB.at(i)); +// monBmatch.push_back(pr); +// } +// +// refreshSwapOrder(monBmatch); +// updateSwapLists(monBmatch, atom_mat_coef); +// Eigen::MatrixXd Coef_new = createNewMatrix(atom_mat_coef, Coef.rows(), +// Coef.cols(), "Columns"); +// return Coef_new; +//} + +Eigen::MatrixXd unscrambleCoef( + const std::vector> &match_mon_complex, + const std::vector &basis_functions_complex, + const Eigen::MatrixXd & complex_coefs) { + + // Let's reduce the complexity of the problem by instead of working + // with the basis functions lets just work with the atoms. We can do + // this by treating all the basis functions associated with a single + // atom as a block. + + list complex_coef_block = + splitCoefsUpByAtoms(basis_functions_complex, complex_coefs, "Columns"); + + // Place all of monomer A atom basis functions on the left side of the + // matrix and all of B monomer atom basis functions on the right side + // of the dimer matrix + // First int is the col in the dimer the atom should be at + // Second int is the col in the dimer the atom is presently at + +// vector> monBmatch; +// for (unsigned i = 0; i < matchDimerB.size(); ++i) { +// pair pr(i, matchDimerB.at(i)); +// monBmatch.push_back(pr); +// } + + vector>> mon_match_index; + unsigned new_index = 0; + for ( const vector & monomer_rows : match_mon_complex){ + vector> mon_matching_index_row; + for( const int & row_index : monomer_rows ){ + pair pr(new_index,row_index); + mon_matching_index_row.push_back(pr); + } + mon_match_index.push_back(mon_matching_index_row); + } + + //refreshSwapOrder(monBmatch); +// refreshSwapOrder(mon_match_index); + // updateSwapLists(monBmatch, atom_mat_coef); + Eigen::MatrixXd Coef_new = createNewMatrix(atom_mat_coef, Coef.rows(), + Coef.cols(), "Columns"); + return Coef_new; + + +} +// Similar to the above function but we will be moving both the rows +// and columns +Eigen::MatrixXd unscramble_S( + const std::vector &matchDimerA, + const std::vector &matchDimerB, + const std::vector &basisFuncP, + Eigen::MatrixXd S) { + + Eigen::MatrixXd S_new(S.rows(),S.cols()); + { + list p_atom_mat_S = splitCoefsUpByAtoms(basisFuncP, S, "Columns"); + vector> monAmatch; + for (unsigned i = 0; i < matchDimerA.size(); ++i) { + pair pr(i, matchDimerA.at(i)); + monAmatch.push_back(pr); + } + vector> monBmatch; + for (unsigned i = 0; i < matchDimerB.size(); ++i) { + pair pr(i + monAmatch.size(), matchDimerB.at(i)); + monBmatch.push_back(pr); + } + + refreshSwapOrder(monBmatch, monAmatch); + updateSwapLists(monBmatch, monAmatch, p_atom_mat_S); + S_new = + createNewMatrix(p_atom_mat_S, S.rows(), S.cols(), "Columns"); + } + + S = S_new; + + { + list p_atom_mat_S = splitCoefsUpByAtoms(basisFuncP, S, "Rows"); + + vector> monAmatch; + for (unsigned i = 0; i < matchDimerA.size(); ++i) { + pair pr(i, matchDimerA.at(i)); + monAmatch.push_back(pr); + } + vector> monBmatch; + for (unsigned i = 0; i < matchDimerB.size(); ++i) { + pair pr(i + monAmatch.size(), matchDimerB.at(i)); + monBmatch.push_back(pr); + } + + refreshSwapOrder(monBmatch, monAmatch); + updateSwapLists(monBmatch, monAmatch, p_atom_mat_S); + S_new = createNewMatrix(p_atom_mat_S, S.rows(), S.cols(), "Rows"); + } + + // Return the correctly swapped dimerCoef + return S_new; +} + +// Same as the above function but here we are assuming counterpoise correction +// is being used and thus we do not need to match with both monomer A and +// monomer B but only need to match with A. +Eigen::MatrixXd unscramble_S( + const std::vector &matchDimerA, + const std::vector &basisFuncP, + Eigen::MatrixXd S) { + + Eigen::MatrixXd S_new(S.rows(),S.cols()); + { + list p_atom_mat_S = splitCoefsUpByAtoms(basisFuncP, S, "Columns"); + + vector> monAmatch; + for (unsigned i = 0; i < matchDimerA.size(); ++i) { + pair pr(i, matchDimerA.at(i)); + monAmatch.push_back(pr); + } + refreshSwapOrder(monAmatch); + updateSwapLists(monAmatch, p_atom_mat_S); + S_new = + createNewMatrix(p_atom_mat_S, S.rows(), S.cols(), "Columns"); + } + + S = S_new; + + { + list p_atom_mat_S = splitCoefsUpByAtoms(basisFuncP, S, "Rows"); + + vector> monAmatch; + for (unsigned i = 0; i < matchDimerA.size(); ++i) { + pair pr(i, matchDimerA.at(i)); + monAmatch.push_back(pr); + } + + refreshSwapOrder(monAmatch); + updateSwapLists(monAmatch, p_atom_mat_S); + S_new = createNewMatrix(p_atom_mat_S, S.rows(), S.cols(), "Rows"); + } + + // Return the correctly swapped dimerCoef + return S_new; +} + + +//TransferComplex::TransferComplex( +// const Eigen::MatrixXd & mat1Coef, +// const Eigen::MatrixXd & mat2Coef, +// const Eigen::MatrixXd & matPCoef, +// const int HOMO_A, +// const int HOMO_B, +// const Eigen::MatrixXd & matS, +// const Eigen::VectorXd & vecPOE, bool cp) { +// +TransferComplex::TransferComplex(const Parameters params) : params_(params) { + + unscrambled_ = false; +// counterPoise_ = cp; + // Consistency check + if (params_.S_AO.cols() != params_.mat_complex.cols()) { + throw invalid_argument( + "The overlap matrix must have the same number " + "of basis functions as the dimer"); + } + //if (cp) { + if (params_.counter_poise) { + int monomer_number = 1; + for ( const Eigen::MatrixXd & mat : params_.mat_monomers){ + if(params_.mat_complex.cols() != mat.cols()){ + throw invalid_argument( + "Counter poise correction requires that the" + " monomers have the same number of coefficients as the complex. " + "Your monomer " + std::to_string(monomer_number) +" does not"); + } + ++monomer_number; + } +// if (mat1Coef.cols() != matPCoef.cols()) { +// throw invalid_argument( +// "Counter poise correction requires that the" +// " monomers have the same number of coefficients as the dimer. " +// "Your monomer 1 does not"); +// } +// if (mat2Coef.cols() != matPCoef.cols()) { +// throw invalid_argument( +// "Counter poise correction requires that the" +// " monomers have the same number of coefficients as the dimer. " +// "Your monomer 2 does not"); +// } + } else { + /// If not counter poise the sum of the cols should equal the same number as is in the complex +// int total_cols = mat1Coef.cols() + mat2Coef.cols(); + int total_cols = 0; + for ( const Eigen::MatrixXd & mat : params_.mat_monomers){ + total_cols+=mat.cols(); + } + + //if (total_cols > matPCoef.cols()) { + if (total_cols > params_.mat_complex.cols()) { + throw invalid_argument( + "Counter poise has not been specified and the total number of " + "basis functions in your monomers is more than the number of basis " + "functions in your complex."); + }else if(total_cols < params_.complex_coefs.cols()){ + throw invalid_argument( + "Counter poise has not been specified and the total number of " + "basis functions in your monomers is less than the number of basis " + "functions in your complex."); + } + } +// +// mat_1_Coef.resize(mat1Coef.rows(),mat1Coef.cols()); +// mat_1_Coef = mat1Coef; +// mat_2_Coef.resize(mat2Coef.rows(),mat2Coef.cols()); +// mat_2_Coef = mat2Coef; +// mat_P_Coef.resize(matPCoef.rows(),matPCoef.cols()); +// mat_P_Coef = matPCoef; +// HOMO_A_ = HOMO_A; +// HOMO_B_ = HOMO_B; +// mat_S.resize(matS.rows(),matS.cols()); +// mat_S = matS; +// vec_P_OE.resize(vecPOE.size()); +// vec_P_OE = vecPOE; +} + +//void TransferComplex::unscramble(const Eigen::MatrixXd &coord_1_mat, +// const Eigen::MatrixXd &coord_2_mat, +// const Eigen::MatrixXd &coord_P_mat, +// const std::vector &basisP, +// const std::vector &basis2) { +// +void TransferComplex::unscramble(const vector &coord_monomers, + const Eigen::MatrixXd &coord_complex, + const std::vector &basis_complex, + const std::vector &basis2) { + unscrambled_ = true; + + const int sig_fig = 4; + + // If dealing with counter poise correction may also need to unscramble + // the basis functions of the monomers + if (counterPoise_) { + vector match_1_2 = matchCol(coord_1_mat,coord_2_mat, sig_fig); + + LOG("Counter Poise unscrambling matrix 2 with respect to matrix 1", 2); + Eigen::MatrixXd unscrambled_2_Coef = unscramble_Coef(match_1_2, basis2, mat_2_Coef); + + this->mat_2_Coef = unscrambled_2_Coef; + + vector match_1_P = matchCol(coord_1_mat,coord_P_mat, sig_fig); + + this->mat_P_Coef = unscramble_Coef(match_1_P, basisP, mat_P_Coef); + + this->mat_S = unscramble_S(match_1_P, basisP, mat_S); + + } else { + + vector> match_mon_complex; + for ( const Eigen::MatrixXd & coord_mon : coord_monomers){ + // Returns each of the rows in complex that match each of the monomers + match_mon_complex.push_back(matchCol(coord_mon,coord_complex, sig_fig)); + } + // Stores the rows in P that match 2 + //vector match_2_P = matchCol(coord_2_mat,coord_P_mat, sig_fig); + + LOG("Unscrambling dimer matrix with respect to matrix 1 and 2", 2); + //this->mat_P_Coef = + // unscramble_Coef(match_1_P, match_2_P, basisP, mat_P_Coef); + this->params_.complex_coefs = unscrambleCoef(match_mon_complex,basis_complex,complex_coefs); +// this->mat_S = unscramble_S(match_1_P, match_2_P, basisP, mat_S); + } + } +} + +void TransferComplex::calcJ() { + + if (unscrambled_ == false) { + cerr << "\nWARNING unable to automatically line up basis functions of" + " monomers with dimers, you better make sure they correctly" + " line up or run the calculations again with the correct " + "flag pop=full" + << endl; + } + + calculate_transfer_integral_(); +} +*/ +} // namespace catnip diff --git a/src/libcatnip/transfer_complex.hpp b/src/libcatnip/transfer_complex.hpp new file mode 100644 index 0000000..2dbd63a --- /dev/null +++ b/src/libcatnip/transfer_complex.hpp @@ -0,0 +1,80 @@ +#pragma once +#ifndef _CATNIP_TRANSFER_COMPLEX_HPP +#define _CATNIP_TRANSFER_COMPLEX_HPP + +// Local private includes +#include "atom_system.hpp" + +// Third party includes +#include + +// Standard includes +#include +#include +#include +#include +#include + +namespace catnip { + +class TransferComplex { + + public: + + class Parameters { + public: + + // It actually makes more sense to place these in the atom groups + //const std::vector> monomers_coefs; + //const std::unique_ptr complex_coefs; + /// Location of each of the homo_orbitals in each of the monomers + //const std::vector homo_orbitals; + //HOMO_A; + //const int HOMO_B; + /// Atomic Orbital overlap matrix + + // The Overlap matrix can be added simply when it is needed + const std::unique_ptr S_AO; + const std::unique_ptr complex_orbital_energies; + /// Counter poise flag + bool counter_poise = false; + /// Calculate all couplings + bool calculate_all = false; + }; + + private: + + Parameters * params_; + + public: + + TransferComplex(Parameters * params) : params_(params) {}; + + void unscramble(AtomSystem atm_sys); + + // Orbital type and a map of the corresponding number + // E.g. + // orbital type orbital number + // "mon1" "LUMO" "mon1" -3 + // "mon2" "HOMO" "mon2" 0 + // + // monomer1 LUMO-3 + // monomer2 HOMO + void calcJ(); + + /** + * \brief Print the transfer integral specified + **/ +// void printTransferIntegral( + // const std::map & orbital_type, + // const std::map & orbnum) const; + + /** + * \brief Print All info in matrix form + **/ + // void printAll() const; + +}; + +} // namespace catnip +#endif // _CATNIP_TRANSFER_COMPLEX_HPP diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 0b88df6..7ba98ce 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1,40 +1,34 @@ list( APPEND UNIT_TEST_SOURCE_FILES - test_argumentdouble - test_argumentfile - test_argumentint - test_argumentparser - test_argumentstring - test_argumentswitch + test_atom + test_atom_group + test_atom_group_container + test_atom_system + test_basis_map + test_elements test_log - test_matrix test_parameters - test_propertydouble - test_propertyfileexist - test_propertyfileext - test_propertyint - test_propertysisterfile - test_propertystringchoice - test_propertystring - test_propertyswitch - test_qc_functions - test_string_support) - -if(CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - link_libraries(gcov) -endif(CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - -if(ENABLE_TESTS) + +# test_qc_functions + test_string_support + test_swap_engine +) + +if(${CODE_COVERAGE} AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + find_library (GCOV gcov) +endif(${CODE_COVERAGE} AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + +if(${ENABLE_UNIT_TESTING}) foreach(PROG IN LISTS UNIT_TEST_SOURCE_FILES) add_executable(unit_${PROG} ${PROG}.cpp) if(CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") set_source_files_properties( ${PROG}.cpp PROPERTIES COMPILE_FLAGS ${COVERAGE_FLAGS} ) endif(CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - target_link_libraries(unit_${PROG} libcatnip) - add_test(unit_${PROG} unit_${PROG}) + target_link_libraries(unit_${PROG} libcatnip Catch2::Catch2) + ParseAndAddCatchTests(unit_${PROG}) endforeach(PROG) -endif(ENABLE_TESTS) +endif(${ENABLE_UNIT_TESTING}) -if(ENABLE_INTEGRATION_TESTS) +if(${ENABLE_INTEGRATION_TESTING}) foreach(PROG test_logreader @@ -45,7 +39,7 @@ if(ENABLE_INTEGRATION_TESTS) set_source_files_properties( ${PROG}.cpp PROPERTIES COMPILE_FLAGS ${COVERAGE_FLAGS}) endif(CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - target_link_libraries(integration${PROG} libcatnip) + target_link_libraries(integration${PROG} libcatnip Catch2::Catch2) add_test(integration${PROG} integration${PROG}) endforeach(PROG) @@ -54,21 +48,24 @@ if(ENABLE_INTEGRATION_TESTS) if(CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") set_source_files_properties( test_io.cpp PROPERTIES COMPILE_FLAGS ${COVERAGE_FLAGS}) endif(CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - target_link_libraries(test_io libcatnip) + target_link_libraries(test_io libcatnip mamap) add_test(regression_test_io test_io -p_P "${PROJECT_SOURCE_DIR}/GAUSSIANFILES/30/30_pair.pun" -p_1 "${PROJECT_SOURCE_DIR}/GAUSSIANFILES/30/ref.pun" -p_2 "${PROJECT_SOURCE_DIR}/GAUSSIANFILES/30/30_2.pun") add_custom_command(TARGET test_io POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_CURRENT_SOURCE_DIR}) + find_program (BASH_PROGRAM bash) if(BASH_PROGRAM) add_test(regression_test_io_script ${BASH_PROGRAM} ${PROJECT_SOURCE_DIR}/src/tests/test_script_io.sh ${CMAKE_CURRENT_SOURCE_DIR}) - add_test(integration_test_calc_J_script ${BASH_PROGRAM} ${PROJECT_SOURCE_DIR}/src/tests/test_script_calc_J.sh ${CMAKE_SOURCE_DIR}) + add_test(integration_test_calc_J_script ${BASH_PROGRAM} ${catnip_SOURCE_DIR}/src/tests/test_script_calc_J.sh ${CMAKE_SOURCE_DIR}) + else() + message(STATUS "Unable to add integration tests, unable to find bash") endif(BASH_PROGRAM) -endif(ENABLE_INTEGRATION_TESTS) +endif(${ENABLE_INTEGRATION_TESTING}) diff --git a/src/tests/test_argumentdouble.cpp b/src/tests/test_argumentdouble.cpp deleted file mode 100644 index 51d64c2..0000000 --- a/src/tests/test_argumentdouble.cpp +++ /dev/null @@ -1,91 +0,0 @@ - -#include "../libcatnip/io/arguments/argumentdouble.hpp" -#include -#include - -using namespace catnip; -using namespace std; - -int main(void) { - - cerr << "Testing: argumentdouble" << endl; - cerr << "Testing: constructor" << endl; - { ArgumentDouble argDouble; } - - cerr << "Testing: getArgumentName" << endl; - { - ArgumentDouble argDouble; - string name = "ARGUMENT_DOUBLE"; - assert(name.compare(argDouble.getArgumentName()) == 0); - } - - cerr << "Testing: getProperties" << endl; - { - ArgumentDouble argDouble; - auto props = argDouble.getProperties(); - - bool double_prop = false; - - for (auto prop : props) { - if (prop.compare("PROPERTY_DOUBLE") == 0) { - double_prop = true; - } - } - assert(double_prop); - } - - cerr << "Testing: getPropertyOptions" << endl; - { - ArgumentDouble argDouble; - auto prop_opts = argDouble.getPropertyOptions(); - - bool opt_min = false; - bool opt_max = false; - - for (auto opt : prop_opts) { - if (opt.compare("MIN") == 0) { - opt_min = true; - } - if (opt.compare("MAX") == 0) { - opt_max = true; - } - } - - assert(opt_min); - assert(opt_max); - } - - cerr << "Testing: getArgPropertyValues" << endl; - { - ArgumentDouble argDouble; - auto prop_values = argDouble.getPropertyValues(); - - bool opt_min = false; - bool opt_max = false; - bool opt_min_val = false; - bool opt_max_val = false; - - for (auto val : prop_values) { - if (val.first.compare("MIN") == 0) { - opt_min = true; - if (val.second.compare(to_string(numeric_limits::lowest())) == - 0) { - opt_min_val = true; - } - } - if (val.first.compare("MAX") == 0) { - opt_max = true; - if (val.second.compare(to_string(numeric_limits::max())) == 0) { - opt_max_val = true; - } - } - } - - assert(opt_min); - assert(opt_max); - assert(opt_min_val); - assert(opt_max_val); - } - - return 0; -} diff --git a/src/tests/test_argumentfile.cpp b/src/tests/test_argumentfile.cpp deleted file mode 100644 index 53e9484..0000000 --- a/src/tests/test_argumentfile.cpp +++ /dev/null @@ -1,163 +0,0 @@ - -#include "../libcatnip/io/arguments/argumentfile.hpp" -#include - -using namespace catnip; -using namespace std; - -int main(void) { - - cerr << "Testing: argumentfile" << endl; - cerr << "Testing: constructor" << endl; - { ArgumentFile argFile; } - - cerr << "Testing: getArgumentName" << endl; - { - ArgumentFile argFile; - string name = "ARGUMENT_FILE"; - assert(name.compare(argFile.getArgumentName()) == 0); - } - - cerr << "Testing: getProperties" << endl; - { - ArgumentFile argFile; - auto props = argFile.getProperties(); - - bool file_exist = false; - bool file_ext = false; - bool sister_file = false; - - for (auto prop : props) { - if (prop.compare("PROPERTY_FILE_EXIST") == 0) { - file_exist = true; - } - if (prop.compare("PROPERTY_FILE_EXT") == 0) { - file_ext = true; - } - if (prop.compare("PROPERTY_SISTER_FILE") == 0) { - sister_file = true; - } - } - assert(file_exist); - assert(file_ext); - assert(sister_file); - } - - cerr << "Testing: getPropertyOptions" << endl; - { - ArgumentFile argFile; - auto prop_opts = argFile.getPropertyOptions(); - - bool file_must_exist = false; - bool sis_file_name = false; - bool sis_file_path = false; - bool sis_file_path_name = false; - bool sis_file_exists = false; - bool allowed_ext = false; - bool allowed_sister_ext = false; - for (auto opt : prop_opts) { - if (opt.compare("ALLOWED_FILE_EXT") == 0) { - allowed_ext = true; - } - if (opt.compare("ALLOWED_SISTER_FILE_EXT") == 0) { - allowed_sister_ext = true; - } - if (opt.compare("FILE_MUST_EXIST") == 0) { - file_must_exist = true; - } - if (opt.compare("SISTER_FILE_NAME") == 0) { - sis_file_name = true; - } - if (opt.compare("SISTER_FILE_PATH") == 0) { - sis_file_path = true; - } - if (opt.compare("SISTER_FILE_PATH_NAME") == 0) { - sis_file_path_name = true; - } - if (opt.compare("SISTER_FILE_EXISTS") == 0) { - sis_file_exists = true; - } - } - - assert(file_must_exist); - assert(allowed_ext); - assert(allowed_sister_ext); - assert(sis_file_name); - assert(sis_file_path); - assert(sis_file_path_name); - assert(sis_file_exists); - } - - cerr << "Testing: getArgPropertyValues" << endl; - { - ArgumentFile argFile; - auto prop_values = argFile.getPropertyValues(); - - bool file_must_exist = false; - bool allowed_ext = false; - bool file_must_exist_val = false; - bool allowed_ext_val = false; - - for (auto val : prop_values) { - if (val.first.compare("ALLOWED_FILE_EXT") == 0) { - allowed_ext = true; - if (val.second[0] == '*') { - allowed_ext_val = true; - } - } - if (val.first.compare("FILE_MUST_EXIST") == 0) { - file_must_exist = true; - if (val.second.compare("0") == 0) { - file_must_exist_val = true; - } - } - } - - assert(file_must_exist); - assert(file_must_exist_val); - - assert(allowed_ext); - assert(allowed_ext_val); - } - - cerr << "Testing: setArgPropertyValues" << endl; - { - ArgumentFile argFile; - auto prop_values = argFile.getPropertyValues(); - - bool file_must_exist = false; - bool allowed_ext = false; - bool file_must_exist_val = false; - bool allowed_ext_val = false; - - for (auto val : prop_values) { - if (val.first.compare("ALLOWED_FILE_EXT") == 0) { - allowed_ext = true; - if (val.second[0] == '*') { - allowed_ext_val = true; - } - } - if (val.first.compare("FILE_MUST_EXIST") == 0) { - file_must_exist = true; - if (val.second.compare("0") == 0) { - file_must_exist_val = true; - } - } - } - - assert(file_must_exist); - assert(file_must_exist_val); - - assert(allowed_ext); - assert(allowed_ext_val); - - set exts{".pun", ".7", ".orb"}; - argFile.setArgPropertyOpt("PROPERTY_FILE_EXT", "ALLOWED_FILE_EXT", exts); - - auto str_exts = - argFile.getPropertyValues("PROPERTY_FILE_EXT", "ALLOWED_FILE_EXT"); - cerr << "extensions " << str_exts << endl; - } - - return 0; -} diff --git a/src/tests/test_argumentint.cpp b/src/tests/test_argumentint.cpp deleted file mode 100644 index c059c3b..0000000 --- a/src/tests/test_argumentint.cpp +++ /dev/null @@ -1,90 +0,0 @@ - -#include "../libcatnip/io/arguments/argumentint.hpp" -#include -#include - -using namespace catnip; -using namespace std; - -int main(void) { - - cerr << "Testing: argumentint" << endl; - cerr << "Testing: constructor" << endl; - { ArgumentInt argInt; } - - cerr << "Testing: getArgumentName" << endl; - { - ArgumentInt argInt; - string name = "ARGUMENT_INT"; - assert(name.compare(argInt.getArgumentName()) == 0); - } - - cerr << "Testing: getProperties" << endl; - { - ArgumentInt argInt; - auto props = argInt.getProperties(); - - bool int_prop = false; - - for (auto prop : props) { - if (prop.compare("PROPERTY_INT") == 0) { - int_prop = true; - } - } - assert(int_prop); - } - - cerr << "Testing: getPropertyOptions" << endl; - { - ArgumentInt argInt; - auto prop_opts = argInt.getPropertyOptions(); - - bool opt_min = false; - bool opt_max = false; - - for (auto opt : prop_opts) { - if (opt.compare("MIN") == 0) { - opt_min = true; - } - if (opt.compare("MAX") == 0) { - opt_max = true; - } - } - - assert(opt_min); - assert(opt_max); - } - - cerr << "Testing: getArgPropertyValues" << endl; - { - ArgumentInt argInt; - auto prop_values = argInt.getPropertyValues(); - - bool opt_min = false; - bool opt_max = false; - bool opt_min_val = false; - bool opt_max_val = false; - - for (auto val : prop_values) { - if (val.first.compare("MIN") == 0) { - opt_min = true; - if (val.second.compare(to_string(numeric_limits::min())) == 0) { - opt_min_val = true; - } - } - if (val.first.compare("MAX") == 0) { - opt_max = true; - if (val.second.compare(to_string(numeric_limits::max())) == 0) { - opt_max_val = true; - } - } - } - - assert(opt_min); - assert(opt_max); - assert(opt_min_val); - assert(opt_max_val); - } - - return 0; -} diff --git a/src/tests/test_argumentparser.cpp b/src/tests/test_argumentparser.cpp deleted file mode 100644 index 5cbac64..0000000 --- a/src/tests/test_argumentparser.cpp +++ /dev/null @@ -1,194 +0,0 @@ - - -#include "../libcatnip/io/argumentparser.hpp" -#include "../libcatnip/matrix.hpp" -#include "../libcatnip/string_support.hpp" -#include -#include -#include -#include - -using namespace catnip; -using namespace std; - -int main(void) { - - cerr << "Testing: ArgumentParser" << endl; - cerr << "Testing: constructor" << endl; - { - vector flag = { - "-p_P", "--punfile-pair", - "File containing dimer of two " - "monomers. This file should have the .pun extension."}; - set> flags; - flags.insert(flag); - ArgumentParser ArgPars(flags); - } - - cerr << "Testing: showUsage" << endl; - { - vector flag1 = { - "-p_P", "--punfile-pair", - "File containing dimer of two " - "monomers. This file should have the .pun extension."}; - vector flag2 = {"-p_1", "--punfile-mon1", - "File containing monomer 1"}; - vector flag3 = {"-homo", "--homo-level", "HOMO molecular orbital"}; - - set> flags; - flags.insert(flag1); - flags.insert(flag2); - flags.insert(flag3); - - ArgumentParser ArgPars(flags); - ArgPars.showUsage(); - } - - cerr << "Testing: setFlagArgOpt" << endl; - { - vector flag1 = { - "-p_P", "--punfile-pair", - "File containing dimer of two " - "monomers. This file should have the .pun extension."}; - vector flag2 = {"-p_1", "--punfile-mon1", - "File containing monomer 1"}; - vector flag3 = {"-homo", "--homo-level", "HOMO molecular orbital"}; - - set> flags; - flags.insert(flag1); - flags.insert(flag2); - flags.insert(flag3); - - ArgumentParser ArgPars(flags); - - string val = ".pun"; - ArgPars.setFlagArgOpt("--punfile-pair", "ARGUMENT_FILE", - "PROPERTY_FILE_EXT", "ALLOWED_FILE_EXT", val); - string val2 = ".7"; - ArgPars.setFlagArgOpt("--punfile-pair", "ARGUMENT_FILE", - "PROPERTY_FILE_EXT", "ALLOWED_FILE_EXT", val2); - string val3 = ".orb"; - ArgPars.setFlagArgOpt("--punfile-pair", "ARGUMENT_FILE", - "PROPERTY_FILE_EXT", "ALLOWED_FILE_EXT", val3); - } - - cerr << "Testing: parse" << endl; - { - vector flag1 = { - "-p_P", "--punfile-pair", - "File containing dimer of two " - "monomers. This file should have the .pun extension."}; - vector flag2 = {"-p_1", "--punfile-mon1", - "File containing monomer 1"}; - vector flag3 = {"-homo", "--homo-level", "HOMO molecular orbital"}; - - set> flags; - flags.insert(flag1); - flags.insert(flag2); - flags.insert(flag3); - - ArgumentParser ArgPars(flags); - - string val = ".pun"; - string val2 = ".7"; - string val3 = ".orb"; - set exts = {val, val2, val3}; - ArgPars.setFlagArgOpt("--punfile-pair", "ARGUMENT_FILE", - "PROPERTY_FILE_EXT", "ALLOWED_FILE_EXT", exts); - ArgPars.setFlagArgOpt("--punfile-mon1", "ARGUMENT_FILE", - "PROPERTY_FILE_EXT", "ALLOWED_FILE_EXT", exts); - ArgPars.setFlagArgOpt("--punfile-mon2", "ARGUMENT_FILE", - "PROPERTY_FILE_EXT", "ALLOWED_FILE_EXT", exts); - - ArgPars.setFlagArgOpt("--punfile-pair", "ARGUMENT_FILE", - "PROPERTY_FILE_EXIST", "FILE_MUST_EXIST", true); - ArgPars.setFlagArgOpt("--punfile-mon1", "ARGUMENT_FILE", - "PROPERTY_FILE_EXIST", "FILE_MUST_EXIST", false); - ArgPars.setFlagArgOpt("--punfile-mon2", "ARGUMENT_FILE", - "PROPERTY_FILE_EXIST", "FILE_MUST_EXIST", true); - - int argc = 7; - const char* argv[7]; // = {"calc_J","--punfile-pair", "testfile.pun", - // "--punfile-mon1","file.orb"}; - argv[0] = "calc_J"; - argv[1] = "--punfile-pair"; - argv[2] = "testfile.pun"; - argv[3] = "--punfile-mon1"; - argv[4] = "file.orb"; - argv[5] = "--punfile-mon2"; - argv[6] = "testfile.pun"; - ArgPars.parse(argv, argc); - - argc = 7; - const char* argv2[7]; - argv2[0] = "calc_J"; - argv2[1] = "--punfile-pair"; - argv2[2] = "testfile.pun"; - argv2[3] = "--punfile-mon1"; - argv2[4] = "file.orb"; - argv2[5] = "--punfile-mon2"; - argv2[6] = "fort.7"; - - bool excep = false; - try { - ArgPars.parse(argv2, argc); - } catch (...) { - excep = true; - } - assert(excep); - cout << "Except thrown: " << excep << endl; - } - - cerr << "Testing: get" << endl; - { - vector flag1 = { - "-p_P", "--punfile-pair", - "File containing dimer of two " - "monomers. This file should have the .pun extension."}; - vector flag2 = {"-p_1", "--punfile-mon1", - "File containing monomer 1"}; - vector flag3 = {"-homo", "--homo-level", "HOMO molecular orbital"}; - - set> flags; - flags.insert(flag1); - flags.insert(flag2); - flags.insert(flag3); - - ArgumentParser ArgPars(flags); - - string val = ".pun"; - string val2 = ".7"; - string val3 = ".orb"; - set exts = {val, val2, val3}; - ArgPars.setFlagArgOpt("--punfile-pair", "ARGUMENT_FILE", - "PROPERTY_FILE_EXT", "ALLOWED_FILE_EXT", exts); - ArgPars.setFlagArgOpt("--punfile-mon1", "ARGUMENT_FILE", - "PROPERTY_FILE_EXT", "ALLOWED_FILE_EXT", exts); - vector sis_exts{".log"}; - ArgPars.setFlagArgOpt("--punfile-mon1", "ARGUMENT_FILE", - "PROPERTY_SISTER_FILE", "ALLOWED_SISTER_FILE_EXT", - ".log"); - - const int argc = 5; - const char* argv[argc]; - argv[0] = "calc_J"; - argv[1] = "--punfile-pair"; - argv[2] = "file.orb"; - argv[3] = "--punfile-mon1"; - argv[4] = "testfile.pun"; - ArgPars.parse(argv, argc); - - string fileName = ArgPars.getStr("--punfile-pair"); - assert(fileName.compare("file.orb") == 0); - string fileName2 = ArgPars.getStr("--punfile-mon1"); - assert(fileName2.compare("testfile.pun") == 0); - string sisFileNamePath = ArgPars.getFlagArgOptValue( - "--punfile-mon1", "ARGUMENT_FILE", "PROPERTY_SISTER_FILE", - "SISTER_FILE_PATH_NAME"); - - cerr << "File name " << sisFileNamePath << endl; - assert(sisFileNamePath.compare("testfile.log") == 0); - } - - return 0; -} diff --git a/src/tests/test_argumentstring.cpp b/src/tests/test_argumentstring.cpp deleted file mode 100644 index 66e93e3..0000000 --- a/src/tests/test_argumentstring.cpp +++ /dev/null @@ -1,126 +0,0 @@ - -#include "../libcatnip/io/arguments/argumentstring.hpp" -#include -#include - -using namespace catnip; -using namespace std; - -int main(void) { - - cerr << "Testing: argumentstring" << endl; - cerr << "Testing: constructor" << endl; - { ArgumentString argString; } - - cerr << "Testing: getArgumentName" << endl; - { - ArgumentString argString; - string name = "ARGUMENT_STRING"; - assert(name.compare(argString.getArgumentName()) == 0); - } - - cerr << "Testing: getProperties" << endl; - { - ArgumentString argString; - auto props = argString.getProperties(); - - bool string_prop = false; - bool string_choice = false; - - for (auto prop : props) { - if (prop.compare("PROPERTY_STRING") == 0) { - string_prop = true; - } - if (prop.compare("PROPERTY_STRING_CHOICE") == 0) { - string_choice = true; - } - } - assert(string_prop); - assert(string_choice); - } - - cerr << "Testing: getPropertyOptions" << endl; - { - ArgumentString argString; - auto prop_opts = argString.getPropertyOptions(); - - bool opt_min = false; - bool opt_max = false; - bool opt_enforced = false; - bool opt_choices = false; - - for (auto opt : prop_opts) { - if (opt.compare("MIN_LENGTH") == 0) { - opt_min = true; - } - if (opt.compare("MAX_LENGTH") == 0) { - opt_max = true; - } - if (opt.compare("STRING_CHOICE_ENFORCED") == 0) { - opt_enforced = true; - } - if (opt.compare("STRING_CHOICES") == 0) { - opt_choices = true; - } - } - - assert(opt_min); - assert(opt_max); - assert(opt_enforced); - assert(opt_choices); - } - - cerr << "Testing: getArgPropertyValues" << endl; - { - ArgumentString argString; - auto prop_values = argString.getPropertyValues(); - - bool opt_min = false; - bool opt_max = false; - bool opt_enforced = false; - bool opt_choices = false; - - bool opt_min_val = false; - bool opt_max_val = false; - bool opt_enforced_val = false; - bool opt_choices_val = false; - - for (auto val : prop_values) { - if (val.first.compare("MIN_LENGTH") == 0) { - opt_min = true; - if (val.second.compare(to_string(0)) == 0) { - opt_min_val = true; - } - } - if (val.first.compare("MAX_LENGTH") == 0) { - opt_max = true; - if (val.second.compare(to_string((size_t)-1)) == 0) { - opt_max_val = true; - } - } - if (val.first.compare("STRING_CHOICE_ENFORCED") == 0) { - opt_enforced = true; - if (val.second.compare("false") == 0) { - opt_enforced_val = true; - } - } - if (val.first.compare("STRING_CHOICES") == 0) { - opt_choices = true; - if (val.second.compare("NOT_DEFINED") == 0) { - opt_choices_val = true; - } - } - } - - assert(opt_min); - assert(opt_max); - assert(opt_min_val); - assert(opt_max_val); - assert(opt_enforced); - assert(opt_choices); - assert(opt_enforced_val); - assert(opt_choices_val); - } - - return 0; -} diff --git a/src/tests/test_argumentswitch.cpp b/src/tests/test_argumentswitch.cpp deleted file mode 100644 index 943c16c..0000000 --- a/src/tests/test_argumentswitch.cpp +++ /dev/null @@ -1,75 +0,0 @@ - -#include "../libcatnip/io/arguments/argumentswitch.hpp" -#include -#include - -using namespace catnip; -using namespace std; - -int main(void) { - - cerr << "Testing: argumentswitch" << endl; - cerr << "Testing: constructor" << endl; - { ArgumentSwitch argSwitch; } - - cerr << "Testing: getArgumentName" << endl; - { - ArgumentSwitch argSwitch; - string name = "ARGUMENT_SWITCH"; - assert(name.compare(argSwitch.getArgumentName()) == 0); - } - - cerr << "Testing: getProperties" << endl; - { - ArgumentSwitch argSwitch; - auto props = argSwitch.getProperties(); - - bool int_prop = false; - - for (auto prop : props) { - if (prop.compare("PROPERTY_SWITCH") == 0) { - int_prop = true; - } - } - assert(int_prop); - } - - cerr << "Testing: getPropertyOptions" << endl; - { - ArgumentSwitch argSwitch; - auto prop_opts = argSwitch.getPropertyOptions(); - - bool opt_def = false; - - for (auto opt : prop_opts) { - if (opt.compare("DEFAULT") == 0) { - opt_def = true; - } - } - - assert(opt_def); - } - - cerr << "Testing: getArgPropertyValues" << endl; - { - ArgumentSwitch argSwitch; - auto prop_values = argSwitch.getPropertyValues(); - - bool opt_def = false; - bool opt_def_val = false; - - for (auto val : prop_values) { - if (val.first.compare("DEFAULT") == 0) { - opt_def = true; - if (val.second.compare("OFF") == 0) { - opt_def_val = true; - } - } - } - - assert(opt_def); - assert(opt_def_val); - } - - return 0; -} diff --git a/src/tests/test_atom.cpp b/src/tests/test_atom.cpp new file mode 100644 index 0000000..7c4c88b --- /dev/null +++ b/src/tests/test_atom.cpp @@ -0,0 +1,23 @@ + +#define CATCH_CONFIG_MAIN +#include + +// Local private includes +#include "../libcatnip/atom.hpp" + +#include "../libcatnip/elements.hpp" + +using namespace catnip; + +TEST_CASE("Elements","[unit]") { + + Elements elements; + Element H = elements.getElement("H"); + + Atom atom(H,0.0,0.0,0.0); + Atom atom2(H,1.0,0.0,0.0); + + REQUIRE( atom != atom2); + REQUIRE( atom == atom); + REQUIRE( atom2 == atom2); +} diff --git a/src/tests/test_atom_group.cpp b/src/tests/test_atom_group.cpp new file mode 100644 index 0000000..34de2e4 --- /dev/null +++ b/src/tests/test_atom_group.cpp @@ -0,0 +1,56 @@ + +#define CATCH_CONFIG_MAIN +#include + +// Local private includes +#include "atom_group.hpp" + +#include "atom.hpp" +#include "elements.hpp" + +// Standard includes +#include + +using namespace catnip; + +TEST_CASE("Atom Group","[unit]") { + + AtomGroup atom_grp("CH2"); + + REQUIRE(atom_grp.getType() == GroupType::Unassigned ); + REQUIRE(atom_grp.getName() == "CH2"); + + Atom atom1(Element::H, 0.0, 0.0, 0.0); + Atom atom2(Element::H, 2.0, 0.0, 0.0); + Atom atom3(Element::C, 1.0, 1.0, 0.0); + // Same atom different memory location + Atom atom4(Element::H, 0.0, 0.0, 0.0); + + auto atom1_ptr = std::make_shared(atom1); + auto atom2_ptr = std::make_shared(atom2); + auto atom3_ptr = std::make_shared(atom3); + auto atom4_ptr = std::make_shared(atom4); + + atom_grp.add(atom1_ptr); + atom_grp.add(atom2_ptr); + atom_grp.add(atom3_ptr); + + REQUIRE(atom_grp.size() == 3); + + REQUIRE(atom_grp.find(atom1_ptr).size() == 1); + REQUIRE(atom_grp.find(atom2_ptr).size() == 1); + REQUIRE(atom_grp.find(atom3_ptr).size() == 1); + + REQUIRE(atom_grp.find(atom1_ptr).at(0) == 0); + REQUIRE(atom_grp.find(atom2_ptr).at(0) == 1); + REQUIRE(atom_grp.find(atom3_ptr).at(0) == 2); + + atom_grp.add(atom4_ptr); + REQUIRE(atom_grp.find(atom1_ptr).size() == 2); + REQUIRE(atom_grp.find(atom1_ptr).at(0) == 0); + REQUIRE(atom_grp.find(atom1_ptr).at(1) == 3); + + REQUIRE(atom_grp.findStrict(atom4_ptr).size() == 1); + REQUIRE(atom_grp.findStrict(atom4_ptr).at(0) == 3); + +} diff --git a/src/tests/test_atom_group_container.cpp b/src/tests/test_atom_group_container.cpp new file mode 100644 index 0000000..62fd0f6 --- /dev/null +++ b/src/tests/test_atom_group_container.cpp @@ -0,0 +1,83 @@ + +#define CATCH_CONFIG_MAIN +#include + +// Local private includes +#include "atom_group_container.hpp" + +#include "atom.hpp" +#include "atom_group.hpp" +#include "elements.hpp" + +// Standard includes +#include + +using namespace catnip; + +TEST_CASE("Atom Group Container","[unit]") { + + Atom atom1(Element::H, 0.0, 0.0, 0.0); + Atom atom2(Element::H, 2.0, 0.0, 0.0); + Atom atom3(Element::C, 1.0, 1.0, 0.0); + + auto atom1_ptr = std::make_shared(atom1); + auto atom2_ptr = std::make_shared(atom2); + auto atom3_ptr = std::make_shared(atom3); + + auto atom_grp1 = std::make_unique("CH2"); + atom_grp1->add(atom1_ptr); + atom_grp1->add(atom2_ptr); + atom_grp1->add(atom3_ptr); + + Atom atom4(Element::O, 3.3, 4.3, 0.0); + Atom atom5(Element::O, 3.0, 3.9, 0.0); + + auto atom4_ptr = std::make_shared(atom4); + auto atom5_ptr = std::make_shared(atom5); + + auto atom_grp2 = std::make_unique("O2"); + atom_grp2->add(atom4_ptr); + atom_grp2->add(atom5_ptr); + + AtomGroupContainer atom_grp_cont; + + atom_grp_cont.add(std::move(atom_grp1)); + atom_grp_cont.add(std::move(atom_grp2)); + + REQUIRE(atom_grp_cont.size() == 2); + + REQUIRE(atom_grp_cont.getType(0) == GroupType::Unassigned); + REQUIRE(atom_grp_cont.getType(1) == GroupType::Unassigned); + REQUIRE(atom_grp_cont.isUpToDate() == false); + + atom_grp_cont.assignGroupTypes(); + REQUIRE(atom_grp_cont.isUpToDate() == true); + + // These should be changed + REQUIRE(atom_grp_cont.getType(0) == GroupType::Island); + REQUIRE(atom_grp_cont.getType(1) == GroupType::Island); + REQUIRE(atom_grp_cont.exists(GroupType::Island)); + + // Now we make a third group that has all the atoms of the first two groups + auto atom_grp3 = std::make_unique("O2CH2"); + atom_grp3->add(std::move(atom1_ptr)); + atom_grp3->add(atom2_ptr); + atom_grp3->add(atom3_ptr); + atom_grp3->add(atom4_ptr); + atom_grp3->add(atom5_ptr); + + atom_grp_cont.add(std::move(atom_grp3)); + REQUIRE(atom_grp_cont.isUpToDate() == false); + + REQUIRE(atom_grp_cont.getType(2) == GroupType::Unassigned); + REQUIRE(atom_grp_cont.exists(GroupType::Unassigned)); + + atom_grp_cont.assignGroupTypes(); + REQUIRE(atom_grp_cont.isUpToDate() == true); + REQUIRE(atom_grp_cont.getType(0) == GroupType::Component); + REQUIRE(atom_grp_cont.getType(1) == GroupType::Component); + REQUIRE(atom_grp_cont.getType(2) == GroupType::Complex); + + REQUIRE(atom_grp_cont.exists(GroupType::Complex)); + REQUIRE(atom_grp_cont.exists(GroupType::Component)); +} diff --git a/src/tests/test_atom_system.cpp b/src/tests/test_atom_system.cpp new file mode 100644 index 0000000..8acb3f8 --- /dev/null +++ b/src/tests/test_atom_system.cpp @@ -0,0 +1,234 @@ + +#define CATCH_CONFIG_MAIN +#include + +// Local private includes +#include "atom_system.hpp" + +#include "atom.hpp" +#include "atom_group.hpp" +#include "atom_group_container.hpp" +#include "elements.hpp" + +// Standard includes +#include + +using namespace catnip; + +TEST_CASE("Atom System","[unit]") { + + Atom atom1(Element::H, 0.0, 0.0, 0.0); + Atom atom2(Element::H, 2.0, 0.0, 0.0); + Atom atom3(Element::C, 1.0, 1.0, 0.0); + Atom atom4(Element::O, 3.3, 4.3, 0.0); + Atom atom5(Element::O, 3.0, 3.9, 0.0); + // Same position as atom5 but different element + Atom atom6(Element::C, 3.0, 3.9, 0.0); + + auto atom1_ptr = std::make_shared(atom1); + auto atom2_ptr = std::make_shared(atom2); + auto atom3_ptr = std::make_shared(atom3); + auto atom4_ptr = std::make_shared(atom4); + auto atom5_ptr = std::make_shared(atom5); + auto atom6_ptr = std::make_shared(atom6); + + SECTION("Building component without atom 5") { + // Extra atoms are allowed in the complex but not in the componets + auto component1 = std::make_unique("CH2"); + component1->add(atom1_ptr); + component1->add(atom2_ptr); + component1->add(atom3_ptr); + + auto component2 = std::make_unique("O2"); + component2->add(atom4_ptr); + + auto complex1 = std::make_unique("O2CH2"); + complex1->add(atom1_ptr); + complex1->add(atom2_ptr); + complex1->add(atom3_ptr); + complex1->add(atom4_ptr); + complex1->add(atom5_ptr); + + auto atom_grp_cont = std::unique_ptr(new AtomGroupContainer); + atom_grp_cont->add(std::move(component1)); + atom_grp_cont->add(std::move(component2)); + atom_grp_cont->add(std::move(complex1)); + + REQUIRE_NOTHROW(AtomSystem(std::move(atom_grp_cont)) ); + } + + SECTION("Building complex without atom 5") { + // Extra atoms are allowed in the complex but not in the componets + auto component1 = std::make_unique("CH2"); + component1->add(atom1_ptr); + component1->add(atom2_ptr); + component1->add(atom3_ptr); + + auto component2 = std::make_unique("O2"); + component2->add(atom4_ptr); + component2->add(atom5_ptr); + + auto complex1 = std::make_unique("O2CH2"); + complex1->add(atom1_ptr); + complex1->add(atom2_ptr); + complex1->add(atom3_ptr); + complex1->add(atom4_ptr); + + auto atom_grp_cont = std::unique_ptr(new AtomGroupContainer); + atom_grp_cont->add(std::move(component1)); + atom_grp_cont->add(std::move(component2)); + atom_grp_cont->add(std::move(complex1)); + + REQUIRE_THROWS(AtomSystem(std::move(atom_grp_cont)) ); + } + + SECTION("Building with atom 5") { + auto component1 = std::make_unique("CH2"); + component1->add(atom1_ptr); + component1->add(atom2_ptr); + component1->add(atom3_ptr); + + auto component2 = std::make_unique("O2"); + component2->add(atom4_ptr); + component2->add(atom5_ptr); + + auto complex1 = std::make_unique("O2CH2"); + complex1->add(atom1_ptr); + complex1->add(atom2_ptr); + complex1->add(atom3_ptr); + complex1->add(atom4_ptr); + complex1->add(atom5_ptr); // O + + auto atom_grp_cont = std::unique_ptr(new AtomGroupContainer); + atom_grp_cont->add(std::move(component1)); + atom_grp_cont->add(std::move(component2)); + atom_grp_cont->add(std::move(complex1)); + + AtomSystem atm_sys(std::move(atom_grp_cont)); + REQUIRE(atm_sys.getComplex()->getType() == GroupType::Complex ); + REQUIRE(atm_sys.getComplex()->getName() == "O2CH2" ); + + std::vector component_indices = atm_sys.getComponentIndices(); + REQUIRE(component_indices.size() == 2); + REQUIRE(component_indices.at(0) == 0); + REQUIRE(component_indices.at(1) == 1); + + std::vector linked_atms = atm_sys.getLinkedAtomsWithDifferentElements(); + REQUIRE(linked_atms.size() == 0); + + // Basis functions + std::vector basis_comp1{ 1, 1, 4}; + std::vector basis_comp2{ 5, 5}; + // should be 5, 5 at the end + std::vector wrong_basis_complex{ 1, 1, 4, 3, 3}; + + atm_sys.assignBasisFunctions( 0, basis_comp1 ); + atm_sys.assignBasisFunctions( 1, basis_comp2 ); + + // Should be complete at this point + REQUIRE( atm_sys.systemComplete() ); + + // By using the basis functions for the complex we ensure that basis + // functions between the components and the complex are consistent + REQUIRE_THROWS( atm_sys.assignBasisFunctions( 2, wrong_basis_complex )); + + std::vector basis_complex{ 1, 1, 4, 5, 5}; + REQUIRE_NOTHROW( atm_sys.assignBasisFunctions( 2, basis_complex )); + + REQUIRE( atm_sys.at(0)->size() == 3); + REQUIRE( atm_sys.at(0)->at(0)->getBasisFuncCount() == 1); // H + REQUIRE( atm_sys.at(0)->at(1)->getBasisFuncCount() == 1); // H + REQUIRE( atm_sys.at(0)->at(2)->getBasisFuncCount() == 4); // C + + REQUIRE( atm_sys.at(1)->size() == 2); + REQUIRE( atm_sys.at(1)->at(0)->getBasisFuncCount() == 5); // O + REQUIRE( atm_sys.at(1)->at(1)->getBasisFuncCount() == 5); // O + + REQUIRE( atm_sys.at(2)->size() == 5); + REQUIRE( atm_sys.at(2)->at(0)->getBasisFuncCount() == 1); // H + REQUIRE( atm_sys.at(2)->at(1)->getBasisFuncCount() == 1); // H + REQUIRE( atm_sys.at(2)->at(2)->getBasisFuncCount() == 4); // C + REQUIRE( atm_sys.at(2)->at(3)->getBasisFuncCount() == 5); // O + REQUIRE( atm_sys.at(2)->at(4)->getBasisFuncCount() == 5); // O + } + + SECTION("Building complex with atom 6") { + auto component1 = std::make_unique("CH2"); + component1->add(atom1_ptr); + component1->add(atom2_ptr); + component1->add(atom3_ptr); + + auto component2 = std::make_unique("O2"); + component2->add(atom4_ptr); + component2->add(atom5_ptr); + + auto complex1 = std::make_unique("OC2H2"); + complex1->add(atom1_ptr); + complex1->add(atom2_ptr); + complex1->add(atom3_ptr); + complex1->add(atom4_ptr); + complex1->add(atom6_ptr);// Carbon instead of Oxygen + + auto atom_grp_cont = std::unique_ptr(new AtomGroupContainer); + atom_grp_cont->add(std::move(component1)); + atom_grp_cont->add(std::move(component2)); + atom_grp_cont->add(std::move(complex1)); + + AtomSystem atm_sys(std::move(atom_grp_cont)); + REQUIRE(atm_sys.getComplex()->getType() == GroupType::Complex ); + REQUIRE(atm_sys.getComplex()->getName() == "OC2H2" ); + + std::vector component_indices = atm_sys.getComponentIndices(); + REQUIRE(component_indices.size() == 2); + REQUIRE(component_indices.at(0) == 0); + REQUIRE(component_indices.at(1) == 1); + + std::vector linked_atms = atm_sys.getLinkedAtomsWithDifferentElements(); + REQUIRE(linked_atms.size() == 1); + AtomSystem::Link link = linked_atms.at(0); + // atm5 from component 2 should be linked with atom 5 of complex + REQUIRE(link.component_name == "O2"); + REQUIRE(link.component_ind == 1); + REQUIRE(link.component_atm_ind == 1); + REQUIRE(link.complex_name == "OC2H2"); + REQUIRE(link.complex_ind == 2); + REQUIRE(link.complex_atm_ind == 4); + + // Basis functions + std::vector basis_comp1{ 1, 1, 4}; + std::vector basis_comp2{ 5, 5}; + // should be 5, 5 at the end + std::vector wrong_basis_complex{ 1, 1, 4, 3, 3}; + + atm_sys.assignBasisFunctions( 0, basis_comp1 ); + atm_sys.assignBasisFunctions( 1, basis_comp2 ); + + // Should NOT be complete at this point, as atom 5 and 6 though positionally + // linked are not in the same memory space + REQUIRE( atm_sys.systemComplete() == false ); + + // By using the basis functions for the complex we ensure that basis + // functions between the components and the complex are consistent + REQUIRE_THROWS( atm_sys.assignBasisFunctions( 2, wrong_basis_complex )); + + std::vector basis_complex{ 1, 1, 4, 5, 5}; + REQUIRE_NOTHROW( atm_sys.assignBasisFunctions( 2, basis_complex )); + REQUIRE( atm_sys.systemComplete() ); + + REQUIRE( atm_sys.at(0)->size() == 3); + REQUIRE( atm_sys.at(0)->at(0)->getBasisFuncCount() == 1); // H + REQUIRE( atm_sys.at(0)->at(1)->getBasisFuncCount() == 1); // H + REQUIRE( atm_sys.at(0)->at(2)->getBasisFuncCount() == 4); // C + + REQUIRE( atm_sys.at(1)->size() == 2); + REQUIRE( atm_sys.at(1)->at(0)->getBasisFuncCount() == 5); // O + REQUIRE( atm_sys.at(1)->at(1)->getBasisFuncCount() == 5); // O + + REQUIRE( atm_sys.at(2)->size() == 5); + REQUIRE( atm_sys.at(2)->at(0)->getBasisFuncCount() == 1); // H + REQUIRE( atm_sys.at(2)->at(1)->getBasisFuncCount() == 1); // H + REQUIRE( atm_sys.at(2)->at(2)->getBasisFuncCount() == 4); // C + REQUIRE( atm_sys.at(2)->at(3)->getBasisFuncCount() == 5); // O + REQUIRE( atm_sys.at(2)->at(4)->getBasisFuncCount() == 5); // O + } +} diff --git a/src/tests/test_basis_map.cpp b/src/tests/test_basis_map.cpp new file mode 100644 index 0000000..667c601 --- /dev/null +++ b/src/tests/test_basis_map.cpp @@ -0,0 +1,267 @@ + +#define CATCH_CONFIG_MAIN +#include + +// Local private includes +#include "basis_map.hpp" + +#include "atom.hpp" +#include "atom_group_container.hpp" +#include "atom_system.hpp" +#include "elements.hpp" + +using namespace catnip; + +TEST_CASE("Basis Map Unscrambled","[integration]") { + + Atom atom1(Element::H, 0.0, 0.0, 0.0); + Atom atom2(Element::H, 2.0, 0.0, 0.0); + Atom atom3(Element::C, 1.0, 1.0, 0.0); + Atom atom4(Element::O, 3.3, 4.3, 0.0); + Atom atom5(Element::O, 3.0, 3.9, 0.0); + + auto atom1_ptr = std::make_shared(atom1); + auto atom2_ptr = std::make_shared(atom2); + auto atom3_ptr = std::make_shared(atom3); + auto atom4_ptr = std::make_shared(atom4); + auto atom5_ptr = std::make_shared(atom5); + + // Extra atoms are allowed in the complex but not in the componets + auto component1 = std::make_unique("CH2"); + component1->add(atom1_ptr); + component1->add(atom2_ptr); + component1->add(atom3_ptr); + + auto component2 = std::make_unique("O2"); + component2->add(atom4_ptr); + component2->add(atom5_ptr); + + auto complex1 = std::make_unique("O2CH2"); + complex1->add(atom1_ptr); + complex1->add(atom2_ptr); + complex1->add(atom3_ptr); + complex1->add(atom4_ptr); + complex1->add(atom5_ptr); + + auto atom_grp_cont = std::unique_ptr(new AtomGroupContainer); + atom_grp_cont->add(std::move(component1)); + atom_grp_cont->add(std::move(component2)); + atom_grp_cont->add(std::move(complex1)); + + auto atm_sys = AtomSystem(std::move(atom_grp_cont)); + + std::vector basis_complex{ 1, 1, 4, 5, 5}; + + int index_complex = 2; + atm_sys.assignBasisFunctions( index_complex, basis_complex); + BasisMap basis_map(std::move(atm_sys)); + + // Equal to the total number of basis in the group + REQUIRE( basis_map.row_col_current[0].size() == 6); + // comp1 atm 1 should map to location 0 in the complex at least currentially + REQUIRE( basis_map.row_col_current[0].at(0) == 0); + // comp1 atm 2 should map to location 1 in the complex at least currentially + REQUIRE( basis_map.row_col_current[0].at(1) == 1); + // comp1 atm 3 should map to location 2-5 in the complex at least currentially + REQUIRE( basis_map.row_col_current[0].at(2) == 2); + REQUIRE( basis_map.row_col_current[0].at(3) == 3); + REQUIRE( basis_map.row_col_current[0].at(4) == 4); + REQUIRE( basis_map.row_col_current[0].at(5) == 5); + + REQUIRE( basis_map.row_col_current[1].size() == 10); + // comp2 atm 1 should map to location 4 in the complex at least currentially + REQUIRE( basis_map.row_col_current[1].at(0) == 6); + // comp2 atm 2 should map to location 5 in the complex at least currentially + REQUIRE( basis_map.row_col_current[1].at(1) == 7); + REQUIRE( basis_map.row_col_current[1].at(2) == 8); + REQUIRE( basis_map.row_col_current[1].at(3) == 9); + REQUIRE( basis_map.row_col_current[1].at(4) == 10); + REQUIRE( basis_map.row_col_current[1].at(5) == 11); + REQUIRE( basis_map.row_col_current[1].at(6) == 12); + REQUIRE( basis_map.row_col_current[1].at(7) == 13); + REQUIRE( basis_map.row_col_current[1].at(8) == 14); + REQUIRE( basis_map.row_col_current[1].at(9) == 15); + + // In this case the final and currential version should be the same + // Equal to the total number of basis in the group + REQUIRE( basis_map.row_col_final[0].size() == 6); + // comp1 atm 1 should map to location 0 in the complex at least finalially + REQUIRE( basis_map.row_col_final[0].at(0) == 0); + // comp1 atm 2 should map to location 1 in the complex at least finalially + REQUIRE( basis_map.row_col_final[0].at(1) == 1); + // comp1 atm 3 should map to location 2-5 in the complex at least finalially + REQUIRE( basis_map.row_col_final[0].at(2) == 2); + REQUIRE( basis_map.row_col_final[0].at(3) == 3); + REQUIRE( basis_map.row_col_final[0].at(4) == 4); + REQUIRE( basis_map.row_col_final[0].at(5) == 5); + + REQUIRE( basis_map.row_col_final[1].size() == 10); + // comp2 atm 1 should map to location 4 in the complex at least finalially + REQUIRE( basis_map.row_col_final[1].at(0) == 6); + // comp2 atm 2 should map to location 5 in the complex at least finalially + REQUIRE( basis_map.row_col_final[1].at(1) == 7); + REQUIRE( basis_map.row_col_final[1].at(2) == 8); + REQUIRE( basis_map.row_col_final[1].at(3) == 9); + REQUIRE( basis_map.row_col_final[1].at(4) == 10); + REQUIRE( basis_map.row_col_final[1].at(5) == 11); + REQUIRE( basis_map.row_col_final[1].at(6) == 12); + REQUIRE( basis_map.row_col_final[1].at(7) == 13); + REQUIRE( basis_map.row_col_final[1].at(8) == 14); + REQUIRE( basis_map.row_col_final[1].at(9) == 15); + + std::pair location = basis_map.findLocation(0); + REQUIRE( location.first == 0 ); + REQUIRE( location.second == 0 ); + location = basis_map.findLocation(1); + REQUIRE( location.first == 0 ); + REQUIRE( location.second == 1 ); + location = basis_map.findLocation(2); + REQUIRE( location.first == 0 ); + REQUIRE( location.second == 2 ); + + location = basis_map.findLocation(6); + REQUIRE( location.first == 1 ); + REQUIRE( location.second == 0 ); + location = basis_map.findLocation(7); + REQUIRE( location.first == 1 ); + REQUIRE( location.second == 1 ); + location = basis_map.findLocation(15); + REQUIRE( location.first == 1 ); + REQUIRE( location.second == 9 ); +} + + +/** + * @brief In this test some of the atoms added to the complex will be added + * in a different order from how they were added to each of the components + * + * @param Scrambled" + * @param "[integration]" + */ +TEST_CASE("Basis Map Scrambled","[integration]") { + + std::vector basis_comp1{ 1, 1, 4}; + std::vector basis_comp2{ 5, 5}; + + Atom atom1(Element::H, 0.0, 0.0, 0.0); + Atom atom2(Element::H, 2.0, 0.0, 0.0); + Atom atom3(Element::C, 1.0, 1.0, 0.0); + Atom atom4(Element::O, 3.3, 4.3, 0.0); + Atom atom5(Element::O, 3.0, 3.9, 0.0); + + auto atom1_ptr = std::make_shared(atom1); + auto atom2_ptr = std::make_shared(atom2); + auto atom3_ptr = std::make_shared(atom3); + auto atom4_ptr = std::make_shared(atom4); + auto atom5_ptr = std::make_shared(atom5); + + // Extra atoms are allowed in the complex but not in the componets + auto component1 = std::make_unique("CH2"); + component1->add(atom1_ptr); + component1->add(atom2_ptr); + component1->add(atom3_ptr); + + auto component2 = std::make_unique("O2"); + component2->add(atom4_ptr); + component2->add(atom5_ptr); + + // HERE: the order has been changed + auto complex1 = std::make_unique("O2CH2"); + complex1->add(atom4_ptr); // The basis functions of atom 4 : 0 - 4 + complex1->add(atom1_ptr); // The basis functiosn of atom 1 : 5 - 5 + complex1->add(atom3_ptr); // The basis functiosn of atom 3 : 6 - 9 + complex1->add(atom5_ptr); // The basis functiosn of atom 5 : 10 - 14 + complex1->add(atom2_ptr); // The basis functions of atom 2 : 15 - 15 + + auto atom_grp_cont = std::unique_ptr(new AtomGroupContainer); + atom_grp_cont->add(std::move(component1)); + atom_grp_cont->add(std::move(component2)); + atom_grp_cont->add(std::move(complex1)); + + AtomSystem atm_sys(std::move(atom_grp_cont)); + + int index_component1 = 0; + int index_component2 = 1; + atm_sys.assignBasisFunctions( index_component1, basis_comp1); + atm_sys.assignBasisFunctions( index_component2, basis_comp2); + + BasisMap basis_map(atm_sys); + + // The row_col_current will now be different but the row_col_final should remail + // the same + + // The basis functions of atom 4 : 0 - 4 + // The basis functiosn of atom 1 : 5 - 5 + // The basis functiosn of atom 3 : 6 - 9 + // The basis functiosn of atom 5 : 10 - 14 + // The basis functions of atom 2 : 15 - 15 + + // Equal to the total number of basis in the group + REQUIRE( basis_map.row_col_current[0].size() == 6); + REQUIRE( basis_map.row_col_current[0].at(0) == 5); // atom 1 + REQUIRE( basis_map.row_col_current[0].at(1) == 15); // atom 2 + REQUIRE( basis_map.row_col_current[0].at(2) == 6); // atom 3 + REQUIRE( basis_map.row_col_current[0].at(3) == 7); + REQUIRE( basis_map.row_col_current[0].at(4) == 8); + REQUIRE( basis_map.row_col_current[0].at(5) == 9); + + REQUIRE( basis_map.row_col_current[1].size() == 10); + REQUIRE( basis_map.row_col_current[1].at(0) == 0); // atom 4 + REQUIRE( basis_map.row_col_current[1].at(1) == 1); + REQUIRE( basis_map.row_col_current[1].at(2) == 2); + REQUIRE( basis_map.row_col_current[1].at(3) == 3); + REQUIRE( basis_map.row_col_current[1].at(4) == 4); + REQUIRE( basis_map.row_col_current[1].at(5) == 10); // atom 5 + REQUIRE( basis_map.row_col_current[1].at(6) == 11); + REQUIRE( basis_map.row_col_current[1].at(7) == 12); + REQUIRE( basis_map.row_col_current[1].at(8) == 13); + REQUIRE( basis_map.row_col_current[1].at(9) == 14); + + // In this case the final and currential version should be the same + // Equal to the total number of basis in the group + REQUIRE( basis_map.row_col_final[0].size() == 6); + // comp1 atm 1 should map to location 0 in the complex at least finalially + REQUIRE( basis_map.row_col_final[0].at(0) == 0); + // comp1 atm 2 should map to location 1 in the complex at least finalially + REQUIRE( basis_map.row_col_final[0].at(1) == 1); + // comp1 atm 3 should map to location 2-5 in the complex at least finalially + REQUIRE( basis_map.row_col_final[0].at(2) == 2); + REQUIRE( basis_map.row_col_final[0].at(3) == 3); + REQUIRE( basis_map.row_col_final[0].at(4) == 4); + REQUIRE( basis_map.row_col_final[0].at(5) == 5); + + REQUIRE( basis_map.row_col_final[1].size() == 10); + // comp2 atm 1 should map to location 4 in the complex at least finalially + REQUIRE( basis_map.row_col_final[1].at(0) == 6); + // comp2 atm 2 should map to location 5 in the complex at least finalially + REQUIRE( basis_map.row_col_final[1].at(1) == 7); + REQUIRE( basis_map.row_col_final[1].at(2) == 8); + REQUIRE( basis_map.row_col_final[1].at(3) == 9); + REQUIRE( basis_map.row_col_final[1].at(4) == 10); + REQUIRE( basis_map.row_col_final[1].at(5) == 11); + REQUIRE( basis_map.row_col_final[1].at(6) == 12); + REQUIRE( basis_map.row_col_final[1].at(7) == 13); + REQUIRE( basis_map.row_col_final[1].at(8) == 14); + REQUIRE( basis_map.row_col_final[1].at(9) == 15); + + // Look for where in the currential rows the row of the complex can be found + std::pair location = basis_map.findLocation(0); + REQUIRE( location.first == 1 ); + REQUIRE( location.second == 0 ); + location = basis_map.findLocation(1); + REQUIRE( location.first == 1 ); + REQUIRE( location.second == 1 ); + location = basis_map.findLocation(2); + REQUIRE( location.first == 1 ); + REQUIRE( location.second == 2 ); + + location = basis_map.findLocation(6); + REQUIRE( location.first == 0 ); + REQUIRE( location.second == 2 ); + location = basis_map.findLocation(7); + REQUIRE( location.first == 0 ); + REQUIRE( location.second == 3 ); + location = basis_map.findLocation(15); + REQUIRE( location.first == 0 ); + REQUIRE( location.second == 1 ); +} diff --git a/src/tests/test_elements.cpp b/src/tests/test_elements.cpp new file mode 100644 index 0000000..164e8dc --- /dev/null +++ b/src/tests/test_elements.cpp @@ -0,0 +1,20 @@ + +#define CATCH_CONFIG_MAIN +#include + +#include "elements.hpp" + +using namespace catnip; + +TEST_CASE("Elements","[unit]") { + + Elements elements; + Element elem = Element::H; + REQUIRE( elem == elements.getElement("H")); + REQUIRE( elements.getString(elem) == "H"); + REQUIRE( elem == elements.getElement("h")); + + Element unknown = Element::Unknown; + REQUIRE( unknown == elements.getElement("blah")); + REQUIRE( "Unknown" == elements.getString(unknown)); +} diff --git a/src/tests/test_io.cpp b/src/tests/test_io.cpp index b788dbd..59a2dd6 100644 --- a/src/tests/test_io.cpp +++ b/src/tests/test_io.cpp @@ -1,8 +1,9 @@ -#include "../libcatnip/io/argumentparser.hpp" -#include "../libcatnip/io/io.hpp" -#include "../libcatnip/matrix.hpp" +#include +#include "io/io.hpp" +#include "parameters.hpp" +#include "matrix.hpp" #include #include #include @@ -13,21 +14,23 @@ using namespace std; int main(int argc, const char* argv[]) { - auto ArgParse = prepareParser(); + auto arg_parser = prepareParser(); - ArgParse->parse(argv, argc); - vector flags{"--pun_P", "--pun_1", "--pun_2", - "--log_P", "--log_1", "--log_2"}; + arg_parser->parse(argv, argc); + + auto parameters = prepareParameters(std::move(arg_parser)) +/* for (auto flag : flags) { cout << endl; - string argu = "ARGUMENT_FILE"; - string prop = "PROPERTY_FILE_EXT"; - string opt = "ALLOWED_FILE_EXT"; - auto val = ArgParse->getFlagArgOptValue(flag, argu, prop, opt); - cout << flag << " " << argu << " " << prop << " " << opt << " " << val - << endl; - + ArgumentType argu = ArgumentType::FILES; + PropertyType prop = PropertyType::FILE_EXT; + Option opt = Option::ALLOWED_VALUES; + auto values = ArgParse->get(flag, argu, prop, opt); + for ( std::string & val : values ){ + cout << val << " "; + } + cout << endl; prop = "PROPERTY_SISTER_FILE"; opt = "ALLOWED_SISTER_FILE_EXT"; auto val1 = ArgParse->getFlagArgOptValue(flag, argu, prop, opt); @@ -59,7 +62,7 @@ int main(int argc, const char* argv[]) { opt = "FILE_DOES_EXIST"; auto val7 = ArgParse->getFlagArgOptValue(flag, argu, prop, opt); cout << flag << " " << argu << " " << prop << " " << opt << " " << val7 - << endl; + << endl;*/ } auto Par = prepareParameters(ArgParse); diff --git a/src/tests/test_log.cpp b/src/tests/test_log.cpp index 36446be..fdf3e54 100644 --- a/src/tests/test_log.cpp +++ b/src/tests/test_log.cpp @@ -1,9 +1,10 @@ +#define CATCH_CONFIG_MAIN +#include #include "../libcatnip/log.hpp" using namespace catnip; -int main(void) { +TEST_CASE("Log","[unit]") { LOG("Testing log message", 1); - return 0; } diff --git a/src/tests/test_logreader.cpp b/src/tests/test_logreader.cpp index dfca2cc..09e1286 100644 --- a/src/tests/test_logreader.cpp +++ b/src/tests/test_logreader.cpp @@ -1,7 +1,10 @@ +#define CATCH_CONFIG_MAIN +#include #include #include +#include #include #include #include @@ -12,12 +15,413 @@ using namespace catnip; using namespace std; -int main(void) { +TEST_CASE("Log Reader","[unit]") { - cerr << "Testing: LogReader Constructor" << endl; + cout << "Testing: LogReader Constructor" << endl; { LogReader lr("file.log"); } - cerr << "Testing: LogReader read" << endl; + cout << "Testing: LogReader read energies" << endl; + { + + string test_file = "testfile_energies.log"; + { + ofstream fid; + fid.open(test_file); + fid << "Test log file contains sections that the log reader"; + fid << " will search and read from." << endl; + fid << " Alpha occ. eigenvalues -- -10.19871 -10.19791 -0.76206 -0.58448 -0.47269" << endl; + fid << " Alpha occ. eigenvalues -- -0.42268 -0.36322 -0.27597" << endl; + fid << " Alpha virt. eigenvalues -- -0.00988 0.02500 0.03257 0.04671 0.06946" << endl; + fid << " Alpha virt. eigenvalues -- 0.08668 0.08746 0.12753 0.15670 0.17639" << endl; + fid.close(); + } + + LogReader lr(test_file); + lr.read(); + + Eigen::VectorXd orbital_energies = lr.getOE("Alpha"); + + set correct_orbital_energies = { + -10.19871, -10.19791, -0.76206, -0.58448, -0.47269, + -0.42268, -0.36322, -0.27597, + -0.00988, 0.02500, 0.03257, 0.04671, 0.06946, + 0.08668, 0.08746, 0.12753, 0.15670, 0.17639}; + + vector found_energy(correct_orbital_energies.size(),false); + for( int index = 0; index < orbital_energies.size();++index){ + if( correct_orbital_energies.count(orbital_energies(index))){ + found_energy.at(index) = true; + } + cout << "Found Energy " << orbital_energies(index); + cout << " " << found_energy.at(index) << endl; + } + + for ( const bool & found : found_energy){ + assert(found); + } + } + + cout << "Testing: LogReader read coordinates" << endl; + { + string test_file = "testfile_coords.log"; + { + ofstream fid; + fid.open(test_file); + fid << "Center Atomic Atomic" << endl; + fid << " Number Number Type X Y Z" << endl; + fid << " ---------------------------------------------------------------------" << endl; + fid << " 1 6 0 0.672749 0.000000 5.000000" << endl; + fid << " 2 6 0 -0.672749 0.000000 5.000000" << endl; + fid << " 3 1 0 1.242623 0.162327 5.920604" << endl; + fid << " 4 1 0 1.242623 -0.162327 4.079396" << endl; + fid << " 5 1 0 -1.242623 0.162327 5.920604" << endl; + fid << " 6 1 0 -1.242623 -0.162327 4.079396" << endl; + fid << "-----------------------------------"; + fid << "----------------------------------" << endl; + fid.close(); + } + + LogReader lr(test_file); + lr.read(); + + vector> atomic_coords = lr.getCoords(); + + cout << atomic_coords.at(0).at(0) << " "; + cout << atomic_coords.at(1).at(0) << " "; + cout << atomic_coords.at(2).at(0) << " "; + assert(atomic_coords.at(0).at(0) == 0.672749); + assert(atomic_coords.at(1).at(0) == 0.000000); + assert(atomic_coords.at(2).at(0) == 5.000000); + cout << "Atom 1 coordinates correct" << endl; + + cout << atomic_coords.at(0).at(1) << " "; + cout << atomic_coords.at(1).at(1) << " "; + cout << atomic_coords.at(2).at(1) << " "; + assert(atomic_coords.at(0).at(1) == -0.672749); + assert(atomic_coords.at(1).at(1) == 0.0000000); + assert(atomic_coords.at(2).at(1) == 5.0000000); + cout << "Atom 2 coordinates correct" << endl; + + cout << atomic_coords.at(0).at(2) << " "; + cout << atomic_coords.at(1).at(2) << " "; + cout << atomic_coords.at(2).at(2) << " "; + assert(atomic_coords.at(0).at(2) == 1.242623); + assert(atomic_coords.at(1).at(2) == 0.162327); + assert(atomic_coords.at(2).at(2) == 5.920604); + cout << "Atom 3 coordinates correct" << endl; + + cout << atomic_coords.at(0).at(3) << " "; + cout << atomic_coords.at(1).at(3) << " "; + cout << atomic_coords.at(2).at(3) << " "; + assert(atomic_coords.at(0).at(3) == 1.242623); + assert(atomic_coords.at(1).at(3) == -0.162327); + assert(atomic_coords.at(2).at(3) == 4.079396); + cout << "Atom 4 coordinates correct" << endl; + + cout << atomic_coords.at(0).at(4) << " "; + cout << atomic_coords.at(1).at(4) << " "; + cout << atomic_coords.at(2).at(4) << " "; + assert(atomic_coords.at(0).at(4) == -1.242623); + assert(atomic_coords.at(1).at(4) == 0.162327); + assert(atomic_coords.at(2).at(4) == 5.920604); + cout << "Atom 5 coordinates correct" << endl; + + cout << atomic_coords.at(0).at(5) << " "; + cout << atomic_coords.at(1).at(5) << " "; + cout << atomic_coords.at(2).at(5) << " "; + assert(atomic_coords.at(0).at(5) == -1.242623); + assert(atomic_coords.at(1).at(5) == -0.162327); + assert(atomic_coords.at(2).at(5) == 4.079396); + cout << "Atom 6 coordinates correct" << endl; + + } + + cout << "Testing: LogReader read overlap" << endl; + { + + string test_file = "testfile_overlap.log"; + { + ofstream fid; + fid.open(test_file); + fid << " *** Overlap *** " << endl; + fid << " 1 2 3 4 5" << endl; + fid << " 1 0.100000D+01" << endl; + fid << " 2 0.219059D+00 0.100000D+01" << endl; + fid << " 3 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 4 0.000000D+00 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 5 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 6 0.184261D+00 0.812273D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 7 0.000000D+00 0.000000D+00 0.569754D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 8 0.000000D+00 0.000000D+00 0.000000D+00 0.569754D+00 0.000000D+00" << endl; + fid << " 9 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.569754D+00" << endl; + fid << " 10 0.697718D-01 0.402091D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 11 0.000000D+00 0.000000D+00 0.164679D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 12 0.000000D+00 0.000000D+00 0.000000D+00 0.164679D+00 0.000000D+00" << endl; + fid << " 13 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.164679D+00" << endl; + fid << " 14 0.791027D-01 0.710235D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 15 0.791027D-01 0.710235D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 16 0.791027D-01 0.710235D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 17 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 18 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 19 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 20 0.481399D-05 0.194904D-01 -0.426713D-01 0.000000D+00 0.000000D+00" << endl; + fid << " 21 0.194904D-01 0.203366D+00 -0.282219D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 22 0.426713D-01 0.282219D+00 -0.333594D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 23 0.000000D+00 0.000000D+00 0.000000D+00 0.115814D+00 0.000000D+00" << endl; + fid << " 24 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.115814D+00" << endl; + fid << " 25 0.643636D-01 0.359351D+00 -0.253511D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 26 0.129620D+00 0.562375D+00 -0.170740D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 27 0.000000D+00 0.000000D+00 0.000000D+00 0.242739D+00 0.000000D+00" << endl; + fid << " 28 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.242739D+00" << endl; + fid << " 29 0.527094D-01 0.309785D+00 -0.673317D-01 0.000000D+00 0.000000D+00" << endl; + fid << " 30 0.555561D-01 0.303665D+00 0.598522D-01 0.000000D+00 0.000000D+00" << endl; + fid << " 31 0.000000D+00 0.000000D+00 0.000000D+00 0.126532D+00 0.000000D+00" << endl; + fid << " 32 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.126532D+00" << endl; + fid << " 33 0.526767D-01 0.334402D+00 -0.413876D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 34 0.113280D-02 0.928256D-01 -0.142160D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 35 0.113280D-02 0.928256D-01 -0.142160D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 36 0.000000D+00 0.000000D+00 0.000000D+00 0.183392D+00 0.000000D+00" << endl; + fid << " 37 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.183392D+00" << endl; + fid << " 38 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 39 0.320525D-01 0.270664D+00 0.190666D+00 0.543105D-01 0.308011D+00" << endl; + fid << " 40 0.916644D-01 0.473962D+00 0.138280D+00 0.393885D-01 0.223384D+00" << endl; + fid << " 41 0.320525D-01 0.270664D+00 0.190666D+00 -0.543105D-01 -0.308011D+00" << endl; + fid << " 42 0.916644D-01 0.473962D+00 0.138280D+00 -0.393885D-01 -0.223384D+00" << endl; + fid << " 43 0.430533D-04 0.789567D-02 -0.152645D-01 0.129366D-02 0.733675D-02" << endl; + fid << " 44 0.142782D-01 0.109874D+00 -0.102097D+00 0.865264D-02 0.490716D-01" << endl; + fid << " 45 0.430533D-04 0.789567D-02 -0.152645D-01 -0.129366D-02 -0.733675D-02" << endl; + fid << " 46 0.142782D-01 0.109874D+00 -0.102097D+00 -0.865264D-02 -0.490716D-01" << endl; + fid << " 6 7 8 9 10" << endl; + fid << " 6 0.100000D+01" << endl; + fid << " 7 0.000000D+00 0.100000D+01" << endl; + fid << " 8 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 9 0.000000D+00 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 10 0.727666D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 11 0.000000D+00 0.588690D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 12 0.000000D+00 0.000000D+00 0.588690D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 13 0.000000D+00 0.000000D+00 0.000000D+00 0.588690D+00 0.000000D+00" << endl; + fid << " 14 0.629936D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.323540D+00" << endl; + fid << " 15 0.629936D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.323540D+00" << endl; + fid << " 16 0.629936D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.323540D+00" << endl; + fid << " 17 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 18 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 19 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 20 0.643636D-01 -0.129620D+00 0.000000D+00 0.000000D+00 0.527094D-01" << endl; + fid << " 21 0.359351D+00 -0.562375D+00 0.000000D+00 0.000000D+00 0.309785D+00" << endl; + fid << " 22 0.253511D+00 -0.170740D+00 0.000000D+00 0.000000D+00 0.673317D-01" << endl; + fid << " 23 0.000000D+00 0.000000D+00 0.242739D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 24 0.000000D+00 0.000000D+00 0.000000D+00 0.242739D+00 0.000000D+00" << endl; + fid << " 25 0.579631D+00 -0.605354D+00 0.000000D+00 0.000000D+00 0.581168D+00" << endl; + fid << " 26 0.605354D+00 -0.525884D-01 0.000000D+00 0.000000D+00 0.250193D+00" << endl; + fid << " 27 0.000000D+00 0.000000D+00 0.579631D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 28 0.000000D+00 0.000000D+00 0.000000D+00 0.579631D+00 0.000000D+00" << endl; + fid << " 29 0.581168D+00 -0.250193D+00 0.000000D+00 0.000000D+00 0.867984D+00" << endl; + fid << " 30 0.491037D+00 0.258780D+00 0.000000D+00 0.000000D+00 0.461882D+00" << endl; + fid << " 31 0.000000D+00 0.000000D+00 0.470171D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 32 0.000000D+00 0.000000D+00 0.000000D+00 0.470171D+00 0.000000D+00" << endl; + fid << " 33 0.353148D+00 -0.422973D+00 0.000000D+00 0.000000D+00 0.254635D+00" << endl; + fid << " 34 0.255918D+00 -0.441451D+00 0.000000D+00 0.000000D+00 0.247363D+00" << endl; + fid << " 35 0.255918D+00 -0.441451D+00 0.000000D+00 0.000000D+00 0.247363D+00" << endl; + fid << " 36 0.000000D+00 0.000000D+00 0.161252D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 37 0.000000D+00 0.000000D+00 0.000000D+00 0.161252D+00 0.000000D+00" << endl; + fid << " 38 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 39 0.375116D+00 0.267879D+00 0.763046D-01 0.432746D+00 0.258482D+00" << endl; + fid << " 40 0.702351D+00 0.303675D+00 0.865010D-01 0.490572D+00 0.640357D+00" << endl; + fid << " 41 0.375116D+00 0.267879D+00 -0.763046D-01 -0.432746D+00 0.258482D+00" << endl; + fid << " 42 0.702351D+00 0.303675D+00 -0.865010D-01 -0.490572D+00 0.640357D+00" << endl; + fid << " 43 0.740737D-01 -0.176934D+00 0.149950D-01 0.850413D-01 0.158045D+00" << endl; + fid << " 44 0.262382D+00 -0.381297D+00 0.323148D-01 0.183267D+00 0.424412D+00" << endl; + fid << " 45 0.740737D-01 -0.176934D+00 -0.149950D-01 -0.850413D-01 0.158045D+00" << endl; + fid << " 46 0.262382D+00 -0.381297D+00 -0.323148D-01 -0.183267D+00 0.424412D+00" << endl; + fid << " 11 12 13 14 15" << endl; + fid << " 11 0.100000D+01" << endl; + fid << " 12 0.000000D+00 0.100000D+01" << endl; + fid << " 13 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 14 0.000000D+00 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 15 0.000000D+00 0.000000D+00 0.000000D+00 0.333333D+00 0.100000D+01" << endl; + fid << " 16 0.000000D+00 0.000000D+00 0.000000D+00 0.333333D+00 0.333333D+00" << endl; + fid << " 17 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 18 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 19 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 20 -0.555561D-01 0.000000D+00 0.000000D+00 0.526767D-01 0.113280D-02" << endl; + fid << " 21 -0.303665D+00 0.000000D+00 0.000000D+00 0.334402D+00 0.928256D-01" << endl; + fid << " 22 0.598522D-01 0.000000D+00 0.000000D+00 0.413876D+00 0.142160D+00" << endl; + fid << " 23 0.000000D+00 0.126532D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 24 0.000000D+00 0.000000D+00 0.126532D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 25 -0.491037D+00 0.000000D+00 0.000000D+00 0.353148D+00 0.255918D+00" << endl; + fid << " 26 0.258780D+00 0.000000D+00 0.000000D+00 0.422973D+00 0.441451D+00" << endl; + fid << " 27 0.000000D+00 0.470171D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 28 0.000000D+00 0.000000D+00 0.470171D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 29 -0.461882D+00 0.000000D+00 0.000000D+00 0.254635D+00 0.247363D+00" << endl; + fid << " 30 0.622202D+00 0.000000D+00 0.000000D+00 0.229601D+00 0.249594D+00" << endl; + fid << " 31 0.000000D+00 0.867984D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 32 0.000000D+00 0.000000D+00 0.867984D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 33 -0.229601D+00 0.000000D+00 0.000000D+00 0.487216D+00 0.154963D+00" << endl; + fid << " 34 -0.249594D+00 0.000000D+00 0.000000D+00 0.154963D+00 0.753228D-01" << endl; + fid << " 35 -0.249594D+00 0.000000D+00 0.000000D+00 0.154963D+00 0.251076D-01" << endl; + fid << " 36 0.000000D+00 0.236690D-01 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 37 0.000000D+00 0.000000D+00 0.236690D-01 0.000000D+00 0.000000D+00" << endl; + fid << " 38 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 39 0.109596D+00 0.312180D-01 0.177046D+00 0.207130D+00 0.123414D+00" << endl; + fid << " 40 0.226998D+00 0.646599D-01 0.366705D+00 0.371459D+00 0.351303D+00" << endl; + fid << " 41 0.109596D+00 -0.312180D-01 -0.177046D+00 0.207130D+00 0.123414D+00" << endl; + fid << " 42 0.226998D+00 -0.646599D-01 -0.366705D+00 0.371459D+00 0.351303D+00" << endl; + fid << " 43 -0.225200D+00 0.190856D-01 0.108240D+00 0.137730D-01 0.170528D-02" << endl; + fid << " 44 -0.505665D+00 0.428549D-01 0.243043D+00 0.120267D+00 0.707321D-01" << endl; + fid << " 45 -0.225200D+00 -0.190856D-01 -0.108240D+00 0.137730D-01 0.170528D-02" << endl; + fid << " 46 -0.505665D+00 -0.428549D-01 -0.243043D+00 0.120267D+00 0.707321D-01" << endl; + fid << " 16 17 18 19 20" << endl; + fid << " 16 0.100000D+01" << endl; + fid << " 17 0.000000D+00 0.100000D+01" << endl; + fid << " 18 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 19 0.000000D+00 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 20 0.113280D-02 0.000000D+00 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 21 0.928256D-01 0.000000D+00 0.000000D+00 0.000000D+00 0.219059D+00" << endl; + fid << " 22 0.142160D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 23 0.000000D+00 -0.183392D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 24 0.000000D+00 0.000000D+00 -0.183392D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 25 0.255918D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.184261D+00" << endl; + fid << " 26 0.441451D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 27 0.000000D+00 -0.161252D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 28 0.000000D+00 0.000000D+00 -0.161252D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 29 0.247363D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.697718D-01" << endl; + fid << " 30 0.249594D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 31 0.000000D+00 -0.236690D-01 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 32 0.000000D+00 0.000000D+00 -0.236690D-01 0.000000D+00 0.000000D+00" << endl; + fid << " 33 0.154963D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.791027D-01" << endl; + fid << " 34 0.251076D-01 0.000000D+00 0.000000D+00 0.000000D+00 0.791027D-01" << endl; + fid << " 35 0.753228D-01 0.000000D+00 0.000000D+00 0.000000D+00 0.791027D-01" << endl; + fid << " 36 0.000000D+00 -0.314243D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 37 0.000000D+00 0.000000D+00 -0.314243D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 38 0.000000D+00 0.000000D+00 0.000000D+00 0.753228D-01 0.000000D+00" << endl; + fid << " 39 0.353785D+00 0.449500D-01 0.254925D+00 0.726146D-01 0.430533D-04" << endl; + fid << " 40 0.406770D+00 0.108227D-01 0.613785D-01 0.174835D-01 0.142782D-01" << endl; + fid << " 41 0.353785D+00 -0.449500D-01 -0.254925D+00 0.726146D-01 0.430533D-04" << endl; + fid << " 42 0.406770D+00 -0.108227D-01 -0.613785D-01 0.174835D-01 0.142782D-01" << endl; + fid << " 43 0.442596D-02 -0.178424D-02 -0.101190D-01 0.857578D-03 0.320525D-01" << endl; + fid << " 44 0.818999D-01 -0.732391D-02 -0.415360D-01 0.352016D-02 0.916644D-01" << endl; + fid << " 45 0.442596D-02 0.178424D-02 0.101190D-01 0.857578D-03 0.320525D-01" << endl; + fid << " 46 0.818999D-01 0.732391D-02 0.415360D-01 0.352016D-02 0.916644D-01" << endl; + fid << " 21 22 23 24 25" << endl; + fid << " 21 0.100000D+01" << endl; + fid << " 22 0.000000D+00 0.100000D+01" << endl; + fid << " 23 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 24 0.000000D+00 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 25 0.812273D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 26 0.000000D+00 0.569754D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 27 0.000000D+00 0.000000D+00 0.569754D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 28 0.000000D+00 0.000000D+00 0.000000D+00 0.569754D+00 0.000000D+00" << endl; + fid << " 29 0.402091D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.727666D+00" << endl; + fid << " 30 0.000000D+00 0.164679D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 31 0.000000D+00 0.000000D+00 0.164679D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 32 0.000000D+00 0.000000D+00 0.000000D+00 0.164679D+00 0.000000D+00" << endl; + fid << " 33 0.710235D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.629936D+00" << endl; + fid << " 34 0.710235D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.629936D+00" << endl; + fid << " 35 0.710235D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.629936D+00" << endl; + fid << " 36 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 37 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 38 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 39 0.789567D-02 0.152645D-01 0.129366D-02 0.733675D-02 0.740737D-01" << endl; + fid << " 40 0.109874D+00 0.102097D+00 0.865264D-02 0.490716D-01 0.262382D+00" << endl; + fid << " 41 0.789567D-02 0.152645D-01 -0.129366D-02 -0.733675D-02 0.740737D-01" << endl; + fid << " 42 0.109874D+00 0.102097D+00 -0.865264D-02 -0.490716D-01 0.262382D+00" << endl; + fid << " 43 0.270664D+00 -0.190666D+00 0.543105D-01 0.308011D+00 0.375116D+00" << endl; + fid << " 44 0.473962D+00 -0.138280D+00 0.393885D-01 0.223384D+00 0.702351D+00" << endl; + fid << " 45 0.270664D+00 -0.190666D+00 -0.543105D-01 -0.308011D+00 0.375116D+00" << endl; + fid << " 46 0.473962D+00 -0.138280D+00 -0.393885D-01 -0.223384D+00 0.702351D+00" << endl; + fid << " 26 27 28 29 30" << endl; + fid << " 26 0.100000D+01" << endl; + fid << " 27 0.000000D+00 0.100000D+01" << endl; + fid << " 28 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 29 0.000000D+00 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 30 0.588690D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 31 0.000000D+00 0.588690D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 32 0.000000D+00 0.000000D+00 0.588690D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 33 0.000000D+00 0.000000D+00 0.000000D+00 0.323540D+00 0.000000D+00" << endl; + fid << " 34 0.000000D+00 0.000000D+00 0.000000D+00 0.323540D+00 0.000000D+00" << endl; + fid << " 35 0.000000D+00 0.000000D+00 0.000000D+00 0.323540D+00 0.000000D+00" << endl; + fid << " 36 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 37 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 38 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 39 0.176934D+00 0.149950D-01 0.850413D-01 0.158045D+00 0.225200D+00" << endl; + fid << " 40 0.381297D+00 0.323148D-01 0.183267D+00 0.424412D+00 0.505665D+00" << endl; + fid << " 41 0.176934D+00 -0.149950D-01 -0.850413D-01 0.158045D+00 0.225200D+00" << endl; + fid << " 42 0.381297D+00 -0.323148D-01 -0.183267D+00 0.424412D+00 0.505665D+00" << endl; + fid << " 43 -0.267879D+00 0.763046D-01 0.432746D+00 0.258482D+00 -0.109596D+00" << endl; + fid << " 44 -0.303675D+00 0.865010D-01 0.490572D+00 0.640357D+00 -0.226998D+00" << endl; + fid << " 45 -0.267879D+00 -0.763046D-01 -0.432746D+00 0.258482D+00 -0.109596D+00" << endl; + fid << " 46 -0.303675D+00 -0.865010D-01 -0.490572D+00 0.640357D+00 -0.226998D+00" << endl; + fid << " 31 32 33 34 35" << endl; + fid << " 31 0.100000D+01" << endl; + fid << " 32 0.000000D+00 0.100000D+01" << endl; + fid << " 33 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 34 0.000000D+00 0.000000D+00 0.333333D+00 0.100000D+01" << endl; + fid << " 35 0.000000D+00 0.000000D+00 0.333333D+00 0.333333D+00 0.100000D+01" << endl; + fid << " 36 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 37 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 38 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00 0.000000D+00" << endl; + fid << " 39 0.190856D-01 0.108240D+00 0.137730D-01 0.170528D-02 0.442596D-02" << endl; + fid << " 40 0.428549D-01 0.243043D+00 0.120267D+00 0.707321D-01 0.818999D-01" << endl; + fid << " 41 -0.190856D-01 -0.108240D+00 0.137730D-01 0.170528D-02 0.442596D-02" << endl; + fid << " 42 -0.428549D-01 -0.243043D+00 0.120267D+00 0.707321D-01 0.818999D-01" << endl; + fid << " 43 0.312180D-01 0.177046D+00 0.207130D+00 0.123414D+00 0.353785D+00" << endl; + fid << " 44 0.646599D-01 0.366705D+00 0.371459D+00 0.351303D+00 0.406770D+00" << endl; + fid << " 45 -0.312180D-01 -0.177046D+00 0.207130D+00 0.123414D+00 0.353785D+00" << endl; + fid << " 46 -0.646599D-01 -0.366705D+00 0.371459D+00 0.351303D+00 0.406770D+00" << endl; + fid << " 36 37 38 39 40" << endl; + fid << " 36 0.100000D+01" << endl; + fid << " 37 0.000000D+00 0.100000D+01" << endl; + fid << " 38 0.000000D+00 0.000000D+00 0.100000D+01" << endl; + fid << " 39 0.178424D-02 0.101190D-01 0.857578D-03 0.100000D+01" << endl; + fid << " 40 0.732391D-02 0.415360D-01 0.352016D-02 0.658292D+00 0.100000D+01" << endl; + fid << " 41 -0.178424D-02 -0.101190D-01 0.857578D-03 0.125798D-01 0.128011D+00" << endl; + fid << " 42 -0.732391D-02 -0.415360D-01 0.352016D-02 0.128011D+00 0.365470D+00" << endl; + fid << " 43 -0.449500D-01 -0.254925D+00 0.726146D-01 0.571644D-03 0.366357D-01" << endl; + fid << " 44 -0.108227D-01 -0.613785D-01 0.174835D-01 0.366357D-01 0.168873D+00" << endl; + fid << " 45 0.449500D-01 0.254925D+00 0.726146D-01 0.104764D-04 0.720595D-02" << endl; + fid << " 46 0.108227D-01 0.613785D-01 0.174835D-01 0.720595D-02 0.617178D-01" << endl; + fid << " 41 42 43 44 45" << endl; + fid << " 41 0.100000D+01" << endl; + fid << " 42 0.658292D+00 0.100000D+01" << endl; + fid << " 43 0.104764D-04 0.720595D-02 0.100000D+01" << endl; + fid << " 44 0.720595D-02 0.617178D-01 0.658292D+00 0.100000D+01" << endl; + fid << " 45 0.571644D-03 0.366357D-01 0.125798D-01 0.128011D+00 0.100000D+01" << endl; + fid << " 46 0.366357D-01 0.168873D+00 0.128011D+00 0.365470D+00 0.658292D+00" << endl; + fid << " 46" << endl; + fid << " 46 0.100000D+01" << endl; + fid.close(); + } + + LogReader lr(test_file); + lr.read(); + + Eigen::MatrixXd overlap = lr.getOverlapMatrix(); + + cout << "Overlap Matrix rows " << overlap.rows() << " cols " << overlap.cols() << endl; + assert(overlap.rows()==46); + assert(overlap.cols()==46); + // We will test the corners of the overlap matrix and a few elements + // at random + cout << "row 1 1 1.000 " << overlap(0,0) << endl; + assert(overlap(0,0)==1); + cout << "row 1 46 0.0142782 " << overlap(0,45) << endl; + assert(overlap(0,45)==0.0142782); + cout << "row 46 1 0.0142782 " << overlap(45,0) << endl; + assert(overlap(45,0)==0.0142782); + cout << "row 46 46 1.000 " << overlap(45,45) << endl; + assert(overlap(45,45)==1); + + assert(overlap(10,6)==0.588690); + assert(overlap(6,10)==0.588690); + + assert(overlap(38,27)==0.0850413); + assert(overlap(27,38)==0.0850413); + + assert(overlap(26,22)==0.569754); + assert(overlap(26,22)==0.569754); + } + + cout << "Testing: LogReader read" << endl; { LogReader lr("../../../GAUSSIANFILES/90_unordered/90_pair.log"); @@ -25,14 +429,15 @@ int main(void) { auto orb_info = lr.getOrbitalInfo(); auto Soverlap = lr.getOverlapMatrix(); - cout << Soverlap->get_rows() << endl; + cout << Soverlap.rows() << endl; auto Alpha = lr.getOE("Alpha"); auto basisFuncCount = lr.getBasisFuncCount(); for (auto c : basisFuncCount) { cout << c << endl; } - auto xyz = lr.getCoords(); + + vector> xyz = lr.getCoords(); auto x = xyz.at(0); auto y = xyz.at(1); auto z = xyz.at(2); @@ -40,5 +445,4 @@ int main(void) { cout << x.at(ind) << " " << y.at(ind) << " " << z.at(ind) << endl; } } - return 0; } diff --git a/src/tests/test_matrix.cpp b/src/tests/test_matrix.cpp deleted file mode 100644 index db78067..0000000 --- a/src/tests/test_matrix.cpp +++ /dev/null @@ -1,298 +0,0 @@ -#include "../libcatnip/matrix.hpp" -#include -#include - -using namespace catnip; -using namespace std; - -int main() { - - cout << "Testing Constructors\n" << endl; - - cout << "Testing: Matrix::Matrix()\n" << endl; - { - Matrix mat0; - cout << mat0 << endl; - } - - cout << "Testing: Matrix::Matrix(int r)\n" << endl; - { - Matrix mat1(3); - cout << mat1 << endl; - } - - cout << "Testing: Matrix::Matrix(int r, int c)\n" << endl; - { - Matrix mat2(2, 3); - cout << mat2 << endl; - } - - cout << "Testing: Matrix::Matrix(int r, int c, int s)\n" << endl; - { - Matrix mat3(3, 1, 2); - cout << mat3 << endl; - } - - cout << "Testing: Matrix::Matrix(vector v_data)\n" << endl; - { - vector v = {1.2, 324.4, 23}; - Matrix mat3(v); - } - - cout << "Testing: Matrix::Matrix(vector> vv_data)\n" << endl; - { - vector> vv_data; - vector v = {1.2, 324.4, 23}; - vv_data.push_back(v); - v.at(1) = -12.5; - vv_data.push_back(v); - Matrix mat3(vv_data); - } - - cout << "\nTesting: Matrix::set_rows(int r)\n" << endl; - { - Matrix mat0; - mat0.set_rows(3); - cout << mat0 << endl; - } - - cout << "\nTesting: Matrix::set_cols(int c)\n" << endl; - { - Matrix mat0; - mat0.set_cols(4); - cout << mat0 << endl; - } - - cout << "\nTesting: Matrix::set_shel(int s)\n" << endl; - { - Matrix mat0; - mat0.set_shel(2); - cout << mat0 << endl; - } - - cout << "\nTesting: Matrix::operator=(const Matrix mat)\n" << endl; - { - vector> vv_data; - vector v = {1.2, 324.4, 23}; - vv_data.push_back(v); - v.at(1) = -12.5; - vv_data.push_back(v); - Matrix mat3(vv_data); - Matrix mat1; - mat1 = mat3; - assert(static_cast(mat1.get_elem(1, 1) * 10) == 12); - assert(static_cast(mat1.get_elem(1, 2) * 10) == 3244); - assert(static_cast(mat1.get_elem(1, 3)) == 23); - assert(static_cast(mat1.get_elem(2, 1) * 10) == 12); - assert(static_cast(mat1.get_elem(2, 2) * 10) == -125); - assert(static_cast(mat1.get_elem(2, 3)) == 23); - } - cout << "\nTesting: Matrix::set_elem(double val)\n" << endl; - { - Matrix mat0; - mat0.set_elem(5.4); - cout << mat0 << endl; - } - - cout << "\nTesting: Matrix::set_elem(double val, int r)\n" << endl; - { - Matrix mat0; - mat0.set_rows(3); - mat0.set_elem(4.4, 3); - cout << mat0 << endl; - } - - cout << "\nTesting: Matrix::set_elem(double val, int r, int c)\n" << endl; - { - Matrix mat0; - mat0.set_rows(3); - mat0.set_cols(4); - mat0.set_elem(4.2, 3, 4); - cout << mat0 << endl; - } - - cout << "\nTesting: Matrix::set_elem(double val, int r, int c)\n" << endl; - { - Matrix mat0; - mat0.set_rows(3); - mat0.set_cols(4); - mat0.set_shel(2); - mat0.set_elem(0.3, 3, 4, 2); - cout << mat0 << endl; - } - - { - Matrix mat4(2, 3); - Matrix mat5(3, 2); - - mat4.set_elem(5, 1, 1); - mat4.set_elem(3, 1, 2); - mat4.set_elem(1, 1, 3); - mat4.set_elem(2, 2, 2); - mat4.set_elem(1, 2, 3); - - mat5.set_elem(2, 1, 1); - mat5.set_elem(1, 1, 2); - mat5.set_elem(1, 2, 1); - mat5.set_elem(3, 3, 1); - mat5.set_elem(4, 3, 2); - - cout << mat4 << endl; - cout << mat5 << endl; - - Matrix mat6 = mat4 * mat5; - cout << mat6 << endl; - - cout << "\nResizing matrix 6" << endl; - mat6.resize(3, 3); - cout << mat6 << endl; - } - - cerr << "Testing: matchRow" << endl; - { - Matrix mat4(2, 3); - Matrix mat5(3, 3); - - // mat4 - // 5 3 1 - // 0 2 1 - - mat4.set_elem(5, 1, 1); - mat4.set_elem(3, 1, 2); - mat4.set_elem(1, 1, 3); - mat4.set_elem(2, 2, 2); - mat4.set_elem(1, 2, 3); - - // mat5 - // 2 1 0 - // 1 0 0 - // 5 3 1 - mat5.set_elem(2, 1, 1); - mat5.set_elem(1, 1, 2); - mat5.set_elem(1, 2, 1); - mat5.set_elem(5, 3, 1); - mat5.set_elem(3, 3, 2); - mat5.set_elem(1, 3, 3); - - auto m_vec = mat4.matchRow(mat5, 4); - assert(m_vec.at(0) == 3); - } - - cerr << "Testing: set_row & set_col" << endl; - { - // mat5 - // 2 1 0 - // 1 0 0 - // 5 3 1 - Matrix mat5(3, 3); - mat5.set_elem(2, 1, 1); - mat5.set_elem(1, 1, 2); - mat5.set_elem(0, 1, 3); - mat5.set_elem(1, 2, 1); - mat5.set_elem(0, 2, 2); - mat5.set_elem(0, 2, 3); - mat5.set_elem(5, 3, 1); - mat5.set_elem(3, 3, 2); - mat5.set_elem(1, 3, 3); - - vector values{9, 12, 13}; - mat5.set_row(values, 1); - assert(mat5.get_elem(1, 1) == 9); - assert(mat5.get_elem(1, 2) == 12); - assert(mat5.get_elem(1, 3) == 13); - assert(mat5.get_elem(2, 1) == 1); - assert(mat5.get_elem(2, 2) == 0); - assert(mat5.get_elem(2, 3) == 0); - assert(mat5.get_elem(3, 1) == 5); - assert(mat5.get_elem(3, 2) == 3); - assert(mat5.get_elem(3, 3) == 1); - - vector values2{-12, 23, 101}; - mat5.set_col(values2, 2); - assert(mat5.get_elem(1, 1) == 9); - assert(mat5.get_elem(1, 2) == -12); - assert(mat5.get_elem(1, 3) == 13); - assert(mat5.get_elem(2, 1) == 1); - assert(mat5.get_elem(2, 2) == 23); - assert(mat5.get_elem(2, 3) == 0); - assert(mat5.get_elem(3, 1) == 5); - assert(mat5.get_elem(3, 2) == 101); - assert(mat5.get_elem(3, 3) == 1); - } - - cerr << "Testing: move_row & move_col" << endl; - { - // mat5 - // 2 1 0 - // 1 0 0 - // 5 3 1 - Matrix mat5(3, 3); - mat5.set_elem(2, 1, 1); - mat5.set_elem(1, 1, 2); - mat5.set_elem(0, 1, 3); - mat5.set_elem(1, 2, 1); - mat5.set_elem(0, 2, 2); - mat5.set_elem(0, 2, 3); - mat5.set_elem(5, 3, 1); - mat5.set_elem(3, 3, 2); - mat5.set_elem(1, 3, 3); - - // 5 3 1 - // 2 1 0 - // 1 0 0 - mat5.move_row(3, 1); - assert(mat5.get_elem(1, 1) == 5); - assert(mat5.get_elem(1, 2) == 3); - assert(mat5.get_elem(1, 3) == 1); - assert(mat5.get_elem(2, 1) == 2); - assert(mat5.get_elem(2, 2) == 1); - assert(mat5.get_elem(2, 3) == 0); - assert(mat5.get_elem(3, 1) == 1); - assert(mat5.get_elem(3, 2) == 0); - assert(mat5.get_elem(3, 3) == 0); - - // 1 5 3 - // 0 2 1 - // 0 1 0 - mat5.move_col(3, 1); - cerr << mat5 << endl; - assert(mat5.get_elem(1, 1) == 1); - assert(mat5.get_elem(1, 2) == 5); - assert(mat5.get_elem(1, 3) == 3); - assert(mat5.get_elem(2, 1) == 0); - assert(mat5.get_elem(2, 2) == 2); - assert(mat5.get_elem(2, 3) == 1); - assert(mat5.get_elem(3, 1) == 0); - assert(mat5.get_elem(3, 2) == 1); - assert(mat5.get_elem(3, 3) == 0); - - // 0 2 1 - // 0 1 0 - // 1 5 3 - mat5.move_row(1, 3); - assert(mat5.get_elem(1, 1) == 0); - assert(mat5.get_elem(1, 2) == 2); - assert(mat5.get_elem(1, 3) == 1); - assert(mat5.get_elem(2, 1) == 0); - assert(mat5.get_elem(2, 2) == 1); - assert(mat5.get_elem(2, 3) == 0); - assert(mat5.get_elem(3, 1) == 1); - assert(mat5.get_elem(3, 2) == 5); - assert(mat5.get_elem(3, 3) == 3); - - // 2 1 0 - // 1 0 0 - // 5 3 1 - mat5.move_col(1, 3); - assert(mat5.get_elem(1, 1) == 2); - assert(mat5.get_elem(1, 2) == 1); - assert(mat5.get_elem(1, 3) == 0); - assert(mat5.get_elem(2, 1) == 1); - assert(mat5.get_elem(2, 2) == 0); - assert(mat5.get_elem(2, 3) == 0); - assert(mat5.get_elem(3, 1) == 5); - assert(mat5.get_elem(3, 2) == 3); - assert(mat5.get_elem(3, 3) == 1); - } - return 0; -} diff --git a/src/tests/test_parameters.cpp b/src/tests/test_parameters.cpp index 80847c4..50884bb 100644 --- a/src/tests/test_parameters.cpp +++ b/src/tests/test_parameters.cpp @@ -1,10 +1,13 @@ + +#define CATCH_CONFIG_MAIN +#include + #include "../libcatnip/parameters.hpp" using namespace catnip; -int main(void) { +TEST_CASE("Parameters","[unit]") { Parameters Par; - return 0; } diff --git a/src/tests/test_propertydouble.cpp b/src/tests/test_propertydouble.cpp deleted file mode 100644 index a70ec8e..0000000 --- a/src/tests/test_propertydouble.cpp +++ /dev/null @@ -1,68 +0,0 @@ - -#include "../libcatnip/io/arguments/properties/propertydouble.hpp" -#include -#include -#include -#include -#include - -using namespace catnip; -using namespace std; - -int main(void) { - - cerr << "Testing: PropertyDouble" << endl; - cerr << "Testing: constructor" << endl; - { PropertyDouble propDouble; } - - cerr << "Testing: getPropertyName" << endl; - { - PropertyDouble propDouble; - string name = propDouble.getPropertyName(); - assert(name.compare("PROPERTY_DOUBLE") == 0); - } - - cerr << "Testing: getPropertyOptions" << endl; - { - - PropertyDouble propDouble; - auto options = propDouble.getPropertyOptions(); - string opt = options.at(0); - assert(opt.compare("MIN") == 0); - opt = options.at(1); - assert(opt.compare("MAX") == 0); - } - - cerr << "Testing: propValid" << endl; - { - PropertyDouble propDouble; - bool valid = propDouble.propValid(0.0); - assert(valid); - } - - cerr << "Testing: setPropOption" << endl; - { - PropertyDouble propDouble; - double val = -1.2; - propDouble.setPropOption("MIN", val); - propDouble.propValid(0.0); - bool excep = false; - try { - val = -2.3; - propDouble.propValid(val); - } catch (...) { - excep = true; - } - assert(excep); - - excep = false; - try { - val = 3.5; - propDouble.setPropOption("MAXimum", val); - } catch (...) { - excep = true; - } - assert(excep); - } - return 0; -} diff --git a/src/tests/test_propertyfileexist.cpp b/src/tests/test_propertyfileexist.cpp deleted file mode 100644 index d405b16..0000000 --- a/src/tests/test_propertyfileexist.cpp +++ /dev/null @@ -1,71 +0,0 @@ - -#include "../libcatnip/io/arguments/properties/propertyfileexist.hpp" -#include -#include -#include -#include -#include - -using namespace catnip; -using namespace std; - -int main(void) { - - cerr << "Testing: PropertyFileExist" << endl; - cerr << "Testing: constructor" << endl; - { - PropertyFileExist propFileExist1(true); - PropertyFileExist propFileExist2(false); - } - - cerr << "Testing: getPropertyName" << endl; - { - PropertyFileExist propFileExist; - string name = propFileExist.getPropertyName(); - assert(name.compare("PROPERTY_FILE_EXIST") == 0); - } - - cerr << "Testing: getPropertyOptions" << endl; - { - - PropertyFileExist propFileExist; - auto options = propFileExist.getPropertyOptions(); - string opt = options.at(0); - assert(opt.compare("FILE_MUST_EXIST") == 0); - } - - cerr << "Testing: propValid" << endl; - { - PropertyFileExist propFileExist1(false); - PropertyFileExist propFileExist2(true); - PropertyFileExist propFileExist3(true); - - bool valid = propFileExist1.propValid("test_propertyfileexist.cpp"); - assert(valid); - - bool excep = false; - try { - valid = propFileExist2.propValid("fake"); - } catch (...) { - excep = true; - } - assert(excep); - - valid = propFileExist3.propValid("testfile.pun"); - assert(valid); - } - - cerr << "Testing: getPropOption" << endl; - { - PropertyFileExist propFileExist1(true); - PropertyFileExist propFileExist2(false); - - bool fileExist = propFileExist1.getPropOption("FILE_MUST_EXIST"); - assert(fileExist); - - fileExist = propFileExist2.getPropOption("FILE_MUST_EXIST"); - assert(fileExist == false); - } - - return 0; -} diff --git a/src/tests/test_propertyfileext.cpp b/src/tests/test_propertyfileext.cpp deleted file mode 100644 index dc9fc2d..0000000 --- a/src/tests/test_propertyfileext.cpp +++ /dev/null @@ -1,82 +0,0 @@ - -#include "../libcatnip/io/arguments/properties/propertyfileext.hpp" -#include -#include -#include -#include -#include - -using namespace catnip; -using namespace std; - -int main(void) { - - cerr << "Testing: PropertyFileExt" << endl; - cerr << "Testing: constructor" << endl; - { - PropertyFileExt propFileExt1("*"); - PropertyFileExt propFileExt2(""); - PropertyFileExt propFileExt3(".jpg"); - bool excep = false; - try { - PropertyFileExt propFileExt4("ffda.fd"); - } catch (...) { - excep = true; - } - assert(excep); - - set exts = {".png", ".gjf"}; - PropertyFileExt propFileExt5(exts); - } - - cerr << "Testing: getPropertyName" << endl; - { - PropertyFileExt propFileExt; - string name = propFileExt.getPropertyName(); - assert(name.compare("PROPERTY_FILE_EXT") == 0); - } - - cerr << "Testing: getPropertyOptions" << endl; - { - - PropertyFileExt propFileExt; - auto options = propFileExt.getPropertyOptions(); - string opt = options.at(0); - assert(opt.compare("ALLOWED_FILE_EXT") == 0); - } - - cerr << "Testing: propValid" << endl; - { - PropertyFileExt propFileExt(".jpg"); - bool valid = propFileExt.propValid("dir/file.jpg"); - assert(valid); - bool excep = false; - try { - propFileExt.propValid("dir/file.jp"); - } catch (...) { - excep = true; - } - assert(excep); - - PropertyFileExt propFileExt2("*"); - valid = propFileExt2.propValid("dir/file.jpg"); - assert(valid); - valid = propFileExt2.propValid("dir/file.jp"); - assert(valid); - - set exts = {".png", ".gjf"}; - PropertyFileExt propFileExt3(exts); - valid = propFileExt3.propValid("Dir2/Path/File.png"); - assert(valid); - valid = propFileExt3.propValid("Dir2/Path/File.gjf"); - assert(valid); - excep = false; - try { - propFileExt3.propValid("dir/file.com"); - } catch (...) { - excep = true; - } - assert(excep); - } - return 0; -} diff --git a/src/tests/test_propertyint.cpp b/src/tests/test_propertyint.cpp deleted file mode 100644 index ecc50fb..0000000 --- a/src/tests/test_propertyint.cpp +++ /dev/null @@ -1,65 +0,0 @@ - -#include "../libcatnip/io/arguments/properties/propertyint.hpp" -#include -#include -#include -#include -#include - -using namespace catnip; -using namespace std; - -int main(void) { - - cerr << "Testing: PropertyInt" << endl; - cerr << "Testing: constructor" << endl; - { PropertyInt propInt; } - - cerr << "Testing: getPropertyName" << endl; - { - PropertyInt propInt; - string name = propInt.getPropertyName(); - assert(name.compare("PROPERTY_INT") == 0); - } - - cerr << "Testing: getPropertyOptions" << endl; - { - - PropertyInt propInt; - auto options = propInt.getPropertyOptions(); - string opt = options.at(0); - assert(opt.compare("MIN") == 0); - opt = options.at(1); - assert(opt.compare("MAX") == 0); - } - - cerr << "Testing: propValid" << endl; - { - PropertyInt propInt; - bool valid = propInt.propValid(0); - assert(valid); - } - - cerr << "Testing: setPropOption" << endl; - { - PropertyInt propInt; - propInt.setPropOption("MIN", 0); - propInt.propValid(0); - bool excep = false; - try { - propInt.propValid(-1); - } catch (...) { - excep = true; - } - assert(excep); - - excep = false; - try { - propInt.setPropOption("MAXimum", 3); - } catch (...) { - excep = true; - } - assert(excep); - } - return 0; -} diff --git a/src/tests/test_propertysisterfile.cpp b/src/tests/test_propertysisterfile.cpp deleted file mode 100644 index 60b947a..0000000 --- a/src/tests/test_propertysisterfile.cpp +++ /dev/null @@ -1,114 +0,0 @@ - -#include "../libcatnip/io/arguments/properties/propertysisterfile.hpp" -#include -#include -#include -#include -#include -#include - -using namespace catnip; -using namespace std; - -int main(void) { - fstream fs; - fs.open("testfile.pun", ios::out); - fs.close(); - - cerr << "Testing: PropertySisterFile" << endl; - cerr << "Testing: constructor" << endl; - { PropertySisterFile propSisterFile1; } - - cerr << "Testing: getPropertyName" << endl; - { - PropertySisterFile propSisterFile; - string name = propSisterFile.getPropertyName(); - assert(name.compare("PROPERTY_SISTER_FILE") == 0); - } - - cerr << "Testing: getPropertyOptions" << endl; - { - - PropertySisterFile propSisterFile; - auto options = propSisterFile.getPropertyOptions(); - - bool allowed_file = false; - bool sister_name = false; - bool sister_path = false; - bool sister_name_path = false; - bool sister_exists = false; - - for (auto opt : options) { - if (opt.compare("ALLOWED_SISTER_FILE_EXT") == 0) { - allowed_file = true; - } - if (opt.compare("SISTER_FILE_NAME") == 0) { - sister_name = true; - } - if (opt.compare("SISTER_FILE_PATH") == 0) { - sister_path = true; - } - if (opt.compare("SISTER_FILE_PATH_NAME") == 0) { - sister_name_path = true; - } - if (opt.compare("SISTER_FILE_EXISTS") == 0) { - sister_exists = true; - } - } - assert(allowed_file); - assert(sister_name); - assert(sister_path); - assert(sister_name_path); - assert(sister_exists); - } - - cerr << "Testing: getPropOption" << endl; - { - PropertySisterFile propSisterFile1; - - vector allowed_ext = - propSisterFile1.getPropOption("ALLOWED_SISTER_FILE_EXT"); - vector file_name = - propSisterFile1.getPropOption("SISTER_FILE_NAME"); - vector file_path = - propSisterFile1.getPropOption("SISTER_FILE_PATH"); - vector file_path_name = - propSisterFile1.getPropOption("SISTER_FILE_PATH_NAME"); - vector fileExist = - propSisterFile1.getPropOption("SISTER_FILE_EXISTS"); - - assert(allowed_ext.at(0).compare("NOT_DEFINED") == 0); - assert(file_name.at(0).compare("NOT_DEFINED") == 0); - assert(file_path.at(0).compare("NOT_DEFINED") == 0); - assert(file_path_name.at(0).compare("NOT_DEFINED") == 0); - assert(fileExist.at(0).compare("false") == 0); - } - - cerr << "Testing: getPropOption" << endl; - { - PropertySisterFile propSisterFile1; - - propSisterFile1.setPropOption("ALLOWED_SISTER_FILE_EXT", ".pun"); - - string fileName = "testfile.log"; - propSisterFile1.propValid(fileName); - vector allowed_ext = - propSisterFile1.getPropOption("ALLOWED_SISTER_FILE_EXT"); - vector file_name = - propSisterFile1.getPropOption("SISTER_FILE_NAME"); - vector file_path = - propSisterFile1.getPropOption("SISTER_FILE_PATH"); - vector file_path_name = - propSisterFile1.getPropOption("SISTER_FILE_PATH_NAME"); - vector fileExist = - propSisterFile1.getPropOption("SISTER_FILE_EXISTS"); - - assert(allowed_ext.at(0).compare(".pun") == 0); - - assert(file_name.at(0).compare("testfile.pun") == 0); - assert(file_path.at(0).compare("") == 0); - assert(file_path_name.at(0).compare("testfile.pun") == 0); - assert(fileExist.at(0).compare("true") == 0); - } - return 0; -} diff --git a/src/tests/test_propertystring.cpp b/src/tests/test_propertystring.cpp deleted file mode 100644 index f0e0ce0..0000000 --- a/src/tests/test_propertystring.cpp +++ /dev/null @@ -1,67 +0,0 @@ - -#include "../libcatnip/io/arguments/properties/propertystring.hpp" -#include -#include -#include -#include -#include - -using namespace catnip; -using namespace std; - -int main(void) { - - cerr << "Testing: PropertyString" << endl; - cerr << "Testing: constructor" << endl; - { PropertyString propString; } - - cerr << "Testing: getPropertyName" << endl; - { - PropertyString propString; - string name = propString.getPropertyName(); - assert(name.compare("PROPERTY_STRING") == 0); - } - - cerr << "Testing: getPropertyOptions" << endl; - { - - PropertyString propString; - auto options = propString.getPropertyOptions(); - string opt = options.at(0); - assert(opt.compare("MIN_LENGTH") == 0); - opt = options.at(1); - assert(opt.compare("MAX_LENGTH") == 0); - } - - cerr << "Testing: propValid" << endl; - { - PropertyString propString; - bool valid = propString.propValid("Hello"); - assert(valid); - } - - cerr << "Testing: setPropOption" << endl; - { - PropertyString propString; - size_t val = 3; - propString.setPropOption("MAX_LENGTH", val); - propString.propValid(""); - bool excep = false; - try { - propString.propValid("Hello"); - } catch (...) { - excep = true; - } - assert(excep); - - excep = false; - try { - val = 4; - propString.setPropOption("MAXimum", val); - } catch (...) { - excep = true; - } - assert(excep); - } - return 0; -} diff --git a/src/tests/test_propertystringchoice.cpp b/src/tests/test_propertystringchoice.cpp deleted file mode 100644 index 7c1cbcc..0000000 --- a/src/tests/test_propertystringchoice.cpp +++ /dev/null @@ -1,99 +0,0 @@ - -#include "../libcatnip/io/arguments/properties/propertystringchoice.hpp" -#include -#include -#include -#include -#include -#include - -using namespace catnip; -using namespace std; - -int main(void) { - cerr << "Testing: PropertyStringChoice" << endl; - cerr << "Testing: constructor" << endl; - { PropertyStringChoice propStrChoice; } - - cerr << "Testing: getPropertyName" << endl; - { - PropertyStringChoice propStrChoice; - string name = propStrChoice.getPropertyName(); - assert(name.compare("PROPERTY_STRING_CHOICE") == 0); - } - - cerr << "Testing: getPropertyOptions" << endl; - { - - PropertyStringChoice propStrChoice; - auto options = propStrChoice.getPropertyOptions(); - - bool choice_enforced = false; - bool str_choices = false; - - for (auto opt : options) { - if (opt.compare("STRING_CHOICE_ENFORCED") == 0) { - choice_enforced = true; - } - if (opt.compare("STRING_CHOICES") == 0) { - str_choices = true; - } - } - assert(choice_enforced); - assert(str_choices); - } - - cerr << "Testing: getPropOption" << endl; - { - PropertyStringChoice propStrChoice; - - set choice_enforced = - propStrChoice.getPropOption("STRING_CHOICE_ENFORCED"); - set choices = propStrChoice.getPropOption("STRING_CHOICES"); - - string enforced = *(choice_enforced.begin()); - string choice = *(choices.begin()); - assert(enforced.compare("false") == 0); - assert(choice.compare("NOT_DEFINED") == 0); - } - - cerr << "Testing: getPropOption" << endl; - { - PropertyStringChoice propStrChoice; - - propStrChoice.setPropOption("STRING_CHOICE_ENFORCED", "true"); - set choices{"true", "false"}; - propStrChoice.setPropOption("STRING_CHOICES", choices); - - string choice = "true"; - propStrChoice.propValid(choice); - choice = "false"; - propStrChoice.propValid(choice); - - choice = "blah"; - bool throwerror = false; - try { - propStrChoice.propValid(choice); - } catch (...) { - throwerror = true; - } - assert(throwerror); - - set allowed_choices = propStrChoice.getPropOption("STRING_CHOICES"); - set choice_on = - propStrChoice.getPropOption("STRING_CHOICE_ENFORCED"); - - bool false_str = false; - bool true_str = false; - for (auto item : allowed_choices) { - if (item.compare("false") == 0) false_str = true; - if (item.compare("true") == 0) true_str = true; - } - assert(false_str); - assert(true_str); - - string on = *(choice_on.begin()); - assert(on.compare("true") == 0); - } - return 0; -} diff --git a/src/tests/test_propertyswitch.cpp b/src/tests/test_propertyswitch.cpp deleted file mode 100644 index ec41006..0000000 --- a/src/tests/test_propertyswitch.cpp +++ /dev/null @@ -1,88 +0,0 @@ - -#include "../libcatnip/io/arguments/properties/propertyswitch.hpp" -#include -#include -#include -#include -#include - -using namespace catnip; -using namespace std; - -int main(void) { - - cerr << "Testing: PropertySwitch" << endl; - cerr << "Testing: constructor" << endl; - { PropertySwitch propSwitch; } - - cerr << "Testing: getPropertyName" << endl; - { - PropertySwitch propSwitch; - string name = propSwitch.getPropertyName(); - assert(name.compare("PROPERTY_SWITCH") == 0); - } - - cerr << "Testing: getPropertyOptions" << endl; - { - - PropertySwitch propSwitch; - auto options = propSwitch.getPropertyOptions(); - string opt = options.at(0); - assert(opt.compare("DEFAULT") == 0); - } - - cerr << "Testing: propValid" << endl; - { - PropertySwitch propSwitch; - bool valid = propSwitch.propValid(0); - assert(valid); - valid = propSwitch.propValid(1); - assert(valid); - valid = propSwitch.propValid(); - assert(valid); - bool excep = false; - try { - propSwitch.propValid(-1); - } catch (...) { - excep = true; - } - assert(excep); - - excep = false; - try { - propSwitch.propValid(2); - } catch (...) { - excep = true; - } - assert(excep); - - valid = propSwitch.propValid("ON"); - assert(valid); - valid = propSwitch.propValid("OFF"); - assert(valid); - valid = propSwitch.propValid("TRUE"); - assert(valid); - valid = propSwitch.propValid("FALSE"); - assert(valid); - valid = propSwitch.propValid("0"); - assert(valid); - valid = propSwitch.propValid("1"); - assert(valid); - } - - cerr << "Testing: setPropOption" << endl; - { - PropertySwitch propSwitch; - propSwitch.setPropOption("DEFAULT", "ON"); - propSwitch.setPropOption("DEFAULT", "OFF"); - // propSwitch.propValid(0); - // bool excep = false; - // try { - // propSwitch.propValid(-1); - // } catch (...) { - // excep = true; - // } - // assert(excep); - } - return 0; -} diff --git a/src/tests/test_punreader.cpp b/src/tests/test_punreader.cpp index 87136cd..3d36a2b 100644 --- a/src/tests/test_punreader.cpp +++ b/src/tests/test_punreader.cpp @@ -1,14 +1,17 @@ +#define CATCH_CONFIG_MAIN +#include #include "../libcatnip/io/file_readers/punreader.hpp" #include #include #include #include +#include using namespace catnip; using namespace std; -int main(void) { +TEST_CASE("Pun Reader","[unit]") { cerr << "Testing: PunReader Constructor" << endl; { PunReader pr("file.pun"); } @@ -18,9 +21,8 @@ int main(void) { PunReader pr("../../../GAUSSIANFILES/90_unordered/90_pair.pun"); pr.read(); - auto m = pr.getCoefsMatrix("Alpha"); - assert(m->get_rows() == 92); + Eigen::MatrixXd m = pr.getCoefsMatrix("Alpha"); + assert(m.rows() == 92); assert(pr.restrictedShell()); } - return 0; } diff --git a/src/tests/test_qc_functions.cpp b/src/tests/test_qc_functions.cpp index 0f94b9a..d0ef8a8 100644 --- a/src/tests/test_qc_functions.cpp +++ b/src/tests/test_qc_functions.cpp @@ -1,30 +1,34 @@ -#include "../libcatnip/matrix.hpp" + +#define CATCH_CONFIG_MAIN +#include #include "../libcatnip/qc_functions.hpp" +#include "../libcatnip/matrix.hpp" #include #include #include - +#include using namespace catnip; using namespace std; -int main(void) { +TEST_CASE("QC Functions","[unit]") { cout << "Testing: unscramble_Coef" << endl; { - Matrix* dimerCoef = new Matrix(8, 8); - for (int i = 1; i <= 8; ++i) { - dimerCoef->set_elem(1.3, i, 1); - dimerCoef->set_elem(0.2, i, 3); - dimerCoef->set_elem(82.4, i, 4); - dimerCoef->set_elem(9.4, i, 5); - dimerCoef->set_elem(3.4, i, 6); - dimerCoef->set_elem(-3.0, i, 8); + Eigen::MatrixXd dimerCoef = Eigen::MatrixXd::Zero(8, 8); + for (int i = 0; i < 8; ++i) { + dimerCoef(i, 0) = 1.3; + dimerCoef(i, 2) = 0.2; + dimerCoef(i, 3) = 82.4; + dimerCoef(i, 4) = 9.4; + dimerCoef(i, 5) = 3.4; + dimerCoef(i, 7) = -3.0; } // Our coefficient matrix should look like this // - // col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 + // col 0 col 1 col 2 col 3 col 4 col 5 col 6 col 7 // _______________________________________________________ + // row 0 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 // row 1 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 // row 2 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 // row 3 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 @@ -32,51 +36,49 @@ int main(void) { // row 5 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 // row 6 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 // row 7 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 - // row 8 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 // atm3 atm1 atm1 atm5 atm4 atm4 atm2 atm2 // Contains the x y and z position of atoms in monomer A - Matrix* coordA = new Matrix(2, 3); + Eigen::MatrixXd coordA(2, 3); // Atom 1 at (1.0,1.0,1.0) // Atom 2 at (0.0,0.0,0.0) - coordA->set_elem(1.0, 1, 1); - coordA->set_elem(1.0, 1, 2); - coordA->set_elem(1.0, 1, 3); + coordA << 1.0, 1.0, 1.0, + 0.0, 0.0, 0.0; // Contains the x y and z position of atoms in monomer B - Matrix* coordB = new Matrix(3, 3); + Eigen::MatrixXd coordB(3, 3); // Atom 3 at (1.0,0.0,0.0) // Atom 4 at (2.0,0.0,0.0) // Atom 5 at (3.0,0.0,0.0) - coordB->set_elem(1.0, 1, 1); - coordB->set_elem(2.0, 2, 1); - coordB->set_elem(3.0, 3, 1); + coordB << 1.0, 0.0, 0.0, + 2.0, 0.0, 0.0, + 3.0, 0.0, 0.0; - Matrix* coordDimer = new Matrix(5, 3); + Eigen::MatrixXd coordDimer(5, 3); // Arrange atoms in the dimer so they do not appear in the // same order as the monomers - // row1 Atom 3 - coordDimer->set_elem(1.0, 1, 1); - // row2 Atom 1 - coordDimer->set_elem(1.0, 2, 1); - coordDimer->set_elem(1.0, 2, 2); - coordDimer->set_elem(1.0, 2, 3); - // row3 Atom 5 - coordDimer->set_elem(3.0, 3, 1); - // row4 Atom 4 - coordDimer->set_elem(2.0, 4, 1); - // row5 Atom 2 (0.0,0.0,0.0) + // Atom 3 1.0, 0.0, 0.0 + // Atom 1 1.0, 1.0, 1.0 + // Atom 5 3.0, 0.0, 0.0 + // Atom 4 2.0, 0.0, 0.0 + // Atom 2 0.0, 0.0, 0.0 + + coordDimer << 1.0, 0.0, 0.0, + 1.0, 1.0, 1.0, + 3.0, 0.0, 0.0, + 2.0, 0.0, 0.0, + 0.0, 0.0, 0.0; - vector matchA = coordA->matchRow(*coordDimer, 2); - vector matchB = coordB->matchRow(*coordDimer, 2); + vector matchA = matchRow(coordA,coordDimer, 2); + vector matchB = matchRow(coordB,coordDimer, 2); - assert(matchA.at(0) == 2); - assert(matchA.at(1) == 5); + assert(matchA.at(0) == 1); + assert(matchA.at(1) == 4); - assert(matchB.at(0) == 1); - assert(matchB.at(1) == 4); - assert(matchB.at(2) == 3); + assert(matchB.at(0) == 0); + assert(matchB.at(1) == 3); + assert(matchB.at(2) == 2); vector basisFuncDimer; // Basis functions per atom @@ -103,8 +105,9 @@ int main(void) { // According to the basis functions and the atom positions the current // coef table for monomer A should look like this - // col 1 col 2 col 3 col 4 + // col 0 col 1 col 2 col 3 // ____________________________ + // row 0 | 0.0 0.2 0.0 -3.0 // row 1 | 0.0 0.2 0.0 -3.0 // row 2 | 0.0 0.2 0.0 -3.0 // row 3 | 0.0 0.2 0.0 -3.0 @@ -112,17 +115,20 @@ int main(void) { // row 5 | 0.0 0.2 0.0 -3.0 // row 6 | 0.0 0.2 0.0 -3.0 // row 7 | 0.0 0.2 0.0 -3.0 - // row 8 | 0.0 0.2 0.0 -3.0 // atm1 atm1 atm2 atm2 cerr << "Before passing in" << endl; + cerr << "MatchA" << endl; for (auto it : matchA) cerr << it << endl; + cerr << "MatchB" << endl; for (auto it : matchB) cerr << it << endl; + cerr << "Basis Functions of Dimer" << endl; for (auto it : basisFuncDimer) cerr << it << endl; // If we correct the dimer coefficient matrix to line up with the // coefficients of the monomers it should look like this // - // Col 1 Col 2 Col 3 Col 4 Col 5 Col 6 Col 7 Col 8 + // Col 0 Col 1 Col 2 Col 3 Col 4 Col 5 Col 6 Col 7 + // Row 0 1.3 9.4 3.4 82.4 0 0.2 0 -3 // Row 1 1.3 9.4 3.4 82.4 0 0.2 0 -3 // Row 2 1.3 9.4 3.4 82.4 0 0.2 0 -3 // Row 3 1.3 9.4 3.4 82.4 0 0.2 0 -3 @@ -130,101 +136,99 @@ int main(void) { // Row 5 1.3 9.4 3.4 82.4 0 0.2 0 -3 // Row 6 1.3 9.4 3.4 82.4 0 0.2 0 -3 // Row 7 1.3 9.4 3.4 82.4 0 0.2 0 -3 - // Row 8 1.3 9.4 3.4 82.4 0 0.2 0 -3 cerr << "Calling unscramble" << endl; - auto NewCoef = unscramble_Coef(matchB, matchA, basisFuncDimer, dimerCoef); - - cerr << *NewCoef << endl; - - for (int i = 1; i <= 8; ++i) { - assert(static_cast(NewCoef->get_elem(i, 1) * 10) == 13); - assert(static_cast(NewCoef->get_elem(i, 2) * 10) == 94); - assert(static_cast(NewCoef->get_elem(i, 3) * 10) == 34); - assert(static_cast(NewCoef->get_elem(i, 4) * 10) == 824); - assert(static_cast(NewCoef->get_elem(i, 5)) == 0); - assert(static_cast(NewCoef->get_elem(i, 6) * 10) == 2); - assert(static_cast(NewCoef->get_elem(i, 7)) == 0); - assert(static_cast(NewCoef->get_elem(i, 8)) == -3); + Eigen::MatrixXd NewCoef = unscramble_Coef(matchB, matchA, basisFuncDimer, dimerCoef); + + cerr << NewCoef << endl; + + for (int i = 0; i < 8; ++i) { + assert(static_cast(NewCoef(i, 0) * 10) == 13); + assert(static_cast(NewCoef(i, 1) * 10) == 94); + assert(static_cast(NewCoef(i, 2) * 10) == 34); + assert(static_cast(NewCoef(i, 3) * 10) == 824); + assert(static_cast(NewCoef(i, 4)) == 0); + assert(static_cast(NewCoef(i, 5) * 10) == 2); + assert(static_cast(NewCoef(i, 6)) == 0); + assert(static_cast(NewCoef(i, 7)) == -3); } } cout << "Testing: unscramble_S_Coef" << endl; { - Matrix* SCoef = new Matrix(8, 8); - for (int i = 1; i <= 8; ++i) { - SCoef->set_elem(1.3, i, 2); - SCoef->set_elem(1.3, i, 3); - SCoef->set_elem(4.0, i, 4); + Eigen::MatrixXd SCoef = Eigen::MatrixXd::Zero(8, 8); + for (int i = 0; i < 8; ++i) { + SCoef(i, 1) = 1.3; + SCoef(i, 2) = 1.3; + SCoef(i, 3) = 4.0; } - for (int i = 1; i <= 8; ++i) { - SCoef->set_elem(1.3, 2, i); - SCoef->set_elem(1.3, 3, i); - SCoef->set_elem(4.0, 4, i); + for (int i = 0; i < 8; ++i) { + SCoef(1, i) = 1.3; + SCoef(2, i) = 1.3; + SCoef(3, i) = 4.0; } - SCoef->set_elem(6.0, 2, 4); - SCoef->set_elem(6.0, 3, 4); - SCoef->set_elem(6.0, 4, 2); - SCoef->set_elem(6.0, 4, 3); + SCoef(1, 3) = 6.0; + SCoef(2, 3) = 6.0; + SCoef(3, 1) = 6.0; + SCoef(3, 2) = 6.0; // Our coefficient matrix should look like this // - // col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 + // col 0 col 1 col 2 col 3 col 4 col 5 col 6 col 7 // _______________________________________________________ - // atm 3 row 1 | 0.0 1.3 1.3 4.0 0.0 0.0 0.0 0.0 + // atm 3 row 0 | 0.0 1.3 1.3 4.0 0.0 0.0 0.0 0.0 + // atm 1 row 1 | 1.3 1.3 1.3 6.0 1.3 1.3 1.3 1.3 // atm 1 row 2 | 1.3 1.3 1.3 6.0 1.3 1.3 1.3 1.3 - // atm 1 row 3 | 1.3 1.3 1.3 6.0 1.3 1.3 1.3 1.3 - // atm 5 row 4 | 4.0 6.0 6.0 4.0 4.0 4.0 4.0 4.0 + // atm 5 row 3 | 4.0 6.0 6.0 4.0 4.0 4.0 4.0 4.0 + // atm 4 row 4 | 0.0 1.3 1.3 4.0 0.0 0.0 0.0 0.0 // atm 4 row 5 | 0.0 1.3 1.3 4.0 0.0 0.0 0.0 0.0 - // atm 4 row 6 | 0.0 1.3 1.3 4.0 0.0 0.0 0.0 0.0 + // atm 2 row 6 | 0.0 1.3 1.3 4.0 0.0 0.0 0.0 0.0 // atm 2 row 7 | 0.0 1.3 1.3 4.0 0.0 0.0 0.0 0.0 - // atm 2 row 8 | 0.0 1.3 1.3 4.0 0.0 0.0 0.0 0.0 // atm3 atm1 atm1 atm5 atm4 atm4 atm2 atm2 // Contains the x y and z position of atoms in monomer A - Matrix* coordA = new Matrix(2, 3); + Eigen::MatrixXd coordA(2, 3); // Atom 1 at (1.0,1.0,1.0) // Atom 2 at (0.0,0.0,0.0) - coordA->set_elem(1.0, 1, 1); - coordA->set_elem(1.0, 1, 2); - coordA->set_elem(1.0, 1, 3); + coordA << 1.0, 1.0, 1.0, + 0.0, 0.0, 0.0; // Contains the x y and z position of atoms in monomer B - Matrix* coordB = new Matrix(3, 3); + Eigen::MatrixXd coordB(3, 3); // Atom 3 at (1.0,0.0,0.0) // Atom 4 at (2.0,0.0,0.0) // Atom 5 at (3.0,0.0,0.0) - coordB->set_elem(1.0, 1, 1); - coordB->set_elem(2.0, 2, 1); - coordB->set_elem(3.0, 3, 1); + coordB << 1.0, 0.0, 0.0, + 2.0, 0.0, 0.0, + 3.0, 0.0, 0.0; - Matrix* coordDimer = new Matrix(5, 3); + Eigen::MatrixXd coordDimer = Eigen::MatrixXd::Zero(5, 3); // Arrange atoms in the dimer so they do not appear in the // same order as the monomers // row1 Atom 3 - coordDimer->set_elem(1.0, 1, 1); + coordDimer(0, 0) = 1.0; // row2 Atom 1 - coordDimer->set_elem(1.0, 2, 1); - coordDimer->set_elem(1.0, 2, 2); - coordDimer->set_elem(1.0, 2, 3); + coordDimer(1, 0) = 1.0; + coordDimer(1, 1) = 1.0; + coordDimer(1, 2) = 1.0; // row3 Atom 5 - coordDimer->set_elem(3.0, 3, 1); + coordDimer(2, 0) = 3.0; // row4 Atom 4 - coordDimer->set_elem(2.0, 4, 1); + coordDimer(3, 0) = 2.0; // row5 Atom 2 (0.0,0.0,0.0) - vector matchA = coordA->matchRow(*coordDimer, 2); - vector matchB = coordB->matchRow(*coordDimer, 2); + vector matchA = matchRow(coordA,coordDimer, 2); + vector matchB = matchRow(coordB,coordDimer, 2); - assert(matchA.at(0) == 2); - assert(matchA.at(1) == 5); + assert(matchA.at(0) == 1); + assert(matchA.at(1) == 4); - assert(matchB.at(0) == 1); - assert(matchB.at(1) == 4); - assert(matchB.at(2) == 3); + assert(matchB.at(0) == 0); + assert(matchB.at(1) == 3); + assert(matchB.at(2) == 2); vector basisFuncDimer; // Basis functions per atom @@ -256,39 +260,38 @@ int main(void) { // If we correct the dimer coefficient matrix to line up with the // coefficients of the monomers it should look like this // - // Col 1 Col 2 Col 3 Col 4 Col 5 Col 6 Col 7 Col 8 + // Col 0 Col 1 Col 2 Col 3 Col 4 Col 5 Col 6 Col 7 + // Row 0 0 0 0 4 1.3 1.3 0 0 // Row 1 0 0 0 4 1.3 1.3 0 0 // Row 2 0 0 0 4 1.3 1.3 0 0 - // Row 3 0 0 0 4 1.3 1.3 0 0 - // Row 4 4 4 4 4 6 6 4 4 + // Row 3 4 4 4 4 6 6 4 4 + // Row 4 1.3 1.3 1.3 6 1.3 1.3 1.3 1.3 // Row 5 1.3 1.3 1.3 6 1.3 1.3 1.3 1.3 - // Row 6 1.3 1.3 1.3 6 1.3 1.3 1.3 1.3 + // Row 6 0 0 0 4 1.3 1.3 0 0 // Row 7 0 0 0 4 1.3 1.3 0 0 - // Row 8 0 0 0 4 1.3 1.3 0 0 cerr << "Calling unscramble" << endl; - auto NewCoef = unscramble_S(matchB, matchA, basisFuncDimer, SCoef); + Eigen::MatrixXd NewCoef = unscramble_S(matchB, matchA, basisFuncDimer, SCoef); - cerr << *NewCoef << endl; + cerr << NewCoef << endl; - for (int i = 1; i <= 8; ++i) { - if (i != 4) { - assert(static_cast(NewCoef->get_elem(i, 5) * 10) == 13); - assert(static_cast(NewCoef->get_elem(i, 6) * 10) == 13); + for (int i = 0; i < 8; ++i) { + if (i != 3) { + assert(static_cast(NewCoef(i, 4) * 10) == 13); + assert(static_cast(NewCoef(i, 5) * 10) == 13); - assert(static_cast(NewCoef->get_elem(5, i) * 10) == 13); - assert(static_cast(NewCoef->get_elem(6, i) * 10) == 13); + assert(static_cast(NewCoef(4, i) * 10) == 13); + assert(static_cast(NewCoef(5, i) * 10) == 13); } } - for (int i = 1; i <= 8; ++i) { - if (i == 5 || i == 6) { - assert(static_cast(NewCoef->get_elem(i, 4)) == 6); - assert(static_cast(NewCoef->get_elem(4, i)) == 6); + for (int i = 0; i < 8; ++i) { + if (i == 4 || i == 5) { + assert(static_cast(NewCoef(i, 3)) == 6); + assert(static_cast(NewCoef(3, i)) == 6); } else { - assert(static_cast(NewCoef->get_elem(4, i)) == 4); - assert(static_cast(NewCoef->get_elem(i, 4)) == 4); + assert(static_cast(NewCoef(3, i)) == 4); + assert(static_cast(NewCoef(i, 3)) == 4); } } } - return 0; } diff --git a/src/tests/test_script_calc_J.sh b/src/tests/test_script_calc_J.sh old mode 100644 new mode 100755 index a84363e..be21925 --- a/src/tests/test_script_calc_J.sh +++ b/src/tests/test_script_calc_J.sh @@ -1,7 +1,7 @@ #!/bin/bash if [ $# -eq 0 ]; then - path="./../" + path="./.." else path=$1 fi @@ -29,7 +29,7 @@ findJeff() { echo "Num array "${#values[@]} for (( i=0; i < ${#values[@]}; i++ )) do - if [ "${values[$i]}" == "J_eff" ] + if [ "${values[$i]}" == "J_ab_eff_single" ] then J_val=${values[$i+1]} break @@ -222,6 +222,26 @@ else fi echo $data >> $fileOut +# Note the only difference in this test is that we have switched p_1 and p_2 +# because the program auto matches the right basis function coordinates with +# the right atoms you should end up with the same numbers. +exec_command="${path}/build/calc_J -p_P ${path}/GAUSSIANFILES/CuBr2_Py/CuBr2-Py.pun -p_2 ${path}/GAUSSIANFILES/CuBr2_Py/CuBr2.pun -p_1 ${path}/GAUSSIANFILES/CuBr2_Py/Py.pun" +data=$(${exec_command}) +if [ $? -eq 0 ]; then + findJeff + if (( $(bc <<< "$J_val > -0.0055" ) )) && (( $(bc <<< "$J_val < -0.0053" ) )) + then + echo "${green}[SUCCESS]${reset} ${exec_command}" + else + echo "${red}[FAILURE]${reset} ${exec_command} expected output -0.00542741" + echo "actual output $J_val" + count_fails=$(($count_fails+1)) + fi +else + echo "${red}[FAILURE]${reset} ${exec_command}" + count_fails=$((count_fails+1)) +fi +echo $data >> $fileOut # The following commands should not work diff --git a/src/tests/test_string_support.cpp b/src/tests/test_string_support.cpp index b1f1204..dceedf6 100644 --- a/src/tests/test_string_support.cpp +++ b/src/tests/test_string_support.cpp @@ -1,4 +1,6 @@ +#define CATCH_CONFIG_MAIN +#include #include "../libcatnip/string_support.hpp" #include #include @@ -8,7 +10,7 @@ using namespace catnip; using namespace std; -int main(void) { +TEST_CASE("String Support","[unit]") { cerr << "Testing: splitSt" << endl; { @@ -103,5 +105,4 @@ int main(void) { assert(str3.compare(str) == 0); } - return 0; } diff --git a/src/tests/test_swap_engine.cpp b/src/tests/test_swap_engine.cpp new file mode 100644 index 0000000..fa1d9b9 --- /dev/null +++ b/src/tests/test_swap_engine.cpp @@ -0,0 +1,389 @@ + +#define CATCH_CONFIG_MAIN +#include + +// Local private includes +#include "swap_engine.hpp" + +#include "atom.hpp" +#include "atom_group_container.hpp" +#include "atom_system.hpp" +#include "basis_map.hpp" +#include "elements.hpp" + +// Third party includes +#include + +// Standard includes +#include +#include + +using namespace catnip; + +/** + * @brief In this test some of the atoms added to the complex will be added + * in a different order from how they were added to each of the components + * + * @param Scrambled" + * @param "[integration]" + */ +TEST_CASE("Basis Map Scrambled","[integration]") { + + std::vector basis_comp1{ 1, 1, 4}; + std::vector basis_comp2{ 5, 5}; + + Atom atom1(Element::H, 0.0, 0.0, 0.0); + Atom atom2(Element::H, 2.0, 0.0, 0.0); + Atom atom3(Element::C, 1.0, 1.0, 0.0); + Atom atom4(Element::O, 3.3, 4.3, 0.0); + Atom atom5(Element::O, 3.0, 3.9, 0.0); + + auto atom1_ptr = std::make_shared(atom1); + auto atom2_ptr = std::make_shared(atom2); + auto atom3_ptr = std::make_shared(atom3); + auto atom4_ptr = std::make_shared(atom4); + auto atom5_ptr = std::make_shared(atom5); + + // Extra atoms are allowed in the complex but not in the componets + auto component1 = std::make_unique("CH2"); + component1->add(atom1_ptr); + component1->add(atom2_ptr); + component1->add(atom3_ptr); + + auto component2 = std::make_unique("O2"); + component2->add(atom4_ptr); + component2->add(atom5_ptr); + + // HERE: the order has been changed + auto complex1 = std::make_unique("O2CH2"); + complex1->add(atom4_ptr); // The basis functions of atom 4 : 0 - 4 + complex1->add(atom1_ptr); // The basis functions of atom 1 : 5 - 5 + complex1->add(atom3_ptr); // The basis functions of atom 3 : 6 - 9 + complex1->add(atom5_ptr); // The basis functions of atom 5 : 10 - 14 + complex1->add(atom2_ptr); // The basis functions of atom 2 : 15 - 15 + + auto atom_grp_cont = std::unique_ptr(new AtomGroupContainer); + atom_grp_cont->add(std::move(component1)); + atom_grp_cont->add(std::move(component2)); + atom_grp_cont->add(std::move(complex1)); + + AtomSystem atm_sys(std::move(atom_grp_cont)); + + int index_component1 = 0; + int index_component2 = 1; + atm_sys.assignBasisFunctions( index_component1, basis_comp1); + atm_sys.assignBasisFunctions( index_component2, basis_comp2); + + BasisMap basis_map(atm_sys); + +} + +TEST_CASE("QC Functions","[integration]") { + + std::cout << "Testing: unscramble_Coef" << std::endl; + { + Eigen::MatrixXd dimerCoef = Eigen::MatrixXd::Zero(8, 8); + for (int i = 0; i < 8; ++i) { + dimerCoef(i, 0) = 1.3; + dimerCoef(i, 2) = 0.2; + dimerCoef(i, 3) = 82.4; + dimerCoef(i, 4) = 9.4; + dimerCoef(i, 5) = 3.4; + dimerCoef(i, 7) = -3.0; + } + + // Our coefficient matrix should look like this + // + // col 0 col 1 col 2 col 3 col 4 col 5 col 6 col 7 + // _______________________________________________________ + // row 0 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 + // row 1 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 + // row 2 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 + // row 3 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 + // row 4 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 + // row 5 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 + // row 6 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 + // row 7 | 1.3 0.0 0.2 82.4 9.4 3.4 0.0 -3.0 + // atm3 atm1 atm1 atm5 atm4 atm4 atm2 atm2 + + Atom atom1(Element::H, 1.0, 1.0, 1.0); + Atom atom2(Element::H, 0.0, 0.0, 0.0); + + auto atom1_ptr = std::make_shared(atom1); + auto atom2_ptr = std::make_shared(atom2); + + auto componentA = std::make_unique("A"); + componentA->add(atom1_ptr); + componentA->add(atom2_ptr); + + Atom atom3(Element::C, 1.0, 0.0, 0.0); + Atom atom4(Element::O, 2.0, 0.0, 0.0); + Atom atom5(Element::O, 3.0, 0.0, 0.0); + + auto atom3_ptr = std::make_shared(atom3); + auto atom4_ptr = std::make_shared(atom4); + auto atom5_ptr = std::make_shared(atom5); + + auto componentB = std::make_unique("B"); + componentB->add(atom3_ptr); + componentB->add(atom4_ptr); + componentB->add(atom5_ptr); + + // Arrange atoms in the dimer so they do not appear in the + // same order as the monomers + + // Atom 3 1->0, 0->0, 0->0 + // Atom 1 1->0, 1->0, 1->0 + // Atom 5 3->0, 0->0, 0->0 + // Atom 4 2->0, 0->0, 0->0 + // Atom 2 0->0, 0->0, 0->0 + + auto complexAB = std::make_unique("AB"); + complexAB->add(atom3_ptr); + complexAB->add(atom1_ptr); + complexAB->add(atom5_ptr); + complexAB->add(atom4_ptr); + complexAB->add(atom2_ptr); + + // Combine atom groups + auto atom_grp_cont = std::unique_ptr(new AtomGroupContainer); + atom_grp_cont->add(std::move(componentA)); + atom_grp_cont->add(std::move(componentB)); + atom_grp_cont->add(std::move(complexAB)); + + // Basis functions per atom + // + // Atom 1 2 + // Atom 2 2 + // Atom 3 1 + // Atom 4 2 + // Atom 5 1 + + // According to the dimer coordinates they will appear in the following + // order + // Atom 3 1 + // Atom 1 2 + // Atom 5 1 + // Atom 4 2 + // Atom 2 2 + + std::vector basisFuncDimer; + basisFuncDimer.push_back(1); + basisFuncDimer.push_back(2); + basisFuncDimer.push_back(1); + basisFuncDimer.push_back(2); + basisFuncDimer.push_back(2); + + AtomSystem atm_sys(std::move(atom_grp_cont)); + + // Assign the basis functions to the atoms that are in the complex + int index_complex = 2; + atm_sys.assignBasisFunctions( index_complex, basisFuncDimer); + BasisMap basis_map(atm_sys); + + // According to the basis functions and the atom positions the current + // coef table for monomer A should look like this + // col 0 col 1 col 2 col 3 + // ____________________________ + // row 0 | 0.0 0.2 0.0 -3.0 + // row 1 | 0.0 0.2 0.0 -3.0 + // row 2 | 0.0 0.2 0.0 -3.0 + // row 3 | 0.0 0.2 0.0 -3.0 + // row 4 | 0.0 0.2 0.0 -3.0 + // row 5 | 0.0 0.2 0.0 -3.0 + // row 6 | 0.0 0.2 0.0 -3.0 + // row 7 | 0.0 0.2 0.0 -3.0 + // atm1 atm1 atm2 atm2 + + auto swap_eng = SwapEngine(basis_map); + + std::cout << "Before arranging dimer coef" << std::endl; + std::cout << dimerCoef << std::endl; + + swap_eng.arrangeCols(dimerCoef); + + std::cout << "Expected output" << std::endl; + std::cout << " Col 1 Col 1 Col 2 Col 3 Col 4 Col 5 Col 6 Col 7 " << std::endl; + std::cout << "Row 0 0.0 0.2 0.0 -3.0 1.3 9.4 3.4 82.4" << std::endl; + std::cout << "Row 1 0.0 0.2 0.0 -3.0 1.3 9.4 3.4 82.4" << std::endl; + std::cout << "Row 2 0.0 0.2 0.0 -3.0 1.3 9.4 3.4 82.4" << std::endl; + std::cout << "Row 3 0.0 0.2 0.0 -3.0 1.3 9.4 3.4 82.4" << std::endl; + std::cout << "Row 4 0.0 0.2 0.0 -3.0 1.3 9.4 3.4 82.4" << std::endl; + std::cout << "Row 5 0.0 0.2 0.0 -3.0 1.3 9.4 3.4 82.4" << std::endl; + std::cout << "Row 6 0.0 0.2 0.0 -3.0 1.3 9.4 3.4 82.4" << std::endl; + std::cout << "Row 7 0.0 0.2 0.0 -3.0 1.3 9.4 3.4 82.4" << std::endl; + + std::cout << "After arranging dimer coef" << std::endl; + std::cout << dimerCoef << std::endl; + + for (int i = 0; i < 8; ++i) { + REQUIRE(dimerCoef(i, 0) == Approx(0.0)); + REQUIRE(dimerCoef(i, 1) == Approx(0.2)); + REQUIRE(dimerCoef(i, 2) == Approx(0.0)); + REQUIRE(dimerCoef(i, 3) == Approx(-3.0)); + REQUIRE(dimerCoef(i, 4) == Approx(1.3)); + REQUIRE(dimerCoef(i, 5) == Approx(9.4)); + REQUIRE(dimerCoef(i, 6) == Approx(3.4)); + REQUIRE(dimerCoef(i, 7) == Approx(82.4)); + } + } + + std::cout << "Testing: unscramble SCoef" << std::endl; + { + Eigen::MatrixXd SCoef = Eigen::MatrixXd::Zero(8, 8); + for (int i = 0; i < 8; ++i) { + SCoef(i, 1) = 1.3; + SCoef(i, 2) = 1.3; + SCoef(i, 3) = 4.0; + } + + for (int i = 0; i < 8; ++i) { + SCoef(1, i) = 1.3; + SCoef(2, i) = 1.3; + SCoef(3, i) = 4.0; + } + + SCoef(1, 3) = 6.0; + SCoef(2, 3) = 6.0; + SCoef(3, 1) = 6.0; + SCoef(3, 2) = 6.0; + + // Our coefficient matrix should look like this + // + // col 0 col 1 col 2 col 3 col 4 col 5 col 6 col 7 + // _______________________________________________________ + // atm 3 row 0 | 0.0 1.3 1.3 4.0 0.0 0.0 0.0 0.0 + // atm 1 row 1 | 1.3 1.3 1.3 6.0 1.3 1.3 1.3 1.3 + // atm 1 row 2 | 1.3 1.3 1.3 6.0 1.3 1.3 1.3 1.3 + // atm 5 row 3 | 4.0 6.0 6.0 4.0 4.0 4.0 4.0 4.0 + // atm 4 row 4 | 0.0 1.3 1.3 4.0 0.0 0.0 0.0 0.0 + // atm 4 row 5 | 0.0 1.3 1.3 4.0 0.0 0.0 0.0 0.0 + // atm 2 row 6 | 0.0 1.3 1.3 4.0 0.0 0.0 0.0 0.0 + // atm 2 row 7 | 0.0 1.3 1.3 4.0 0.0 0.0 0.0 0.0 + // atm3 atm1 atm1 atm5 atm4 atm4 atm2 atm2 + + // Contains the x y and z position of atoms in monomer A + Atom atom1(Element::H, 1.0, 1.0, 1.0); + Atom atom2(Element::H, 0.0, 0.0, 0.0); + + auto atom1_ptr = std::make_shared(atom1); + auto atom2_ptr = std::make_shared(atom2); + + auto componentB = std::make_unique("B"); + componentB->add(atom1_ptr); + componentB->add(atom2_ptr); + + // Contains the x y and z position of atoms in monomer B + Atom atom3(Element::C, 1.0, 0.0, 0.0); + Atom atom4(Element::O, 2.0, 0.0, 0.0); + Atom atom5(Element::O, 3.0, 0.0, 0.0); + + auto atom3_ptr = std::make_shared(atom3); + auto atom4_ptr = std::make_shared(atom4); + auto atom5_ptr = std::make_shared(atom5); + + auto componentA = std::make_unique("A"); + componentA->add(atom3_ptr); + componentA->add(atom4_ptr); + componentA->add(atom5_ptr); + + // Positions of atoms in the complex + auto complexAB = std::make_unique("AB"); + complexAB->add(atom3_ptr); + complexAB->add(atom1_ptr); + complexAB->add(atom5_ptr); + complexAB->add(atom4_ptr); + complexAB->add(atom2_ptr); + + // Combine atom groups + auto atom_grp_cont = std::unique_ptr(new AtomGroupContainer); + atom_grp_cont->add(std::move(componentA)); + atom_grp_cont->add(std::move(componentB)); + atom_grp_cont->add(std::move(complexAB)); + + AtomSystem atm_sys(std::move(atom_grp_cont)); + + // Basis functions per atom + // + // Atom 1 2 + // Atom 2 2 + // Atom 3 1 + // Atom 4 2 + // Atom 5 1 + + // According to the dimer coordinates they will appear in the following + // order + // Atom 3 1 + // Atom 1 2 + // Atom 5 1 + // Atom 4 2 + // Atom 2 2 + + std::vector basisFuncDimer; + basisFuncDimer.push_back(1); + basisFuncDimer.push_back(2); + basisFuncDimer.push_back(1); + basisFuncDimer.push_back(2); + basisFuncDimer.push_back(2); + + // Assign the basis functions to the atoms that are in the complex + int index_complex = 2; + atm_sys.assignBasisFunctions( index_complex, basisFuncDimer); + BasisMap basis_map(atm_sys); + + // If we correct the dimer coefficient matrix to line up with the + // coefficients of the monomers it should look like this + // + // Col 0 Col 1 Col 2 Col 3 Col 4 Col 5 Col 6 Col 7 + // Row 0 0 0 0 4 1.3 1.3 0 0 + // Row 1 0 0 0 4 1.3 1.3 0 0 + // Row 2 0 0 0 4 1.3 1.3 0 0 + // Row 3 4 4 4 4 6 6 4 4 + // Row 4 1.3 1.3 1.3 6 1.3 1.3 1.3 1.3 + // Row 5 1.3 1.3 1.3 6 1.3 1.3 1.3 1.3 + // Row 6 0 0 0 4 1.3 1.3 0 0 + // Row 7 0 0 0 4 1.3 1.3 0 0 + // atm3 atm4 atm3 atm5 atm1 atm1 atm2 atm2 + + auto swap_eng = SwapEngine(basis_map); + + std::cout << "Before arranging S" << std::endl; + std::cout << SCoef << std::endl; + + swap_eng.arrange(SCoef); + + std::cout << "Expected output" << std::endl; + std::cout << " Col 1 Col 1 Col 2 Col 3 Col 4 Col 5 Col 6 Col 7 " << std::endl; + std::cout << "Row 0 0 0 0 4 1.3 1.3 0 0 " << std::endl; + std::cout << "Row 1 0 0 0 4 1.3 1.3 0 0 " << std::endl; + std::cout << "Row 2 0 0 0 4 1.3 1.3 0 0 " << std::endl; + std::cout << "Row 3 4 4 4 4 6 6 4 4 " << std::endl; + std::cout << "Row 4 1.3 1.3 1.3 6 1.3 1.3 1.3 1.3" << std::endl; + std::cout << "Row 5 1.3 1.3 1.3 6 1.3 1.3 1.3 1.3" << std::endl; + std::cout << "Row 6 0 0 0 4 1.3 1.3 0 0 " << std::endl; + std::cout << "Row 7 0 0 0 4 1.3 1.3 0 0 " << std::endl; + + std::cout << "After arranging dimer coef" << std::endl; + std::cout << SCoef << std::endl; + + for (int i = 0; i < 8; ++i) { + if (i != 3) { + REQUIRE(SCoef(i, 4) == Approx(1.3)); + REQUIRE(SCoef(i, 5) == Approx(1.3)); + + REQUIRE(SCoef(4, i) == Approx(1.3)); + REQUIRE(SCoef(5, i) == Approx(1.3)); + } + } + + for (int i = 0; i < 8; ++i) { + if (i == 4 || i == 5) { + REQUIRE(SCoef(i, 3) == Approx(6)); + REQUIRE(SCoef(3, i) == Approx(6)); + } else { + REQUIRE(SCoef(3, i) == Approx(4)); + REQUIRE(SCoef(i, 3) == Approx(4)); + } + } + } +} diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt new file mode 100644 index 0000000..6727ec3 --- /dev/null +++ b/src/tools/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(calcJ calcJ.cpp) +target_link_libraries(calcJ libcatnip) +install(TARGETS calcJ EXPORT CATNIP_Targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +add_executable(CATNIP::calcJ ALIAS calcJ) +set_property(TARGET libcatnip APPEND PROPERTY BINARIES "calcJ") diff --git a/src/tools/main.cpp b/src/tools/calcJ.cpp similarity index 74% rename from src/tools/main.cpp rename to src/tools/calcJ.cpp index be9d395..7ee0c62 100644 --- a/src/tools/main.cpp +++ b/src/tools/calcJ.cpp @@ -1,11 +1,11 @@ -#include +/*#include #include #include #include #include -#include +#include */ #include -#include +/*#include #include #include #include @@ -16,20 +16,22 @@ #include "../libcatnip/io/file_readers/logreader.hpp" #include "../libcatnip/io/file_readers/punreader.hpp" #include "../libcatnip/io/io.hpp" -#include "../libcatnip/log.hpp" -#include "../libcatnip/matrix.hpp" #include "../libcatnip/parameters.hpp" #include "../libcatnip/qc_functions.hpp" +#include "../libcatnip/matrix.hpp"*/ +#include "catnip_config.hpp" +#include "log.hpp" -#include "../libcatnip/calcJconfig.hpp" +#include using namespace catnip; using namespace std; int main(int argc, const char *argv[]) { cout << endl; - cout << "Running calc_J VERSION " << calcJ_VERSION_MAJOR << "."; - cout << calcJ_VERSION_MINOR << endl; + cout << "Running calc_J VERSION " << catnip_VERSION_MAJOR << "."; + cout << catnip_VERSION_MINOR << "." << endl; + cout << catnip_VERSION_PATCH << "." << endl; string line; LOG("Preparing parser", 1); @@ -47,7 +49,7 @@ int main(int argc, const char *argv[]) { cout << "pun file for the dimer is: " + par->getPunP() + '\n'; // Open the .pun file find the total number of molecular orbitals - +/* LOG("Reading pun files", 1); LOG("Reading pun file: " + par->getPunP(), 2); PunReader pr_P(par->getPunP()); @@ -77,23 +79,21 @@ int main(int argc, const char *argv[]) { // No need to worry about beta orbitals { - Matrix *mat_S = lr_P.getOverlapMatrix(); + Eigen::MatrixXd mat_S = lr_P.getOverlapMatrix(); - Matrix *mat_P_Coef = pr_P.getCoefsMatrix(par->getSpinP()); - auto vec_P_OE = lr_P.getOE(par->getSpinP()); - Matrix *mat_P_OE = new Matrix(vec_P_OE); + Eigen::MatrixXd mat_P_Coef = pr_P.getCoefsMatrix(par->getSpinP()); + + Eigen::VectorXd vec_P_OE = Eigen::VectorXd(lr_P.getOE(par->getSpinP())); int HOMO1 = lr_1.getHOMOLevel(par->getSpin1()); LOG("Getting " + par->getSpin1() + " of monomer 1", 2); - Matrix *mat_1_Coef = pr_1.getCoefsMatrix(par->getSpin1()); - auto vec_1_OE = lr_1.getOE(par->getSpin1()); - Matrix *mat_1_OE = new Matrix(vec_1_OE); + Eigen::MatrixXd mat_1_Coef = pr_1.getCoefsMatrix(par->getSpin1()); + Eigen::VectorXd vec_1_OE = lr_1.getOE(par->getSpin1()); int HOMO2 = lr_2.getHOMOLevel(par->getSpin2()); LOG("Getting " + par->getSpin2() + " of monomer 2", 2); - Matrix *mat_2_Coef = pr_2.getCoefsMatrix(par->getSpin2()); - auto vec_2_OE = lr_2.getOE(par->getSpin2()); - Matrix *mat_2_OE = new Matrix(vec_2_OE); + Eigen::MatrixXd mat_2_Coef = pr_2.getCoefsMatrix(par->getSpin2()); + Eigen::VectorXd vec_2_OE = lr_2.getOE(par->getSpin2()); // Unscramble dimer coef and energies first need to see how the dimer // and monomer coefficients line up. To determine how the ceofficients @@ -103,37 +103,30 @@ int main(int argc, const char *argv[]) { // the position of the atoms in the monomer unit and the positions of // the atoms in the dimer we can determine how the coefficients need // to be rearranged. - auto coord_P = lr_P.getCoords(); - auto coord_1 = lr_1.getCoords(); - auto coord_2 = lr_2.getCoords(); + vector> coord_P = lr_P.getCoords(); + vector> coord_1 = lr_1.getCoords(); + vector> coord_2 = lr_2.getCoords(); // Convert coords to matrices - Matrix coord_P_mat(coord_P); - Matrix coord_1_mat(coord_1); - Matrix coord_2_mat(coord_2); - - auto basis_P = lr_P.getBasisFuncCount(); - auto basis_1 = lr_1.getBasisFuncCount(); - auto basis_2 = lr_2.getBasisFuncCount(); + Eigen::MatrixXd coord_P_mat = convert(coord_P); + Eigen::MatrixXd coord_1_mat = convert(coord_1); + Eigen::MatrixXd coord_2_mat = convert(coord_2); - int MO1 = mat_1_OE->get_rows(); - int MO2 = mat_2_OE->get_rows(); - - pair Orbs1 = {MO1, HOMO1}; - pair Orbs2 = {MO2, HOMO2}; + vector basis_P = lr_P.getBasisFuncCount(); + vector basis_1 = lr_1.getBasisFuncCount(); + vector basis_2 = lr_2.getBasisFuncCount(); LOG("Creating transfercomplex", 1); - TransferComplex TC(mat_1_Coef, mat_2_Coef, mat_P_Coef, Orbs1, Orbs2, mat_S, - mat_P_OE, par->getCounterPoise()); + TransferComplex TC(mat_1_Coef, mat_2_Coef, mat_P_Coef, HOMO1, HOMO2, mat_S, + vec_P_OE, par->getCounterPoise()); // Set the transfer complex to counterpoise if it is the case. - // If the basis function search returns 0 for any of the components then // we cannot automatically determine what the transfer integral is if (basis_1.size() != 0 && basis_2.size() != 0 && basis_P.size() != 0) { LOG("Unscrambling matrices", 1); TC.unscramble(coord_1_mat, coord_2_mat, coord_P_mat, basis_P, basis_2); - } + } cout << endl; cout << "Dimer Spin " << par->getSpinP() << endl; @@ -168,8 +161,13 @@ int main(int argc, const char *argv[]) { orbitalnums["mon2"] = par->getOrbNum2(); LOG("Calculating transfer integral", 1); - TC.calcJ(orbitaltypes, orbitalnums); + TC.calcJ(); + if(par->getPrintSwitch()){ + TC.printAll(); + }else{ + TC.printTransferIntegral(orbitaltypes, orbitalnums); + } } - +*/ return 0; }