diff --git a/.gitignore b/.gitignore index 4e7318d5..f3d70e96 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,31 @@ -wannier90.x -postw90.x -.DS_Store -make.inc -w90chk2chk.x -w90spn2spn.x -libwannier.a -libwan2.a -libwannier.so -libwannier.dylib -*~ -*.x.dSYM +### Build system +cmake-build-*/ +build/ +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps + + +### Other +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +### IDE files .vscode +/.idea + +### Project files +/CMakeUserPresets.json diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..d8439c94 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,179 @@ +cmake_minimum_required(VERSION 3.25...3.29) + +#[=============================================================================[ +# Basic project definition # +]=============================================================================] + +list(APPEND CMAKE_MESSAGE_CONTEXT Wannier90) +project(Wannier90 + VERSION 4.0.0 + DESCRIPTION "Compute maximally-localised Wannier functions." + HOMEPAGE_URL https://www.wannier90.org + LANGUAGES Fortran C + ) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS OFF) + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif () + +#[=============================================================================[ +# Options # +]=============================================================================] + +option(WANNIER90_MPI "Wannier90: Build with MPI support" OFF) +option(WANNIER90_SHARED_LIBS "Wannier90: Build library as a shared library" ${PROJECT_IS_TOP_LEVEL}) +option(WANNIER90_INSTALL "Wannier90: Install files" ${PROJECT_IS_TOP_LEVEL}) +option(WANNIER90_TEST "Wannier90: Build test-suite" ${PROJECT_IS_TOP_LEVEL}) + +#[=============================================================================[ +# Project configuration # +]=============================================================================] + +if (NOT CMAKE_Fortran_MODULE_DIRECTORY) + set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/fortran_mods) +endif () +set(BUILD_SHARED_LIBS ${WANNIER90_SHARED_LIBS}) + +if (WANNIER90_INSTALL) + include(GNUInstallDirs) + include(CMakePackageConfigHelpers) + + # CMake does not properly support fortran module installation paths. + # Adapting the standard from fortran-stdlib + # https://gitlab.kitware.com/cmake/cmake/-/issues/19608 + # https://discourse.cmake.org/t/api-design-c-modules-source-listings-and-interface-properties/5389/14 + cmake_path(APPEND CMAKE_INSTALL_INCLUDEDIR ${PROJECT_NAME} "${CMAKE_Fortran_COMPILER_ID}-${CMAKE_Fortran_COMPILER_VERSION}" + OUTPUT_VARIABLE _DEFAULT_CMAKE_INSTALL_MODULEDIR + ) + set(CMAKE_INSTALL_MODULEDIR ${_DEFAULT_CMAKE_INSTALL_MODULEDIR} + CACHE STRING + "Fortran module installation path (Not a cmake native variable)" + ) + cmake_path(IS_ABSOLUTE CMAKE_INSTALL_MODULEDIR _is_absolute) + if (_is_absolute) + set(CMAKE_INSTALL_FULL_MODULEDIR ${CMAKE_INSTALL_MODULEDIR}) + else () + cmake_path(APPEND CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_MODULEDIR} + OUTPUT_VARIABLE CMAKE_INSTALL_FULL_MODULEDIR + ) + endif () +endif () + +#[=============================================================================[ +# External packages # +]=============================================================================] + +## Third-party libraries +find_package(BLAS REQUIRED) +find_package(LAPACK REQUIRED) +if (WANNIER90_MPI) + find_package(MPI REQUIRED) +endif () + +#[=============================================================================[ +# Main definition # +]=============================================================================] + +## Main targets +add_executable(Wannier90_exe) +set_target_properties(Wannier90_exe PROPERTIES + OUTPUT_NAME wannier90.x + EXPORT_NAME exe +) +add_executable(Wannier90::exe ALIAS Wannier90_exe) +add_executable(Wannier90_post) +set_target_properties(Wannier90_post PROPERTIES + OUTPUT_NAME postw90.x + EXPORT_NAME post +) +add_executable(Wannier90::post ALIAS Wannier90_post) +add_library(Wannier90_lib) +set_target_properties(Wannier90_lib PROPERTIES + OUTPUT_NAME wannier90 + EXPORT_NAME wannier90 + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} +) +add_library(Wannier90::wannier90 ALIAS Wannier90_lib) + +## Main implementations +add_subdirectory(src) + +## Testing +if (WANNIER90_TEST) + enable_testing() + ## Define compiled support programs + # TODO: These should be moved outside of src and hard coded path? + add_executable(w90chk2chk.x src/w90chk2chk.F90) + add_executable(w90spn2spn.x src/w90spn2spn.F90) + target_link_libraries(w90chk2chk.x PRIVATE Wannier90_lib) + target_link_libraries(w90spn2spn.x PRIVATE Wannier90_lib) + + add_subdirectory(test-suite) +endif () + +#[=============================================================================[ +# Install or Export # +]=============================================================================] + +## Installs +if (WANNIER90_INSTALL) + configure_file(cmake/wannier90.pc.in wannier90.pc) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/wannier90.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig + COMPONENT Wannier90_Development + ) + write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/Wannier90ConfigVersion.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion + ) + configure_package_config_file( + cmake/Wannier90Config.cmake.in + Wannier90Config.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Wannier90 + ) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Wannier90ConfigVersion.cmake + ${CMAKE_CURRENT_BINARY_DIR}/Wannier90Config.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Wannier90 + COMPONENT Spglib_Development + ) + install(EXPORT Wannier90Targets + FILE Wannier90Targets.cmake + NAMESPACE Wannier90:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Wannier90 + COMPONENT Wannier90_Development + ) + export(EXPORT Wannier90Targets + FILE Wannier90Targets.cmake + NAMESPACE Wannier90:: + ) +endif () + +## Make project available to FetchContent +if (NOT PROJECT_IS_TOP_LEVEL) + # Propagate variables for FetchContent + # All variables have to be consistent with CMakeExtraUtilsConfig.cmake + set(Wannier90_MPI ${WANNIER90_WITH_MPI}) + if (CMAKE_VERSION VERSION_LESS 3.25) + # TODO: Remove when cmake 3.25 is commonly distributed + set(Wannier90_VERSION ${Wannier90_VERSION} PARENT_SCOPE) + set(Wannier90_VERSION_MAJOR ${Wannier90_VERSION_MAJOR} PARENT_SCOPE) + set(Wannier90_VERSION_MINOR ${Wannier90_VERSION_MINOR} PARENT_SCOPE) + set(Wannier90_VERSION_PATCH ${Wannier90_VERSION_PATCH} PARENT_SCOPE) + set(Wannier90_VERSION_TWEAK ${Wannier90_VERSION_TWEAK} PARENT_SCOPE) + set(Wannier90_MPI ${Wannier90_MPI} PARENT_SCOPE) + endif () + return(PROPAGATE + Wannier90_VERSION + Wannier90_VERSION_MAJOR + Wannier90_VERSION_MINOR + Wannier90_VERSION_PATCH + Wannier90_VERSION_TWEAK + Wannier90_MPI + ) +endif () diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 00000000..f65d6c85 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,7 @@ +{ + "version": 6, + "include": [ + "cmake/CMakePresets-defaults.json", + "cmake/CMakePresets-CI.json" + ] +} \ No newline at end of file diff --git a/cmake/CMakePresets-CI.json b/cmake/CMakePresets-CI.json new file mode 100644 index 00000000..19428bcd --- /dev/null +++ b/cmake/CMakePresets-CI.json @@ -0,0 +1,197 @@ +{ + "version": 6, + "include": [ + "CMakePresets-defaults.json" + ], + "configurePresets": [ + { + "name": "ci-base", + "hidden": true, + "generator": "Ninja", + "inherits": [ + "default" + ], + "cacheVariables": { + "WANNIER90_TEST": { + "type": "BOOL", + "value": true + }, + "WANNIER90_MPI": { + "type": "BOOL", + "value": "$env{WITH_MPI}" + } + }, + "errors": { + "deprecated": true + } + }, + { + "name": "gcc-ci", + "displayName": "CI - GCC toolchain", + "inherits": [ + "ci-base" + ], + "binaryDir": "cmake-build-gcc", + "cacheVariables": { + "CMAKE_Fortran_COMPILER": { + "type": "FILEPATH", + "value": "gfortran" + } + } + }, + { + "name": "llvm-ci", + "displayName": "CI - LLVM toolchain", + "inherits": [ + "ci-base" + ], + "binaryDir": "cmake-build-gcc", + "cacheVariables": { + "CMAKE_Fortran_COMPILER": { + "type": "FILEPATH", + "value": "flang-new" + } + } + }, + { + "name": "intel-ci", + "displayName": "CI - Intel toolchain", + "inherits": [ + "ci-base" + ], + "binaryDir": "cmake-build-intel", + "cacheVariables": { + "CMAKE_Fortran_COMPILER": { + "type": "FILEPATH", + "value": "ifx" + } + } + } + ], + "buildPresets": [ + { + "name": "ci-base", + "hidden": true, + "inherits": [ + "default" + ], + "cleanFirst": true + }, + { + "name": "gcc-ci", + "displayName": "CI - GCC toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "gcc-ci" + }, + { + "name": "llvm-ci", + "displayName": "CI - LLVM toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "llvm-ci" + }, + { + "name": "intel-ci", + "displayName": "CI - Intel toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "intel-ci" + } + ], + "testPresets": [ + { + "name": "ci-base", + "hidden": true, + "inherits": [ + "default" + ], + "output": { + "outputOnFailure": true + } + }, + { + "name": "gcc-ci", + "displayName": "CI - GCC toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "gcc-ci" + }, + { + "name": "llvm-ci", + "displayName": "CI - LLVM toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "llvm-ci" + }, + { + "name": "intel-ci", + "displayName": "CI - Intel toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "intel-ci" + } + ], + "workflowPresets": [ + { + "name": "gcc-ci", + "displayName": "CI - GCC toolchain", + "steps": [ + { + "type": "configure", + "name": "gcc-ci" + }, + { + "type": "build", + "name": "gcc-ci" + }, + { + "type": "test", + "name": "gcc-ci" + } + ] + }, + { + "name": "llvm-ci", + "displayName": "CI - LLVM toolchain", + "steps": [ + { + "type": "configure", + "name": "llvm-ci" + }, + { + "type": "build", + "name": "llvm-ci" + }, + { + "type": "test", + "name": "llvm-ci" + } + ] + }, + { + "name": "intel-ci", + "displayName": "CI - Intel toolchain", + "steps": [ + { + "type": "configure", + "name": "intel-ci" + }, + { + "type": "build", + "name": "intel-ci" + }, + { + "type": "test", + "name": "intel-ci" + } + ] + } + ] +} diff --git a/cmake/CMakePresets-defaults.json b/cmake/CMakePresets-defaults.json new file mode 100644 index 00000000..4fe47d85 --- /dev/null +++ b/cmake/CMakePresets-defaults.json @@ -0,0 +1,103 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "default", + "displayName": "Default preset", + "binaryDir": "cmake-build-release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": { + "type": "STRING", + "value": "Release" + } + } + }, + { + "name": "_mpi", + "hidden": true, + "cacheVariables": { + "WANNIER90_MPI": { + "type": "BOOL", + "value": true + } + } + }, + { + "name": "mpi", + "displayName": "MPI preset", + "binaryDir": "cmake-build-mpi", + "inherits": [ + "_mpi", + "default" + ] + } + ], + "buildPresets": [ + { + "name": "default", + "displayName": "Default preset", + "configurePreset": "default" + }, + { + "name": "mpi", + "displayName": "MPI preset", + "configurePreset": "mpi", + "inherits": [ + "default" + ] + } + ], + "testPresets": [ + { + "name": "default", + "displayName": "Default preset", + "configurePreset": "default" + }, + { + "name": "mpi", + "displayName": "MPI preset", + "configurePreset": "mpi", + "inherits": [ + "default" + ] + } + ], + "workflowPresets": [ + { + "name": "default", + "displayName": "Default workflow", + "steps": [ + { + "type": "configure", + "name": "default" + }, + { + "type": "build", + "name": "default" + }, + { + "type": "test", + "name": "default" + } + ] + }, + { + "name": "mpi", + "displayName": "MPI workflow", + "steps": [ + { + "type": "configure", + "name": "mpi" + }, + { + "type": "build", + "name": "mpi" + }, + { + "type": "test", + "name": "mpi" + } + ] + } + ] +} \ No newline at end of file diff --git a/cmake/Wannier90Config.cmake.in b/cmake/Wannier90Config.cmake.in new file mode 100644 index 00000000..5718d521 --- /dev/null +++ b/cmake/Wannier90Config.cmake.in @@ -0,0 +1,8 @@ +@PACKAGE_INIT@ + + +## Define basic variables +set(Wannier90_MPI @WANNIER90_WITH_MPI@) + +## Parse find_package request +include(${CMAKE_CURRENT_LIST_DIR}/Wannier90Targets.cmake) diff --git a/cmake/wannier90.pc.in b/cmake/wannier90.pc.in new file mode 100644 index 00000000..e1fdf3e8 --- /dev/null +++ b/cmake/wannier90.pc.in @@ -0,0 +1,9 @@ +prefix: @CMAKE_INSTALL_PREFIX@ + +Name: wannier +Version: @PROJECT_VERSION@ +Description: @PROJECT_DESCRIPTION@ +URL: @PROJECT_HOMEPAGE_URL@ + +Cflags: -I@CMAKE_INSTALL_FULL_MODULEDIR@ -I@CMAKE_INSTALL_FULL_INCLUDEDIR@ +Libs: -L@CMAKE_INSTALL_FULL_LIBDIR@ -lwannier90 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..33f54722 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,58 @@ +## Source files definitions +target_sources(Wannier90_lib PRIVATE + comms.F90 + constants.F90 + disentangle.F90 + error.F90 + error_base.F90 + hamiltonian.F90 + io.F90 + kmesh.F90 + library_interface.F90 + overlap.F90 + plot.F90 + readwrite.F90 + sitesym.F90 + transport.F90 + types.F90 + utility.F90 + wannier90_readwrite.F90 + wannier90_types.F90 + wannierise.F90 + ws_distance.F90 + ) +target_sources(Wannier90_exe PRIVATE + wannier_prog.F90 + ) + +## Linking targets +target_link_libraries(Wannier90_exe PRIVATE + Wannier90_lib +) +target_link_libraries(Wannier90_lib PRIVATE + BLAS::BLAS LAPACK::LAPACK +) +target_include_directories(Wannier90_lib PUBLIC + "$" + "$" +) +if (WANNIER90_MPI) + target_link_libraries(Wannier90_lib PRIVATE MPI::MPI_Fortran) +endif () + +add_subdirectory(postw90) + +## Installs +if (WANNIER90_INSTALL) + install(TARGETS Wannier90_lib Wannier90_exe + EXPORT Wannier90Targets + LIBRARY COMPONENT Wannier90_Runtime NAMELINK_COMPONENT Wannier90_Development + ARCHIVE COMPONENT Wannier90_Development + PUBLIC_HEADER COMPONENT Wannier90_Development + RUNTIME COMPONENT Wannier90_Runtime + ) + install(FILES ${CMAKE_Fortran_MODULE_DIRECTORY}/w90_library.mod + DESTINATION ${CMAKE_INSTALL_MODULEDIR} + COMPONENT Wannier90_Development + ) +endif () diff --git a/src/postw90/CMakeLists.txt b/src/postw90/CMakeLists.txt new file mode 100644 index 00000000..e2a4faca --- /dev/null +++ b/src/postw90/CMakeLists.txt @@ -0,0 +1,32 @@ +target_sources(Wannier90_post PRIVATE + postw90.F90 + ) +target_sources(Wannier90_lib PRIVATE + berry.F90 + boltzwann.F90 + dos.F90 + geninterp.F90 + get_oper.F90 + gyrotropic.F90 + kpath.F90 + kslice.F90 + postw90.F90 + postw90_common.F90 + postw90_readwrite.F90 + postw90_types.F90 + spin.F90 + wan_ham.F90 + ) +target_link_libraries(Wannier90_post PRIVATE + Wannier90_lib BLAS::BLAS LAPACK::LAPACK) + +## Installs +if (WANNIER90_INSTALL) + install(TARGETS Wannier90_post + EXPORT Wannier90Targets + LIBRARY COMPONENT Wannier90_Runtime NAMELINK_COMPONENT Wannier90_Development + ARCHIVE COMPONENT Wannier90_Development + PUBLIC_HEADER COMPONENT Wannier90_Development + RUNTIME COMPONENT Wannier90_Runtime + ) +endif () diff --git a/test-suite/CMakeLists.txt b/test-suite/CMakeLists.txt new file mode 100644 index 00000000..c29f035e --- /dev/null +++ b/test-suite/CMakeLists.txt @@ -0,0 +1,129 @@ +cmake_minimum_required(VERSION 3.20...3.29) + +#[=============================================================================[ +# Basic project definition # +]=============================================================================] + +list(APPEND CMAKE_MESSAGE_CONTEXT Test) +project(Wannier90_test + LANGUAGES C Fortran +) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS OFF) + +#[=============================================================================[ +# Options # +]=============================================================================] + +#[=============================================================================[ +# Project configuration # +]=============================================================================] + +#[=============================================================================[ +# External packages # +]=============================================================================] + +find_package(Python 3.8 REQUIRED) + +#[=============================================================================[ +# Main definition # +]=============================================================================] + +## Prepare test environment +foreach (extra_file IN ITEMS + checkpoints + run_tests + testcode + tests + tools +) + file(COPY ${extra_file} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +endforeach () + +set(test_names + testpostw90_boltzwann + testpostw90_example04_dos + testpostw90_example04_pdos + testpostw90_fe_ahc + testpostw90_fe_ahc_adaptandfermi + testpostw90_fe_dos_spin + testpostw90_fe_kpathcurv + testpostw90_fe_kpathmorbcurv + testpostw90_fe_kpathmorbcurv_ws + testpostw90_fe_kslicecurv + testpostw90_fe_kslicemorb + testpostw90_fe_kubo_Axy + testpostw90_fe_kubo_Szz + testpostw90_fe_kubo_jdos + testpostw90_fe_morb + testpostw90_fe_morbandahc + testpostw90_fe_spin + testpostw90_gaas_kdotp + testpostw90_gaas_sc_eta_corr + testpostw90_gaas_sc_xyz + testpostw90_gaas_sc_xyz_scphase2 + testpostw90_gaas_sc_xyz_scphase2_ws + testpostw90_gaas_sc_xyz_ws + testpostw90_gaas_shc + testpostw90_pt_kpathbandsshc + testpostw90_pt_kpathshc + testpostw90_pt_ksliceshc + testpostw90_pt_shc + testpostw90_pt_shc_ryoo + testpostw90_si_geninterp + testpostw90_si_geninterp_wsdistance + testpostw90_te_gyrotropic + testpostw90_te_gyrotropic_C + testpostw90_te_gyrotropic_D0 + testpostw90_te_gyrotropic_Dw + testpostw90_te_gyrotropic_K + testpostw90_te_gyrotropic_NOA + testpostw90_te_gyrotropic_dos + testw90_basic1 + testw90_basic2 + testw90_benzene_gamma_val + testw90_benzene_gamma_val_hexcell + testw90_benzene_gamma_valcond + testw90_bvec + testw90_cube_format + testw90_disentanglement_sawfs + testw90_example01 + testw90_example02 + testw90_example02_restart + testw90_example03 + testw90_example03_labelinfo + testw90_example03_optmem + testw90_example04 + testw90_example05 + testw90_example07 + testw90_example11_1 + testw90_example11_2 + testw90_example21_As_sp + testw90_example26 + testw90_gaas_disentanglement_issue192 + testw90_lavo3_dissphere + testw90_na_chain_gamma + testw90_nnkpt1 + testw90_nnkpt2 + testw90_nnkpt3 + testw90_nnkpt4 + testw90_nnkpt5 + testw90_precond_1 + testw90_precond_2 + testw90_write_u_matrices +) +if (WANNIER90_WITH_MPI) + list(APPEND test_names + partestw90_mpierr + ) +endif () + +## Define tests +foreach (test IN LISTS test_names) + add_test(NAME ${test} + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/run_tests -c ${test} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) +endforeach ()