diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d71118..7f59663 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,117 +1,119 @@ # ============================================================================= # file CMakeLists.txt # # @author Till Junge # # @date 08 Jan 2018 # # @brief Main configuration file # # @section LICENCE # # Copyright © 2018 Till Junge # # µSpectre is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3, or (at # your option) any later version. # # µSpectre is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Emacs; see the file COPYING. If not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # ============================================================================= cmake_minimum_required(VERSION 3.7.0) project(µSpectre) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(BUILD_SHARED_LIBS ON) add_compile_options(-Wall -Wextra -Weffc++) enable_testing() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # using Clang add_compile_options(-Wno-missing-braces) elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # using GCC string( TOLOWER "${CMAKE_BUILD_TYPE}" build_type ) if ("release" STREQUAL "${build_type}" ) add_compile_options(-march=native) endif() if ("debug" STREQUAL "${build_type}" ) add_compile_options(-O0) endif() elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") # using Intel C++ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # using Visual Studio C++ endif() find_package(Boost COMPONENTS unit_test_framework REQUIRED) find_package(Eigen3 3.3 REQUIRED NO_MODULE) include_directories( tests src ${EIGEN3_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${FFTW_INCLUDES} ) #find_package(MPI REQUIRED) find_package(FFTW REQUIRED) #find_package(FFTWMPI REQUIRED) #build tests file( GLOB TEST_SRCS "${CMAKE_SOURCE_DIR}/tests/test_*.cc") add_executable(main_test_suite tests/main_test_suite.cc ${TEST_SRCS}) target_link_libraries(main_test_suite ${Boost_LIBRARIES} muSpectre) add_test(main_test_suite main_test_suite --report_level=detailed --build_info=TRUE) #add_test(main_test_suite main_test_suite --build_info=TRUE) # compile the library add_compile_options( -Werror) add_subdirectory( "${CMAKE_SOURCE_DIR}/src/" ) #compile executables file( GLOB binaries "${CMAKE_SOURCE_DIR}/bin/*.cc") foreach(binaryfile ${binaries}) get_filename_component(binaryname ${binaryfile} NAME_WE) add_executable(${binaryname} ${binaryfile}) target_link_libraries(${binaryname} ${Boost_LIBRARIES} muSpectre) endforeach(binaryfile ${binaries}) # compile benchmarks file(GLOB benchmarks "${CMAKE_SOURCE_DIR}/benchmarks/benchmark*cc") foreach(benchmark ${benchmarks}) get_filename_component(benchmark_name ${benchmark} NAME_WE) add_executable(${benchmark_name} ${benchmark}) target_link_libraries(${benchmark_name} ${BOOST_LIBRARIES} muSpectre) endforeach(benchmark ${benchmark}) # copy python test configure_file( "${CMAKE_SOURCE_DIR}/tests/python_binding_tests.py" "${CMAKE_BINARY_DIR}/python_binding_tests.py" COPYONLY) add_test(python_binding_test python_binding_tests.py) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 12ffbe4..0c8568a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,50 +1,66 @@ # ============================================================================= # file CMakeLists.txt # # @author Till Junge # # @date 08 Jan 2018 # # @brief Configuration for libmuSpectre # # @section LICENCE # # Copyright © 2018 Till Junge # # µSpectre is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3, or (at # your option) any later version. # # µSpectre is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Emacs; see the file COPYING. If not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # ============================================================================= include_directories( common materials system external ) set (muSpectre_SRC ) add_subdirectory(common) add_subdirectory(materials) add_subdirectory(fft) add_subdirectory(system) add_subdirectory(solver) find_package(FFTW REQUIRED) + +# The following checks whether std::optional exists and replaces it by +# boost::optional if necessary +include(CheckCXXSourceCompiles) +CHECK_CXX_SOURCE_COMPILES( + "#include +int main() { +std::experimental::optional A{}; +}" + HAS_STD_OPTIONAL) + +if( NOT HAS_STD_OPTIONAL) + add_definitions(-DNO_EXPERIMENTAL) +endif() + + add_library(muSpectre ${muSpectre_SRC}) target_link_libraries(muSpectre Eigen3::Eigen ${FFTW_LIBRARIES}) add_subdirectory(language_bindings) diff --git a/src/common/utilities.hh b/src/common/utilities.hh index fa2b43b..174af67 100644 --- a/src/common/utilities.hh +++ b/src/common/utilities.hh @@ -1,172 +1,200 @@ /** * file utilities.hh * * @author Till Junge * * @date 17 Nov 2017 * * @brief additions to the standard name space to anticipate C++17 features * * @section LICENCE * * Copyright © 2017 Till Junge * * µSpectre is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3, or (at * your option) any later version. * * µSpectre is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Emacs; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef UTILITIES_H #define UTILITIES_H #include #include -#include + +#ifdef NO_EXPERIMENTAL +# if defined(__INTEL_COMPILER) +//# pragma warning ( disable : 383 ) +# elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu +# pragma clang diagnostic push +# pragma clang diagnostic ignored "Weffc++" +# elif (defined(__GNUC__) || defined(__GNUG__)) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Weffc++" +# endif +# include +# if defined(__INTEL_COMPILER) +//# pragma warning ( disable : 383 ) +# elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu +# pragma clang diagnostic pop +# pragma clang diagnostic ignored "Weffc++" +# elif (defined(__GNUC__) || defined(__GNUG__)) +# pragma GCC diagnostic pop +# pragma GCC diagnostic ignored "-Weffc++" +# endif +#else +# include +#endif namespace std_replacement { namespace detail { template struct is_reference_wrapper : std::false_type {}; template struct is_reference_wrapper> : std::true_type {}; template constexpr bool is_reference_wrapper_v = is_reference_wrapper::value; template auto INVOKE(T Base::*pmf, Derived&& ref, Args&&... args) noexcept(noexcept((std::forward(ref).*pmf)(std::forward(args)...))) -> std::enable_if_t::value && std::is_base_of>::value, decltype((std::forward(ref).*pmf)(std::forward(args)...))> { return (std::forward(ref).*pmf)(std::forward(args)...); } template auto INVOKE(T Base::*pmf, RefWrap&& ref, Args&&... args) noexcept(noexcept((ref.get().*pmf)(std::forward(args)...))) -> std::enable_if_t::value && is_reference_wrapper_v>, decltype((ref.get().*pmf)(std::forward(args)...))> { return (ref.get().*pmf)(std::forward(args)...); } template auto INVOKE(T Base::*pmf, Pointer&& ptr, Args&&... args) noexcept(noexcept(((*std::forward(ptr)).*pmf)(std::forward(args)...))) -> std::enable_if_t::value && !is_reference_wrapper_v> && !std::is_base_of>::value, decltype(((*std::forward(ptr)).*pmf)(std::forward(args)...))> { return ((*std::forward(ptr)).*pmf)(std::forward(args)...); } template auto INVOKE(T Base::*pmd, Derived&& ref) noexcept(noexcept(std::forward(ref).*pmd)) -> std::enable_if_t::value && std::is_base_of>::value, decltype(std::forward(ref).*pmd)> { return std::forward(ref).*pmd; } template auto INVOKE(T Base::*pmd, RefWrap&& ref) noexcept(noexcept(ref.get().*pmd)) -> std::enable_if_t::value && is_reference_wrapper_v>, decltype(ref.get().*pmd)> { return ref.get().*pmd; } template auto INVOKE(T Base::*pmd, Pointer&& ptr) noexcept(noexcept((*std::forward(ptr)).*pmd)) -> std::enable_if_t::value && !is_reference_wrapper_v> && !std::is_base_of>::value, decltype((*std::forward(ptr)).*pmd)> { return (*std::forward(ptr)).*pmd; } template auto INVOKE(F&& f, Args&&... args) noexcept(noexcept(std::forward(f)(std::forward(args)...))) -> std::enable_if_t>::value, decltype(std::forward(f)(std::forward(args)...))> { return std::forward(f)(std::forward(args)...); } } // namespace detail template< class F, class... ArgTypes > auto invoke(F&& f, ArgTypes&&... args) // exception specification for QoI noexcept(noexcept(detail::INVOKE(std::forward(f), std::forward(args)...))) -> decltype(detail::INVOKE(std::forward(f), std::forward(args)...)) { return detail::INVOKE(std::forward(f), std::forward(args)...); } namespace detail { template constexpr decltype(auto) apply_impl(F &&f, Tuple &&t, std::index_sequence) { return std_replacement::invoke(std::forward(f), std::get(std::forward(t))...); } } // namespace detail template constexpr decltype(auto) apply(F &&f, Tuple &&t) { return detail::apply_impl (std::forward(f), std::forward(t), std::make_index_sequence>::value>{}); } } //namespace std_replacement + namespace muSpectre { using std_replacement::apply; template +#ifdef NO_EXPERIMENTAL + using optional = typename boost::optional; +#else using optional = typename std::experimental::optional; +#endif /* ---------------------------------------------------------------------- */ template auto asStdTuple(BoostTuple&& boostTuple, std::index_sequence) { return std::tuple>::type...> (boost::get(std::forward(boostTuple))...); } template auto asStdTuple(BoostTuple&& boostTuple) { return asStdTuple(std::forward(boostTuple), std::make_index_sequence>::value>()); } } // muSpectre #endif /* UTILITIES_H */ diff --git a/tests/test_fft_utils.cc b/tests/test_fft_utils.cc index 3030e71..7c3e678 100644 --- a/tests/test_fft_utils.cc +++ b/tests/test_fft_utils.cc @@ -1,83 +1,82 @@ /** * file test_fft_utils.cc * * @author Till Junge * * @date 11 Dec 2017 * * @brief test the small utility functions used by the fft engines and projections * * @section LICENCE * * Copyright © 2017 Till Junge * * µSpectre is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3, or (at * your option) any later version. * * µSpectre is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Emacs; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include -#include "boost/range/combine.hpp" #include "tests.hh" #include "fft/fft_utils.hh" namespace muSpectre { BOOST_AUTO_TEST_SUITE(fft_utils); BOOST_AUTO_TEST_CASE(fft_freqs_test) { //simply comparing to np.fft.fftfreq(12, 1/12.) const std::valarray ref{0., 1., 2., 3., 4., 5., -6., -5., -4., -3., -2., -1.}; auto res{fft_freqs(12)}; Real error = abs(res-ref).sum(); BOOST_CHECK_EQUAL(error, 0.); } BOOST_AUTO_TEST_CASE(fft_freqs_test_length) { //simply comparing to np.fft.fftfreq(10) const std::valarray ref{ 0. , 0.1, 0.2, 0.3, 0.4, -0.5, -0.4, -0.3, -0.2, -0.1}; auto res{fft_freqs(10, 10.)}; Real error = abs(res-ref).sum(); BOOST_CHECK_EQUAL(error, 0.); } BOOST_AUTO_TEST_CASE(wave_vector_computation) { // here, build a FFT_freqs and check it returns the correct xi's constexpr Dim_t dim{twoD}; FFT_freqs freq_struc{{12, 10}, {1., 10.}}; Ccoord_t ccoord1{2, 3}; auto xi{freq_struc.get_xi(ccoord1)}; auto unit_xi{freq_struc.get_unit_xi(ccoord1)}; typename FFT_freqs::Vector ref; ref << 2., .3; // from above tests BOOST_CHECK_LT((xi-ref).norm(), tol); BOOST_CHECK_LT(abs(xi.dot(unit_xi)-xi.norm()), xi.norm()*tol); BOOST_CHECK_LT(abs(unit_xi.norm()-1.), tol); ccoord1={7, 8}; xi = freq_struc.get_xi(ccoord1); unit_xi = freq_struc.get_unit_xi(ccoord1); ref << -5., -.2; BOOST_CHECK_LT((xi-ref).norm(), tol); BOOST_CHECK_LT(abs(xi.dot(unit_xi)-xi.norm()), xi.norm()*tol); BOOST_CHECK_LT(abs(unit_xi.norm()-1.), tol); } BOOST_AUTO_TEST_SUITE_END(); } // muSpectre diff --git a/tests/tests.hh b/tests/tests.hh index c37f3ce..0666ccd 100644 --- a/tests/tests.hh +++ b/tests/tests.hh @@ -1,45 +1,63 @@ /** * file tests.hh * * @author Till Junge * * @date 10 May 2017 * * @brief common defs for tests * * @section LICENCE * * Copyright © 2017 Till Junge * * µSpectre is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3, or (at * your option) any later version. * * µSpectre is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Emacs; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "common/common.hh" +# if defined(__INTEL_COMPILER) +//# pragma warning ( disable : 383 ) +# elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu +# pragma clang diagnostic push +# pragma clang diagnostic ignored "Weffc++" +# elif (defined(__GNUC__) || defined(__GNUG__)) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Weffc++" +# endif #include #include +# if defined(__INTEL_COMPILER) +//# pragma warning ( disable : 383 ) +# elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu +# pragma clang diagnostic pop +# pragma clang diagnostic ignored "Weffc++" +# elif (defined(__GNUC__) || defined(__GNUG__)) +# pragma GCC diagnostic pop +# pragma GCC diagnostic ignored "-Weffc++" +# endif #ifndef TESTS_H #define TESTS_H namespace muSpectre { const Real tol = 1e-14*100; //it's in percent } // muSpectre #endif /* TESTS_H */