diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5c3a85e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,92 @@ +cmake_minimum_required(VERSION 3.18) +project(cpp-d4) +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + +if(NOT DEFINED D4LIBS_DIR AND NOT DEFINED D4INCLUDE_DIR) + find_package(LAPACKE REQUIRED) + find_package(CBLAS CONFIG REQUIRED) +endif(NOT DEFINED D4LIBS_DIR AND NOT DEFINED D4INCLUDE_DIR) + + +IF(CMAKE_COMPILER_IS_GNUCXX) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-reorder -pedantic \ + -Wextra -Wcast-align -Wcast-qual -Wchar-subscripts \ + -Wcomment -Wdisabled-optimization \ + -Wformat -Wformat=2 -Wformat-nonliteral -Wformat-security\ + -Wformat-y2k -Wimport -Winit-self -Winline -Winvalid-pch\ + -Wunsafe-loop-optimizations -Wmissing-braces\ + -Wmissing-field-initializers -Wmissing-format-attribute \ + -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wparentheses\ + -Wpointer-arith -Wredundant-decls -Wsequence-point\ + -Wsign-compare -Wstack-protector -Wstrict-aliasing\ + -Wstrict-aliasing=2 -Wswitch -Wsuggest-override\ + -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunreachable-code\ + -Wunused -Wunused-function -Wunused-label -Wunused-parameter\ + -Wunused-value -Wunused-variable -Wvariadic-macros\ + -Wvolatile-register-var -Wwrite-strings -Wdeprecated-declarations\ + -Wno-error=unused-local-typedefs -Wno-error=enum-compare -Wno-narrowing -Werror=return-type -g") +set (GCC ON) +if(WIN32) # Check if we are on Windows +else() + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic") +endif(WIN32) +ENDIF(CMAKE_COMPILER_IS_GNUCXX) + +include_directories(${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR} ) +if(DEFINED D4LIBS_DIR AND DEFINED D4INCLUDE_DIR) + include_directories(${D4INCLUDE_DIR}) +endif(DEFINED D4LIBS_DIR AND DEFINED D4INCLUDE_DIR) + + +set(cpp_d4_SRC + src/damping/atm.cpp + src/damping/rational.cpp + src/dftd_cutoff.cpp + src/dftd_damping.cpp + src/dftd_dispersion.cpp + src/dftd_eeq.cpp + src/dftd_model.cpp + src/dftd_ncoord.cpp + src/dftd_readxyz.cpp + ) + +add_library(libcpp_d4 ${cpp_d4_SRC}) + +add_executable(cpp-d4 + src/program_dftd.cpp +) + +add_executable(cpp-d4_test + test/main.cpp + test/test_grad.cpp + test/molecules.cpp + test/test_disp.cpp + test/test_disp2.cpp + test/test_ncoord.cpp + test/test_param.cpp + test/util.cpp +) + +if(DEFINED D4LIBS_DIR AND DEFINED D4INCLUDE_DIR) + link_directories(${D4LIBS_DIR}) + + target_link_libraries(cpp-d4 libcpp_d4 cblas lapacke pthread) + target_link_libraries(cpp-d4_test libcpp_d4 cblas lapacke pthread) +else() + target_link_libraries(cpp-d4 libcpp_d4 ${LAPACKE_LIBRARIES} ${CBLAS_LIBRARIES} pthread) + target_link_libraries(cpp-d4_test libcpp_d4 ${LAPACKE_LIBRARIES} ${CBLAS_LIBRARIES} pthread) +endif(DEFINED D4LIBS_DIR AND DEFINED D4INCLUDE_DIR) + +include(CTest) + +add_test(NAME disp2 COMMAND cpp-d4_test disp) +add_test(NAME disp COMMAND cpp-d4_test disp) +add_test(NAME grad COMMAND cpp-d4_test grad) +add_test(NAME ncoord COMMAND cpp-d4_test ncoord) +add_test(NAME param COMMAND cpp-d4_test param) + + +if(WIN32) # Check if we are on Windows +else() + target_link_libraries(cpp-d4 dl ) +endif(WIN32) diff --git a/README.md b/README.md index 9acae29..d0e9243 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,11 @@ This project is a port of the [`dftd4`](https://github.com/dftd4/dftd4) project to C++ and provides the D4(EEQ)-ATM method. -## Building This Project +## Requirements +cpp-d4 depends on cblas and lapacke, the C implementation of blas and lapack. + +## Building This Project This project is build with `meson`, to setup and perform a build run: ```bash @@ -21,6 +24,45 @@ Run the test suite with: meson test -C _build --print-errorlogs ``` +In addition to `meson`, one can use CMake to build cpp-d4 and include it into external projects (see for example [https://github.com/conradhuebler/curcuma](https://github.com/conradhuebler/curcuma)). + +```bash +cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo .. +make +``` +The tests can be started with + +```bash +make test +``` +In case, cblas and lapacke can not be found using cmake (which for example happens on Ubuntu), one can specify one include and library path for both dependencies. + +```bash +cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo .. -DD4LIBS_DIR=/usr/lib/ -DD4INCLUDE_DIR=/usr/include/ +``` + +```bash +cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo .. -DD4LIBS_DIR=$(find /usr -name 'cblas.so' |head -n1 |sed 's/cblas.so//g') -DD4INCLUDE_DIR=$(find /usr -name 'cblas.h' |head -n1 |sed 's/cblas.h//g') +``` + +Using CMake it is then easy to include cpp-d4 in an own project. + +```cmake +if(NOT DEFINED D4LIBS_DIR AND NOT DEFINED D4INCLUDE_DIR) + find_package(LAPACKE REQUIRED) + find_package(CBLAS CONFIG REQUIRED) +else() + include_directories(${INCLUDE_DIR}) +endif(DEFINED D4LIBS_DIR AND DEFINED D4INCLUDE_DIR) + +add_subdirectory(cpp-d4) + +if(DEFINED D4LIBS_DIR AND DEFINED D4INCLUDE_DIR) + target_link_libraries(yourproject PUBLIC libcpp_d4 cblas lapacke ) +else() + target_link_libraries(yourproject PUBLIC libcpp_d4 ${LAPACKE_LIBRARIES} ${CBLAS_LIBRARIES} ) +endif(DEFINED D4LIBS_DIR AND DEFINED D4INCLUDE_DIR) +``` ## Citations - E. Caldeweyher, C. Bannwarth and S. Grimme, _J. Chem. Phys._, **2017**, 147, 034112. DOI: [10.1063/1.4993215](https://dx.doi.org/10.1063/1.4993215) diff --git a/include/dftd_geometry.h b/include/dftd_geometry.h index d9ecdbc..7d7dab6 100644 --- a/include/dftd_geometry.h +++ b/include/dftd_geometry.h @@ -42,6 +42,52 @@ class TMolecule { xyz.Delete(); at.Delete(); } + + /* set structure by array of coords (double), atom types (int) and number of atoms */ + /* Geometry has to be in bohrs */ + void SetGeometry(const double* coord, const int* attype, int number) + { + GetMemory(number); + for(int i = 0; i < NAtoms; ++i) + { + at(i) = attype[i]; + xyz(i, 0) = coord[3*i + 0]; + xyz(i, 1) = coord[3*i + 1]; + xyz(i, 2) = coord[3*i + 2]; + } + } + + /* update the geometry */ + /* Geometry has to be in bohrs */ + void UpdateGeometry(const double* coord) + { + for(int i = 0; i < NAtoms; ++i) + { + xyz(i, 0) = coord[3*i + 0]; + xyz(i, 1) = coord[3*i + 1]; + xyz(i, 2) = coord[3*i + 2]; + } + } + + /* update the position of a single atom (index, coord and element) */ + /* Geometry has to be in bohrs */ + void UpdateAtom(int index, double x, double y, double z, int element = -1) + { + //std::cout << x << " " << y << " " << z << std::endl; + if(element != -1) + at(index) = element; + xyz(index, 0) = x; + xyz(index, 1) = y; + xyz(index, 2) = z; + } + + void Print() const + { + for(int i = 0; i < NAtoms; ++i) + { + std::cout << at(i) << " " << xyz(i, 0) << " " << xyz(i, 1) << " " << xyz(i, 2) << std::endl; + } + } }; } // namespace dftd4