diff --git a/CMakeLists.txt b/CMakeLists.txt index ba2586d..c9b240a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,222 +1,228 @@ #################################################### # # # SpecMiCP : CMakeLists.txt # # # #################################################### project(specmicp) cmake_minimum_required(VERSION 2.8.8) # Configuration options # ====================== # For an explanation of the options see the INSTALL file option( SPECMICP_USE_OPENMP "Thread parallelisation of specmicp instances if available" ON ) option( SPECMICP_NO_DEBUG "Disable SpecMiCP assert" OFF ) option( SPECMICP_BUILD_STATIC "Build static libraries" OFF ) option( SPECMICP_BUILD_EXAMPLE "Build the examples" ON ) option( SPECMICP_DEBUG_EQUATION_FD_JACOBIAN "Use a finite difference jacobian is specmicp" OFF ) option( SPECMICP_BINARIES_USE_STATIC "SpecMiCP binaries use static libraries" OFF) # PGO sequence option( SPECMICP_PROFILE_GENERATE "Generate the profile for PGO optimization" OFF ) option( SPECMICP_PROFILE_USE "Use the generated profile for PGO optimization" OFF ) # LTO optimization option( SPECMICP_LTO "Use link time optimization" OFF ) option( SPECMICP_LD_GOLD "Use GNU gold linker" ON ) option( SPECMICP_BENCHMARK "Build benchmark" OFF ) # global variables # ================ set(SPECMICP_VERSION 0.0.3) # External Package # ================ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake) # OpenMP #------- # not required but recommended if(SPECMICP_USE_OPENMP) find_package(OpenMP) endif() # Boost # ----- find_package(Boost REQUIRED) include_directories(${Boost_INCLUDE_DIR}) # Eigen # ----- find_package(Eigen3 REQUIRED) # This module comes from the Eigen3 Package include_directories(${EIGEN3_INCLUDE_DIR}) # Eigen unsuported # GMRES.h is really the file we are using/looking for # If it doesn't exist then the solver will not be included in the list of the parse solvers if(EXISTS "${EIGEN3_INCLUDE_DIR}/unsupported/Eigen/src/IterativeSolvers/GMRES.h") add_definitions(-DEIGEN_UNSUPPORTED_FOUND) include_directories("${EIGEN3_INCLUDE_DIR}/unsupported/") endif() # Yaml-cpp # -------- include(FindPkgConfig) pkg_check_modules(YAML REQUIRED yaml-cpp>=0.5) include_directories(${YAML_INCLUDE_DIRS}) link_directories(${YAML_LIBRARY_DIRS}) +# HDF5 +# ---- + +find_package(HDF5 REQUIRED COMPONENTS C CXX) +# HDF5 is optional, must be checked by files that used it + # sanitizer include(SanitizerBuild) # compilation flags # ================= # check the availability of : # c++11 include(cxx11) # -fuse-ld=gold include(gold_linker) # pgo optimization include(pg_optimization) # -fvisibility-hidden include(visibility_flag) # just a friendly warning if(NOT UNIX) message(WARNING "not tested !") endif() include(lto) # set the flag SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_FLAG}") if (OPENMP_FOUND) SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") endif() SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -pedantic") ##SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") message(STATUS "c++ flags : ${CMAKE_CXX_FLAGS}") # Directories ######################################################################### # 3rd party # ========= # installation dir # ---------------- # http://www.cmake.org/pipermail/cmake/2010-February/035466.html # compute default library install dir # library # ------ set (_DEFAULT_LIBRARY_INSTALL_DIR lib) if (EXISTS "${CMAKE_INSTALL_PREFIX}/lib32/" AND CMAKE_SIZEOF_VOID_P EQUAL 4) set (_DEFAULT_LIBRARY_INSTALL_DIR lib32) elif (EXISTS "${CMAKE_INSTALL_PREFIX}/lib64/" AND CMAKE_SIZEOF_VOID_P EQUAL 8) set (_DEFAULT_LIBRARY_INSTALL_DIR lib64) endif () # the library install dir set(LIBRARY_INSTALL_DIR "${_DEFAULT_LIBRARY_INSTALL_DIR}" CACHE PATH "Installation directory for libraries") set(STATIC_LIBRARY_INSTALL_DIR "${_DEFAULT_LIBRARY_INSTALL_DIR}/static" CACHE PATH "Installation directory for static libraries") # make the library install dir an absolute path (can be important e.g. when using CONFIGURE_FILE to embed # the library installation directory into a file) if(NOT IS_ABSOLUTE "${LIBRARY_INSTALL_DIR}") set(LIBRARY_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${LIBRARY_INSTALL_DIR}") endif() if(NOT IS_ABSOLUTE "${STATIC_LIBRARY_INSTALL_DIR}") set(STATIC_LIBRARY_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${STATIC_LIBRARY_INSTALL_DIR}") endif() # Binaries # -------- set(BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for the programs") # include #-------- set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include/specmicp" CACHE PATH "Installation directory for the headers") # share #------ set(SHARE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/specmicp" CACHE PATH "Installation directory for the miscalleneous files...") enable_testing(true) # CPP API : SpecMiCP / ReactMiCP ######################################################################### # the main source directory - the c++ api set(SPECMICP_CPP_API ${CMAKE_CURRENT_SOURCE_DIR}/src) include_directories(${SPECMICP_CPP_API}) add_subdirectory( ${SPECMICP_CPP_API} ) set(SPECMICP_LIBS specmicp specmicp_database specmicp_common ${YAML_LIBRARIES}) set(REACTMICP_LIBS reactmicp dfpm ${SPECMICP_LIBS} ) set(SPECMICP_STATIC_LIBS specmicp_static specmicp_database_static specmicp_common_static ${YAML_LIBRARIES}) set(REACTMICP_STATIC_LIBS reactmicp_static dfpm_static ${SPECMICP_STATIC_LIBS}) # Binaries ######################################################################### add_subdirectory(src/bin/specmicp) # Database ######################################################################### add_subdirectory( data ) # Documentation ######################################################################### # "common" documentation # ----------------------- set( DOCS_LIST ${CMAKE_CURRENT_SOURCE_DIR}/README.md ${CMAKE_CURRENT_SOURCE_DIR}/INSTALL ${CMAKE_CURRENT_SOURCE_DIR}/COPYING ) add_custom_target(docs SOURCES ${DOCS_LIST}) install(FILES ${DOCS_LIST} DESTINATION ${SHARE_INSTALL_DIR} ) # scripts # -------- add_subdirectory( scripts ) # Doxygen documentation # --------------------- add_subdirectory( doc ) # Tests ######################################################################### add_subdirectory( tests ) # Examples ######################################################################### add_subdirectory( examples ) # Benchmark ######################################################################## if (SPECMICP_BENCHMARK) add_subdirectory( benchmark ) endif() # Docker ######################################################################## file(COPY docker/Dockerfile docker/run_tests.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/docker ) diff --git a/src/reactmicp/CMakeLists.txt b/src/reactmicp/CMakeLists.txt index f593534..c062a10 100644 --- a/src/reactmicp/CMakeLists.txt +++ b/src/reactmicp/CMakeLists.txt @@ -1,174 +1,184 @@ # ReactMiCP # ============= set(REACTMICP_SOLVER_DIR solver) set(REACTMICP_SYSTEMS_DIR systems) set(REACTMICP_EQUILIBRIUMCURVE equilibrium_curve) +set(REACTMICP_IO io) add_custom_target(reactmicp_incl SOURCES ${REACTMICP_SOLVER_DIR}/reactive_transport_solver_structs.hpp ${REACTMICP_SOLVER_DIR}/staggers_base/variables_base.hpp ${REACTMICP_SOLVER_DIR}/staggers_base/transport_stagger_base.hpp ${REACTMICP_SOLVER_DIR}/staggers_base/chemistry_stagger_base.hpp ${REACTMICP_SOLVER_DIR}/staggers_base/upscaling_stagger_base.hpp ${REACTMICP_SOLVER_DIR}/staggers_base/stagger_structs.hpp ${REACTMICP_SOLVER_DIR}/staggers_base/decl.inl ${REACTMICP_SOLVER_DIR}/staggers_base/staggers_base.hpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/variablesfwd.hpp ${REACTMICP_SYSTEMS_DIR}/unsaturated/types_fwd.hpp ${REACTMICP_SYSTEMS_DIR}/unsaturated/variables_sub.hpp ${REACTMICP_SYSTEMS_DIR}/unsaturated/variables_box.hpp ${REACTMICP_SYSTEMS_DIR}/unsaturated/transport_constraints.hpp ) set(REACTMICP_LIBFILES ${REACTMICP_EQUILIBRIUMCURVE}/chemistry.cpp ${REACTMICP_EQUILIBRIUMCURVE}/eqcurve_extractor.cpp ${REACTMICP_EQUILIBRIUMCURVE}/eqcurve_coupler.cpp ${REACTMICP_EQUILIBRIUMCURVE}/eqcurve_solid_transport.cpp # Flexible reactive transport solver # ---------------------------------- ${REACTMICP_SOLVER_DIR}/reactive_transport_solver.cpp ${REACTMICP_SOLVER_DIR}/timestepper.cpp ${REACTMICP_SOLVER_DIR}/runner.cpp # ${REACTMICP_SYSTEMS_DIR}/saturated_react/variables.cpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/transport_program.cpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/transport_stagger.cpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/equilibrium_stagger.cpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/kinetic_stagger.cpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/react_solver.cpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/init_variables.cpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/diffusive_upscaling_stagger.cpp ${REACTMICP_SYSTEMS_DIR}/unsaturated/variables.cpp ${REACTMICP_SYSTEMS_DIR}/unsaturated/saturation_equation.cpp ${REACTMICP_SYSTEMS_DIR}/unsaturated/pressure_equation.cpp ${REACTMICP_SYSTEMS_DIR}/unsaturated/aqueous_equation.cpp ${REACTMICP_SYSTEMS_DIR}/unsaturated/transport_stagger.cpp ${REACTMICP_SYSTEMS_DIR}/unsaturated/equilibrium_stagger.cpp ${REACTMICP_SYSTEMS_DIR}/unsaturated/variables_interface.cpp ${REACTMICP_SYSTEMS_DIR}/unsaturated/equilibrium_constraints.cpp - io/reactive_transport.cpp - io/saturated_react.cpp - io/configuration.cpp + ${REACTMICP_IO}/reactive_transport.cpp + ${REACTMICP_IO}/saturated_react.cpp + ${REACTMICP_IO}/configuration.cpp ) +# hdf5 +# ----- +if (HDF5_FOUND) + list(APPEND REACTMICP_LIBFILES ${REACTMICP_IO}/saturated_react_hdf5.cpp) + + include_directories(HDF5_INCLUDE_DIRS) + set_source_files_properties(${REACTMICP_IO}/saturated_react_hdf5.cpp PROPERTIES COMPILE_DEFINITIONS HDF5_DEFINITIONS) +endif() + set_visibility_flag(${REACTMICP_LIBFILES}) set_pgo_flag(${REACTMICP_LIBFILES}) if(OPENMP_FOUND) if(SPECMICP_USE_OPENMP) set_source_files_properties(${REACTMICP_SYSTEMS_DIR}/saturated_react/equilibrium_stagger.cpp PROPERTIES COMPILE_DEFINITIONS "SPECMICP_USE_OPENMP" ) set_source_files_properties(${REACTMICP_SYSTEMS_DIR}/saturated_react/kinetic_stagger.cpp PROPERTIES COMPILE_DEFINITIONS "SPECMICP_USE_OPENMP" ) set_source_files_properties(${REACTMICP_SYSTEMS_DIR}/unsaturated/transport_stagger.cpp PROPERTIES COMPILE_DEFINITIONS "SPECMICP_USE_OPENMP" ) set_source_files_properties(${REACTMICP_SYSTEMS_DIR}/unsaturated/equilibrium_stagger.cpp PROPERTIES COMPILE_DEFINITIONS "SPECMICP_USE_OPENMP" ) endif() endif() add_library(objreactmicp OBJECT ${REACTMICP_LIBFILES}) set_property(TARGET objreactmicp PROPERTY POSITION_INDEPENDENT_CODE 1) add_library(reactmicp SHARED $) target_link_libraries(reactmicp dfpm) install(TARGETS reactmicp LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR} ) # include files # ------------- set(REACTMICP_STAGGERBASE_INCLUDE_LIST ${REACTMICP_SOLVER_DIR}/staggers_base/variables_base.hpp ${REACTMICP_SOLVER_DIR}/staggers_base/transport_stagger_base.hpp ${REACTMICP_SOLVER_DIR}/staggers_base/chemistry_stagger_base.hpp ${REACTMICP_SOLVER_DIR}/staggers_base/upscaling_stagger_base.hpp ${REACTMICP_SOLVER_DIR}/staggers_base/stagger_structs.hpp ${REACTMICP_SOLVER_DIR}/staggers_base/decl.inl ${REACTMICP_SOLVER_DIR}/staggers_base/staggers_base.hpp ) set(REACTMICP_SOLVER_INCLUDE_LIST ${REACTMICP_SOLVER_DIR}/reactive_transport_solver_structs.hpp ${REACTMICP_SOLVER_DIR}/reactive_transport_solver.hpp ${REACTMICP_SOLVER_DIR}/timestepper.hpp ${REACTMICP_SOLVER_DIR}/runner.hpp ) set(REACTMICP_SATURATEDREACT_INCLUDE_LIST ${REACTMICP_SYSTEMS_DIR}/saturated_react/variablesfwd.hpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/variables.hpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/transport_program.hpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/transport_stagger.hpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/equilibrium_stagger.hpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/kinetic_stagger.hpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/react_solver.hpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/init_variables.hpp ${REACTMICP_SYSTEMS_DIR}/saturated_react/diffusive_upscaling_stagger.hpp ) set(REACTMICP_EQUILIBRIUMCURVE_INCLUDE_LIST ${REACTMICP_EQUILIBRIUMCURVE}/chemistry.cpp ${REACTMICP_EQUILIBRIUMCURVE}/eqcurve_extractor.cpp ${REACTMICP_EQUILIBRIUMCURVE}/eqcurve_coupler.cpp ${REACTMICP_EQUILIBRIUMCURVE}/eqcurve_solid_transport.cpp ) set(REACTMICP_IO_INCLUDE_LIST io/reactive_transport.hpp io/saturated_react.hpp io/configuration.hpp ) install(FILES ${REACTMICP_STAGGERBASE_INCLUDE_LIST} DESTINATION ${INCLUDE_INSTALL_DIR}/reactmicp/solver/staggers_base ) install(FILES ${REACTMICP_SOLVER_INCLUDE_LIST} DESTINATION ${INCLUDE_INSTALL_DIR}/reactmicp/solver ) install(FILES ${REACTMICP_SATURATEDREACT_INCLUDE_LIST} DESTINATION ${INCLUDE_INSTALL_DIR}/reactmicp/systems/saturated_react ) install(FILES ${REACTMICP_EQUILIBRIUMCURVE_INCLUDE_LIST} DESTINATION ${INCLUDE_INSTALL_DIR}/reactmicp/equilibrium_curve ) install(FILES ${REACTMICP_IO_INCLUDE_LIST} DESTINATION ${INCLUDE_INSTALL_DIR}/reactmicp/io ) # static libraries # ---------------- if(SPECMICP_BUILD_STATIC) add_library(reactmicp_static STATIC $) install(TARGETS reactmicp_static ARCHIVE DESTINATION ${STATIC_LIBRARY_INSTALL_DIR} ) else() add_library(reactmicp_static EXCLUDE_FROM_ALL STATIC $) endif() set_target_properties(reactmicp_static PROPERTIES OUTPUT_NAME reactmicp) target_link_libraries(reactmicp_static dfpm_static) diff --git a/src/reactmicp/io/saturated_react_hdf5.cpp b/src/reactmicp/io/saturated_react_hdf5.cpp new file mode 100644 index 0000000..f590063 --- /dev/null +++ b/src/reactmicp/io/saturated_react_hdf5.cpp @@ -0,0 +1,13 @@ +#include "saturated_react_hdf5.hpp" + +namespace specmicp { +namespace io { + +SaturatedReactHDF5NodalOutput::SaturatedReactHDF5NodalOutput(const std::string &filename): + HDF5File(filename, HDF5_OpenMode::create_truncate) +{ + +} + +} //end namespace io +} //end namespace specmicp diff --git a/src/reactmicp/io/saturated_react_hdf5.hpp b/src/reactmicp/io/saturated_react_hdf5.hpp new file mode 100644 index 0000000..d02b2c0 --- /dev/null +++ b/src/reactmicp/io/saturated_react_hdf5.hpp @@ -0,0 +1,55 @@ +/*------------------------------------------------------------------------------- + +Copyright (c) 2015 F. Georget , Princeton University +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +-----------------------------------------------------------------------------*/ + +#ifndef SPECMICP_REACTMICP_IO_SATURATEDREACTHDF5 +#define SPECMICP_REACTMICP_IO_SATURATEDREACTHDF5 + +#include +#include "../../utils/io/specmicp_hdf5.hpp" + +namespace specmicp { +namespace io { + +class SaturatedReactHDF5NodalOutput: public HDF5File +{ +public: + SaturatedReactHDF5NodalOutput(const std::string& filename); + +private: + struct SaturatedReactHDF5NodalOutputImpl; + std::unique_ptr m_impl; +}; + +} //end namespace io +} //end namespace specmicp + +#endif // SPECMICP_REACTMICP_IO_SATURATEDREACTHDF5 diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index 308492a..a50b341 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -1,100 +1,118 @@ +# headers only module +# ------------------- add_custom_target(utils_inc SOURCES #log.hpp # sparse solvers # -------------- sparse_solvers/sparse_solver_base.hpp sparse_solvers/sparse_solver.hpp sparse_solvers/sparse_solver_structs.hpp sparse_solvers/sparse_qr.hpp sparse_solvers/sparse_lu.hpp sparse_solvers/sparse_bicgstab.hpp sparse_solvers/sparse_gmres.hpp options_handler.hpp perfs_handler.hpp compat.hpp ) set(SPECMICP_COMMON_LIBRARY_FILES log.cpp dateandtime.cpp timer.cpp moving_average.cpp ../physics/laws.cpp ../physics/units.cpp ../physics/io/units.cpp io/format.cpp io/csv_formatter.cpp io/yaml.cpp ) +# hdf5 +# ----- +if (HDF5_FOUND) + list(APPEND SPECMICP_COMMON_LIBRARY_FILES io/specmicp_hdf5.cpp) + + include_directories(HDF5_INCLUDE_DIRS) + set_source_files_properties(io/specmicp_hdf5.cpp PROPERTIES COMPILE_DEFINITIONS HDF5_DEFINITIONS) +endif() + set_pgo_flag(${SPECMICP_COMMON_LIBRARY_FILES}) add_library(objspecmicp_common OBJECT ${SPECMICP_COMMON_LIBRARY_FILES}) set_property(TARGET objspecmicp_common PROPERTY POSITION_INDEPENDENT_CODE 1) add_library(specmicp_common SHARED $) +if (HDF5_FOUND) + target_link_libraries(specmicp_common ${HDF5_LIBRARIES}) +endif() + install(TARGETS specmicp_common LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR} ) set(UTILS_INCLUDE_LIST log.hpp options_handler.hpp perfs_handler.hpp moving_average.hpp timer.hpp dateandtime.hpp compat.hpp ) set(UTILS_SPARSE_INCLUDE_LIST # sparse solvers # -------------- sparse_solvers/sparse_solver.hpp sparse_solvers/sparse_solver_base.hpp sparse_solvers/sparse_solver_structs.hpp sparse_solvers/sparse_qr.hpp sparse_solvers/sparse_lu.hpp sparse_solvers/sparse_bicgstab.hpp sparse_solvers/sparse_gmres.hpp ) set(UTILS_IO_INCLUDE_LIST io/format.hpp io/csv_formatter.hpp io/yaml.hpp ) install(FILES ${UTILS_INCLUDE_LIST} DESTINATION ${INCLUDE_INSTALL_DIR}/utils ) install(FILES ${UTILS_SPARSE_INCLUDE_LIST} DESTINATION ${INCLUDE_INSTALL_DIR}/utils/sparse_solvers ) install(FILES ${UTILS_IO_INCLUDE_LIST} DESTINATION ${INCLUDE_INSTALL_DIR}/utils/io ) # static libraries # ---------------- if(SPECMICP_BUILD_STATIC) add_library(specmicp_common_static STATIC $) install(TARGETS specmicp_common_static ARCHIVE DESTINATION ${STATIC_LIBRARY_INSTALL_DIR} ) else() add_library(specmicp_common_static EXCLUDE_FROM_ALL STATIC $) endif() set_target_properties(specmicp_common_static PROPERTIES OUTPUT_NAME specmicp_common) +if (HDF5_FOUND) + target_link_libraries(specmicp_common_static ${HDF5_LIBRARIES}) +endif() diff --git a/src/utils/io/specmicp_hdf5.cpp b/src/utils/io/specmicp_hdf5.cpp new file mode 100644 index 0000000..b38ee36 --- /dev/null +++ b/src/utils/io/specmicp_hdf5.cpp @@ -0,0 +1,114 @@ +#include "specmicp_hdf5.hpp" + +#include + +#include "../compat.hpp" + +namespace specmicp { +namespace io { + +HDF5File::HDF5File(const std::string& filename, HDF5_OpenMode mode) +{ + open(filename, mode); +} + + +HDF5File::~HDF5File() { + close(); +} + + +bool HDF5File::open( + const std::string& filename, + HDF5_OpenMode mode + ) +{ + if (m_file != nullptr) + m_file->close(); + + + unsigned int flag = H5F_ACC_DEFAULT; + switch (mode) { + case HDF5_OpenMode::CreateTruncate: + flag = H5F_ACC_TRUNC; + break; + case HDF5_OpenMode::CreateFailIfExist: + flag = H5F_ACC_EXCL; + break; + case HDF5_OpenMode::OpenReadOnly: + flag = H5F_ACC_RDONLY; + break; + case HDF5_OpenMode::OpenReadWrite: + flag = H5F_ACC_RDWR; + break; + } + + m_file = make_unique(filename, flag); + + return is_open(); +} + +bool HDF5File::is_open() { + return (m_file != nullptr); + +} + +void HDF5File::close() { + if (is_open()) { + m_file->close(); + m_file.reset(nullptr); + } +} + +std::unique_ptr HDF5File::create_dataset( + const std::string& name, + const H5::DataType& type, + const H5::DataSpace& data_space, + const H5::DSetCreatPropList& list + ) +{ + return make_unique( + m_file->createDataSet(name, type, data_space, list)); +} + + +std::unique_ptr HDF5File::create_dataset( + const std::string& name, + const std::string& section, + const H5::DataType& type, + const H5::DataSpace& data_space, + const H5::DSetCreatPropList& list + ) +{ + return create_dataset(complete_name(name, section), type, data_space, list); +} + + +std::unique_ptr HDF5File::create_group( + const std::string& name + ) +{ + return make_unique( + m_file->createGroup(name) + ); +} + + +std::string HDF5File::complete_name( + const std::string& name, + const std::string& section + ) +{ + std::string comp = section; + if (comp[comp.size()-1] != '/') { + comp.reserve(comp.size()+1+name.size()); + comp += "/"+name; + } + else { + comp += name; + } + return comp; +} + +} //end namespace io +} //end namespace specmicp diff --git a/src/utils/io/specmicp_hdf5.hpp b/src/utils/io/specmicp_hdf5.hpp new file mode 100644 index 0000000..45d71bb --- /dev/null +++ b/src/utils/io/specmicp_hdf5.hpp @@ -0,0 +1,126 @@ +/*------------------------------------------------------------------------------- + +Copyright (c) 2014,2015 F. Georget , Princeton University +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +-----------------------------------------------------------------------------*/ + +#ifndef SPECMICP_UTIL_SPECMICPHDF5_HPP +#define SPECMICP_UTIL_SPECMICPHDF5_HPP + +#include "../../macros.hpp" +#include + +// forward declaration +namespace H5 { +class H5File; +class DataSet; +class DataSpace; +class PredType; +class DataType; +class DSetCreatPropList; +class Group; +} //end namespace H5 + +namespace specmicp { +namespace io { + +//! \brief Mode to open/create a file +enum class HDF5_OpenMode +{ + CreateTruncate, //!< Create a file, truncate if it exists + CreateFailIfExist, //!< Create a file, fail if it exists + OpenReadOnly, //!< Open a file, read only mode + OpenReadWrite //!< Open a file, read write mode +}; + +//! \brief A HDF5 file +//! +//! To be subclassed +class HDF5File +{ +public: + + HDF5File(); + HDF5File(const std::string& filename, HDF5_OpenMode mode); + ~HDF5File(); + + //! \brief Open a file + //! + //! \param filename Name of the file to open + //! \param mode Opening mode + //! \return True if the file was successfully open + //! + bool open(const std::string& filename, HDF5_OpenMode mode); + + //! \brief Close the file + void close(); + + //! \brief Return true if the file handle is open + bool is_open(); + + //! \brief Create a dataset in the root ("/") + std::unique_ptr create_dataset( + const std::string& name, + const H5::DataType& type, + const H5::DataSpace& data_space, + const H5::DSetCreatPropList& list + ); + + //! \brief Create a dataset in 'section' + std::unique_ptr create_dataset( + const std::string& name, + const std::string& section, + const H5::DataType& type, + const H5::DataSpace& data_space, + const H5::DSetCreatPropList& list + ); + + //! \brief Create a new group + std::unique_ptr create_group( + const std::string& name + ); + + //! \brief Give the complete the name of a dataset + std::string complete_name( + const std::string& name, + const std::string& section + ); + +protected: + std::unique_ptr m_file {nullptr}; + +private: + HDF5File(const HDF5File& other) = delete; + HDF5File& operator= (const HDF5File& other) = delete; +}; + +} //end namespace io +} //end namespace specmicp + +#endif // SPECMICP_UTIL_SPECMICPHDF5_HPP