diff --git a/src/reactmicp/io/hdf5_unsaturated.cpp b/src/reactmicp/io/hdf5_unsaturated.cpp index 4077322..7b9e586 100644 --- a/src/reactmicp/io/hdf5_unsaturated.cpp +++ b/src/reactmicp/io/hdf5_unsaturated.cpp @@ -1,746 +1,755 @@ /* ============================================================================= Copyright (c) 2014 - 2016 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. * ============================================================================= */ #include "hdf5_unsaturated.hpp" #include "reactmicp/systems/unsaturated/variables.hpp" #include "specmicp_common/io/hdf5/file.hpp" #include "specmicp_common/io/hdf5/group.hpp" #include "specmicp_common/io/hdf5/dataset.hpp" #include "specmicp_common/io/hdf5_timesteps.hpp" #include "specmicp/io/hdf5_adimensional.hpp" #include "dfpm/io/hdf5_mesh.hpp" #include "specmicp_database/io/hdf5_database.hpp" #include "specmicp_common/physics/units.hpp" #include "specmicp_database/data_container.hpp" #include "specmicp_common/compat.hpp" #include "specmicp_common/log.hpp" #include #include #include using namespace specmicp::reactmicp::systems::unsaturated; #define MESH_GRPNAME "mesh" #define DATABASE_GRPNAME "database" #define UNIT_ATTRIBUTE "unit" #define MAIN_VARIABLES_GRPNAME "main_variables" #define CHEMISTRY_SOLUTION_GRPNAME "chemistry_solution" #define TRANSPORT_PROPERTIES_GRPNAME "transport_properties" #define LIQUID_SATURATION_DSET "liquid_saturation" #define AQUEOUS_CONC_DSET "aqueous_concentration" #define SOLID_CONC_DSET "solid_concentration" #define PRESSURE_DSET "partial_pressure" #define CAP_PRESSURE_DSET "capillary_pressure" #define POROSITY_DSET "porosity" #define LIQUID_DIFFUSIVITY_DSET "liquid_diffusivity" #define REL_LIQUID_DIFFUSIVITY_DSET "relative_liquid_diffusivity" #define LIQUID_PERMEABILITY_DSET "liquid_permeability" #define REL_LIQUID_PERMEABILITY_DSET "relative_liquid_permeability" #define RESISTANCE_GAS_DIFFUSIVITY_DSET "resistance_gas_diffusivity" #define REL_GAS_DIFFUSIVITY_DSET "relative_gas_diffusivity" namespace specmicp { namespace io { //! \brief Implementation of the UnsaturatedHDF5Saver //! //! \internal struct SPECMICP_DLL_LOCAL UnsaturatedHDF5Saver::UnsaturatedHDF5SaverImpl { public: std::string m_filepath; std::shared_ptr m_vars; //!< the variables database::RawDatabasePtr m_database; //!< the database UnsaturatedHDF5SaverImpl( const std::string& filename, std::shared_ptr vars, const units::UnitsSet the_units): m_filepath(filename), m_vars(vars), m_database(vars->get_database()) { init_file(the_units); } //! \brief Save a timestep void save_timestep( const std::string& name ); //! \brief Save the main variables void save_main_variables( hdf5::Group& timestep_grp ); //! \brief Save the chemical solution void save_chemical_solution( hdf5::Group& timestep_grp ); //! \brief Save the transport properties void save_transport_properties( hdf5::Group& timestep_grp ); //! \brief create the file and save common values (mesh, db, units) void init_file(const units::UnitsSet& the_units); }; // UnsaturatedHDF5Saver::UnsaturatedHDF5Saver( const std::string& filename, std::shared_ptr vars, const units::UnitsSet& the_units ): m_impl(make_unique(filename, vars, the_units)) {} UnsaturatedHDF5Saver::~UnsaturatedHDF5Saver() = default; void UnsaturatedHDF5Saver::save_timestep(scalar_t timestep) { return m_impl->save_timestep(std::to_string(timestep)); } // Implementation // ============== //! \brief Save a timestep void UnsaturatedHDF5Saver::UnsaturatedHDF5SaverImpl::save_timestep( const std::string& name ) { hdf5::File the_file = hdf5::File::open(m_filepath, hdf5::OpenMode::OpenReadWrite); hdf5::Group timestep_grp = the_file.create_group(name); save_main_variables(timestep_grp); save_chemical_solution(timestep_grp); save_transport_properties(timestep_grp); } // ugly, but more readable at the end #define uvars(var_name) \ m_vars->get_ ## var_name ().variable #define uvarsi(var_name, index) \ m_vars->get_ ## var_name (index).variable void UnsaturatedHDF5Saver::UnsaturatedHDF5SaverImpl::save_main_variables( hdf5::Group& timestep_grp ) { hdf5::Group main_vars_grp = timestep_grp.create_group(MAIN_VARIABLES_GRPNAME); // water { auto water_group = main_vars_grp.create_group(m_database->get_label_component(0)); water_group.create_vector_dataset(LIQUID_SATURATION_DSET, uvars(liquid_saturation)); water_group.create_vector_dataset(AQUEOUS_CONC_DSET, uvars(water_aqueous_concentration)); water_group.create_vector_dataset(SOLID_CONC_DSET, uvarsi(solid_concentration, 0)); if (m_vars->component_has_gas(0)) { water_group.create_vector_dataset(PRESSURE_DSET, uvarsi(pressure_main_variables, 0)); } water_group.create_vector_dataset(CAP_PRESSURE_DSET, uvars(capillary_pressure)); } for (index_t aq_component: m_database->range_aqueous_component()) { auto aqcomp_group = main_vars_grp.create_group(m_database->get_label_component(aq_component)); aqcomp_group.create_vector_dataset(AQUEOUS_CONC_DSET, uvarsi(aqueous_concentration, aq_component)); aqcomp_group.create_vector_dataset(SOLID_CONC_DSET, uvarsi(solid_concentration, aq_component)); if (m_vars->component_has_gas(aq_component)) { aqcomp_group.create_vector_dataset(PRESSURE_DSET, uvarsi(pressure_main_variables, aq_component)); } } } void UnsaturatedHDF5Saver::UnsaturatedHDF5SaverImpl::save_chemical_solution( hdf5::Group& timestep_grp ) { auto chem_grp = timestep_grp.create_group(CHEMISTRY_SOLUTION_GRPNAME); for (auto node: m_vars->get_mesh()->range_nodes()) { if (m_vars->get_adim_solution(node).is_valid) { save_adimensional_system_solution(chem_grp, std::to_string(node), m_vars->get_adim_solution(node)); } } } // time to get ugly and use macro // this is simply a quick wrapper that call the save_eigen matrix function // It avoids all the boilerplate #define save_transport_property(name, var) \ transport_grp.create_vector_dataset(name, uvars(var)) void UnsaturatedHDF5Saver::UnsaturatedHDF5SaverImpl::save_transport_properties( hdf5::Group& timestep_grp ) { auto transport_grp = timestep_grp.create_group(TRANSPORT_PROPERTIES_GRPNAME); save_transport_property(POROSITY_DSET, porosity); save_transport_property(LIQUID_DIFFUSIVITY_DSET, liquid_diffusivity); save_transport_property(REL_LIQUID_DIFFUSIVITY_DSET, relative_liquid_diffusivity); save_transport_property(LIQUID_PERMEABILITY_DSET, liquid_permeability); save_transport_property(REL_LIQUID_PERMEABILITY_DSET, relative_liquid_permeability); save_transport_property(RESISTANCE_GAS_DIFFUSIVITY_DSET, resistance_gas_diffusivity); save_transport_property(REL_GAS_DIFFUSIVITY_DSET, relative_gas_diffusivity); } #undef save_transport_property // we remove the ugly macro, no one saws anything :) #undef uvars #undef uvarsi void UnsaturatedHDF5Saver::UnsaturatedHDF5SaverImpl::init_file( const units::UnitsSet& the_units ) { hdf5::File the_file = hdf5::File::open(m_filepath, hdf5::OpenMode::CreateTruncate); save_mesh(the_file, MESH_GRPNAME, m_vars->get_mesh()); save_database_labels(the_file, DATABASE_GRPNAME, m_vars->get_database()); std::array units_values = { units::scaling_factor(the_units.length), units::scaling_factor(the_units.mass), units::scaling_factor(the_units.quantity) }; the_file.create_scalar_attribute(UNIT_ATTRIBUTE, units_values); } // =========================================================================== // =========================================================================== // Reader // ======= struct SPECMICP_DLL_LOCAL UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl { UnsaturatedHDF5ReaderImpl(const std::string& name): m_file(hdf5::File::open(name, hdf5::OpenMode::OpenReadOnly)), m_timesteps(m_file) { } units::UnitsSet get_units(); AdimensionalSystemSolution get_adim_solution( scalar_t timestep, index_t node ); AdimensionalSystemSolution get_adim_solution( std::string timestep, index_t node ); void initialize_variables( scalar_t timestep, reactmicp::systems::unsaturated::UnsaturatedVariables* vars ); void read_main_variables( const hdf5::GroupPath& timestep_group, reactmicp::systems::unsaturated::UnsaturatedVariables* vars ); void read_chemical_solutions( const hdf5::GroupPath& timestep_group, reactmicp::systems::unsaturated::UnsaturatedVariables* vars ); void read_transport_properties( const hdf5::GroupPath& timestep_group, reactmicp::systems::unsaturated::UnsaturatedVariables* vars ); //! \brief Return a main variable against x Vector main_variable_vs_x( const std::string& timestep, const std::string& component, const std::string& variable ); //! \brief Return a main variable against t Vector main_variable_vs_t( index_t node, const std::string& component, const std::string& variable ); //! \brief Open a timestep group hdf5::Group open_timestep(const std::string& timestep); //! \brief Open a timestep group hdf5::Group open_timestep(const scalar_t& timestep); //! \brief Open the main variables group hdf5::Group open_main_variables(const std::string& timestep); //! \brief Open the main variables group for a component hdf5::Group open_main_variables_component( const std::string& timestep, const std::string& component ); //! \brief Open the transport variables group hdf5::Group open_transport_variables(const std::string& timestep); //! \brief Return a main variable against x Vector transport_variable_vs_x( const std::string& timestep, const std::string& variable ); //! \brief Return a main variable against t Vector transport_variable_vs_t( index_t node, const std::string& variable ); + mesh::Mesh1DPtr get_mesh() { + return read_mesh(m_file, MESH_GRPNAME); + } + hdf5::Group open_chemistry_solutions(const std::string& timestep); hdf5::File m_file; HDF5Timesteps m_timesteps; }; UnsaturatedHDF5Reader::UnsaturatedHDF5Reader( const std::string &filepath ): m_impl(utils::make_pimpl(filepath)) { } UnsaturatedHDF5Reader::~UnsaturatedHDF5Reader() = default; //! \brief Initialize variables from a saved timestep //! //! The Mesh and the database must already be ok void UnsaturatedHDF5Reader::initialize_variables( scalar_t timestep, reactmicp::systems::unsaturated::UnsaturatedVariables* vars ) { return m_impl->initialize_variables(timestep, vars); } const HDF5Timesteps& UnsaturatedHDF5Reader::get_timesteps() const { return m_impl->m_timesteps; } units::UnitsSet UnsaturatedHDF5Reader::get_units() { return m_impl->get_units(); } AdimensionalSystemSolution UnsaturatedHDF5Reader::get_adim_solution( scalar_t timestep, index_t node ) { return m_impl->get_adim_solution(timestep, node); } AdimensionalSystemSolution UnsaturatedHDF5Reader::get_adim_solution( std::string timestep, index_t node ) { return m_impl->get_adim_solution(timestep, node); } Vector UnsaturatedHDF5Reader::main_variable_vs_x( const std::string& timestep, const std::string& component, const std::string& variable ) { return m_impl->main_variable_vs_x(timestep, component, variable); } Vector UnsaturatedHDF5Reader::main_variable_vs_x( scalar_t timestep, const std::string& component, const std::string& variable ) { const std::string str_timestep = m_impl->m_timesteps.get_string(timestep); return m_impl->main_variable_vs_x(str_timestep, component, variable); } Vector UnsaturatedHDF5Reader::main_variable_vs_t( index_t node, const std::string& component, const std::string& variable ) { return m_impl->main_variable_vs_t(node, component, variable); } Vector UnsaturatedHDF5Reader::transport_variable_vs_x( const std::string& timestep, const std::string& variable ) { return m_impl->transport_variable_vs_x(timestep, variable); } Vector UnsaturatedHDF5Reader::transport_variable_vs_x( scalar_t timestep, const std::string& variable ) { const std::string str_timestep = m_impl->m_timesteps.get_string(timestep); return m_impl->transport_variable_vs_x(str_timestep, variable); } Vector UnsaturatedHDF5Reader::transport_variable_vs_t( index_t node, const std::string& variable ) { return m_impl->transport_variable_vs_t(node, variable); } +mesh::Mesh1DPtr UnsaturatedHDF5Reader::get_mesh() +{ + return m_impl->get_mesh(); +} + // =========== Implementation =============================== units::UnitsSet UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::get_units() { units::UnitsSet the_units; // quantity conversion factor was not solved in early version // really early, can probably be simplified at some point std::vector conversion_factor = m_file.read_scalar_attribute(UNIT_ATTRIBUTE); the_units.length = units::from_scaling_factor(conversion_factor[0]); the_units.mass = units::from_scaling_factor(conversion_factor[1]); if (conversion_factor.size() == 2) { WARNING << "Units for quantity of matter was not recorded, assuming moles."; } else { the_units.quantity = units::from_scaling_factor(conversion_factor[2]); } return the_units; } void UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::initialize_variables( scalar_t timestep, reactmicp::systems::unsaturated::UnsaturatedVariables *vars ) { auto name_group = m_timesteps.get_string(timestep); auto timestep_group = m_file.open_group(name_group); read_main_variables(timestep_group, vars); read_chemical_solutions(timestep_group, vars); read_transport_properties(timestep_group, vars); } // ugly, but more readable at the end #define uvars(var_name) \ vars->get_ ## var_name ().variable #define uvarsi(var_name, index) \ vars->get_ ## var_name (index).variable void UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::read_main_variables( const hdf5::GroupPath& timestep_group, reactmicp::systems::unsaturated::UnsaturatedVariables* vars ) { hdf5::Group main_vars_grp = timestep_group.open_group(MAIN_VARIABLES_GRPNAME); database::RawDatabasePtr raw_database = vars->get_database(); { // Water auto group = main_vars_grp.open_group(raw_database->get_label_component(0)); uvars(liquid_saturation) = group.read_vector_dataset(LIQUID_SATURATION_DSET); uvars(water_aqueous_concentration) = group.read_vector_dataset(AQUEOUS_CONC_DSET); uvarsi(solid_concentration, 0) = group.read_vector_dataset(SOLID_CONC_DSET); uvars(capillary_pressure) = group.read_vector_dataset(CAP_PRESSURE_DSET); if (vars->component_has_gas(0)) { uvarsi(pressure_main_variables, 0) = group.read_vector_dataset(PRESSURE_DSET); } } for (auto component: raw_database->range_aqueous_component()) { auto group = main_vars_grp.open_group( raw_database->get_label_component(component)); uvarsi(aqueous_concentration, component) = group.read_vector_dataset(AQUEOUS_CONC_DSET); uvarsi(solid_concentration, component) = group.read_vector_dataset(SOLID_CONC_DSET); if (vars->component_has_gas(component)) { uvarsi(pressure_main_variables, component) = group.read_vector_dataset(PRESSURE_DSET); } } } void UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::read_chemical_solutions( const hdf5::GroupPath& timestep_group, reactmicp::systems::unsaturated::UnsaturatedVariables* vars ) { hdf5::Group chem_group = timestep_group.open_group(CHEMISTRY_SOLUTION_GRPNAME); database::RawDatabasePtr raw_database = vars->get_database(); mesh::Mesh1DPtr the_mesh = vars->get_mesh(); for (auto node: the_mesh->range_nodes()) { vars->set_adim_solution(node, read_adimensional_system_solution(chem_group, std::to_string(node))); } } // time to get ugly and use macro // this is simply a quick wrapper that call the read_eigen_matrix function // It avoids all the boilerplate #define read_transport_property(name, var) \ uvars(var) = trans_group.read_vector_dataset(name); void UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::read_transport_properties( const hdf5::GroupPath& timestep_group, reactmicp::systems::unsaturated::UnsaturatedVariables* vars ) { hdf5::Group trans_group = timestep_group.open_group(TRANSPORT_PROPERTIES_GRPNAME); read_transport_property(POROSITY_DSET, porosity); read_transport_property(LIQUID_DIFFUSIVITY_DSET, liquid_diffusivity); read_transport_property(REL_LIQUID_DIFFUSIVITY_DSET, relative_liquid_diffusivity); read_transport_property(LIQUID_PERMEABILITY_DSET, liquid_permeability); read_transport_property(REL_LIQUID_PERMEABILITY_DSET, relative_liquid_permeability); read_transport_property(RESISTANCE_GAS_DIFFUSIVITY_DSET, resistance_gas_diffusivity); read_transport_property(REL_GAS_DIFFUSIVITY_DSET, relative_gas_diffusivity); } #undef read_transport_property // we remove the ugly macro, no one saws anything :) #undef uvars #undef uvarsi hdf5::Group UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::open_timestep( const scalar_t& timestep ) { auto str_timestep = m_timesteps.get_string(timestep); return m_file.open_group(str_timestep); } hdf5::Group UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::open_timestep( const std::string& timestep ) { return m_file.open_group(timestep); } hdf5::Group UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::open_main_variables( const std::string& timestep ) { auto timestep_grp = open_timestep(timestep); return timestep_grp.open_group(MAIN_VARIABLES_GRPNAME); } hdf5::Group UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::open_main_variables_component( const std::string& timestep, const std::string& component ) { auto main_vars_grp = open_main_variables(timestep); return main_vars_grp.open_group(component); } //! \brief Return a main variable against x Vector UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::main_variable_vs_x( const std::string& timestep, const std::string& component, const std::string& variable ) { auto comp_grp = open_main_variables_component(timestep, component); return comp_grp.read_vector_dataset(variable); } //! \brief Return a main variable against t Vector UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::main_variable_vs_t( index_t node, const std::string& component, const std::string& variable ) { Vector data(m_timesteps.size()); index_t cnt = 0; for (auto it: m_timesteps) { Vector timestep_vector = main_variable_vs_x(it.second, component, variable); data(cnt) = timestep_vector(node); ++cnt; } return data; } hdf5::Group UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::open_transport_variables( const std::string& timestep ) { auto timestep_grp = open_timestep(timestep); return timestep_grp.open_group(TRANSPORT_PROPERTIES_GRPNAME); } Vector UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::transport_variable_vs_x( const std::string& timestep, const std::string& variable ) { auto grp = open_transport_variables(timestep); return grp.read_vector_dataset(variable); } Vector UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::transport_variable_vs_t( index_t node, const std::string& variable ) { Vector data(m_timesteps.size()); index_t cnt = 0; for (auto it: m_timesteps) { Vector timestep_vector = transport_variable_vs_x(it.second, variable); data(cnt) = timestep_vector(node); ++cnt; } return data; } hdf5::Group UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::open_chemistry_solutions( const std::string& timestep ) { auto timestep_grp = open_timestep(timestep); return timestep_grp.open_group(CHEMISTRY_SOLUTION_GRPNAME); } AdimensionalSystemSolution UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::get_adim_solution( scalar_t timestep, index_t node ) { auto str_timestep = m_timesteps.get_string(timestep); return get_adim_solution(str_timestep, node); } AdimensionalSystemSolution UnsaturatedHDF5Reader::UnsaturatedHDF5ReaderImpl::get_adim_solution( std::string timestep, index_t node ) { auto chem_grp = open_chemistry_solutions(timestep); return read_adimensional_system_solution(chem_grp, std::to_string(node)); } } //end namespace io } //end namespace specmicp diff --git a/src/reactmicp/io/hdf5_unsaturated.hpp b/src/reactmicp/io/hdf5_unsaturated.hpp index 23dd47f..b8382ea 100644 --- a/src/reactmicp/io/hdf5_unsaturated.hpp +++ b/src/reactmicp/io/hdf5_unsaturated.hpp @@ -1,176 +1,182 @@ /* ============================================================================= Copyright (c) 2014 - 2016 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_IO_REACTMICP_HDF5_UNSATURATED_HPP #define SPECMICP_IO_REACTMICP_HDF5_UNSATURATED_HPP //! \file reactmicp/io/hdf5_unsaturated.hpp //! \brief HDF5 formatter for the unsaturated system #include "specmicp_common/types.hpp" #include "specmicp_common/pimpl_ptr.hpp" + +#include "dfpm/meshes/mesh1dfwd.hpp" + #include namespace specmicp { struct AdimensionalSystemSolution; namespace units { struct UnitsSet; } //end namespace units namespace reactmicp { namespace systems { namespace unsaturated { class UnsaturatedVariables; } //end namespace unsaturated } //end namespace systems } //end namespace reactmicp namespace io { class HDF5File; class HDF5Timesteps; //! \brief Save the unsaturated set of variables in HDF5 format //! class SPECMICP_DLL_PUBLIC UnsaturatedHDF5Saver { using UnsaturatedVariables = reactmicp::systems::unsaturated::UnsaturatedVariables; public: UnsaturatedHDF5Saver( const std::string& filename, std::shared_ptr vars, const units::UnitsSet& the_units ); ~UnsaturatedHDF5Saver(); //! \brief Save the variables //! //! All the values will be saved in a new group 'section/name' void save_timestep(scalar_t timestep); private: struct SPECMICP_DLL_LOCAL UnsaturatedHDF5SaverImpl; //! \brief implementation details //! \internal std::unique_ptr m_impl; // delete copy and assignement operator, no need for them UnsaturatedHDF5Saver(const UnsaturatedHDF5Saver& other) = delete; UnsaturatedHDF5Saver& operator= (const UnsaturatedHDF5Saver& other) = delete; }; //! \brief Read saved data from an HDF5 file class SPECMICP_DLL_PUBLIC UnsaturatedHDF5Reader { public: //UnsaturatedHDF5Reader(const HDF5File& file); UnsaturatedHDF5Reader(const std::string& filepath); ~UnsaturatedHDF5Reader(); const HDF5Timesteps& get_timesteps() const; units::UnitsSet get_units(); AdimensionalSystemSolution get_adim_solution( std::string timestep, index_t node ); AdimensionalSystemSolution get_adim_solution( scalar_t timestep, index_t node ); //! \brief Return a main variable against x Vector main_variable_vs_x( scalar_t timestep, const std::string& component, const std::string& variable ); //! \brief Return a main variable against x Vector main_variable_vs_x( const std::string& timestep, const std::string& component, const std::string& variable ); //! \brief Return a main variable against t Vector main_variable_vs_t( index_t node, const std::string& component, const std::string& variable ); //! \brief Return a transport variable against x Vector transport_variable_vs_x( const std::string& timestep, const std::string& variable ); //! \brief Return a transport variable against x Vector transport_variable_vs_x( scalar_t timestep, const std::string& variable ); //! \brief Return a transport variable against t Vector transport_variable_vs_t( index_t node, const std::string& variable ); //! \brief Initialize variables from a saved timestep //! //! The Mesh and the database must already be ok void initialize_variables( scalar_t timestep, reactmicp::systems::unsaturated::UnsaturatedVariables* vars ); + //! \brief Return the mesh saved in the file + mesh::Mesh1DPtr get_mesh(); + private: struct SPECMICP_DLL_LOCAL UnsaturatedHDF5ReaderImpl; utils::pimpl_ptr m_impl; // delete copy and assignement operator UnsaturatedHDF5Reader(const UnsaturatedHDF5Reader& other) = delete; UnsaturatedHDF5Reader& operator= (const UnsaturatedHDF5Reader& other) = delete; }; } //end namespace io } //end namespace specmicp #endif // SPECMICP_IO_REACTMICP_HDF5_UNSATURATED_HPP