diff --git a/src/specmicp_database/data_container.cpp b/src/specmicp_database/data_container.cpp index 968b152..55f206e 100644 --- a/src/specmicp_database/data_container.cpp +++ b/src/specmicp_database/data_container.cpp @@ -1,286 +1,287 @@ /* ============================================================================= 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 "data_container.hpp" #include "errors.hpp" #include "config_database.hpp" namespace std { template <> struct hash { size_t operator() (const specmicp::database::Metadata& meta_data) const { auto hasher = hash(); return hasher(meta_data.path)+hasher(meta_data.name)+hasher(meta_data.version); } }; } namespace specmicp { namespace database { const std::string water_label{LABEL_WATER}; //!< The water label in the database const std::string electron_label{LABEL_ELECTRON}; //!< The electron label in the database +units::UnitsSet const database_units {units::CMG_units}; // Conversion factor // // conversion from g/mol to (mass_unit)/mol scalar_t SPECMICP_CONST_F scaling_factor_molar_mass(units::MassUnit mass_unit) { scalar_t factor = 1.0; if (mass_unit == units::MassUnit::kilogram) factor = 1e-3; return factor; } // conversion from g/mol to (mass_unit)/(mol_unit) scalar_t SPECMICP_CONST_F scaling_factor_molar_mass(const units::UnitsSet& units_set) { scalar_t factor = 1.0; if (units_set.mass == units::MassUnit::kilogram) factor = 1e-3; if (units_set.quantity == units::QuantityUnit::millimoles) factor *= 1e-3; return factor; } scalar_t DataContainer::molar_volume_mineral(index_t m, units::LengthUnit length_unit) const { const auto& molar_volume = minerals.molar_volume(m); if (molar_volume < 0) { throw db_noninitialized_value("molar volume", minerals.get_label(m)); } return scaling_molar_volume(length_unit)*molar_volume; } scalar_t DataContainer::molar_volume_mineral(index_t m, const units::UnitsSet& units_set) const { const auto& molar_volume = minerals.molar_volume(m); if (molar_volume < 0) { throw db_noninitialized_value("molar volume", minerals.get_label(m)); } return scaling_molar_volume(units_set)*molar_volume; } scalar_t DataContainer::molar_volume_mineral_kinetic(index_t m, units::LengthUnit length_unit) const { const auto& molar_volume = minerals_kinetic.molar_volume(m); if (molar_volume < 0) { throw db_noninitialized_value("molar volume", minerals_kinetic.get_label(m)); } return scaling_molar_volume(length_unit)*molar_volume; } scalar_t DataContainer::molar_volume_mineral_kinetic(index_t m, const units::UnitsSet& units_set) const { const auto& molar_volume = minerals_kinetic.molar_volume(m); if (molar_volume < 0) { throw db_noninitialized_value("molar volume", minerals_kinetic.get_label(m)); } return scaling_molar_volume(units_set)*molar_volume; } scalar_t DataContainer::scaling_molar_volume(units::LengthUnit length_unit) const { scalar_t scaling = 1.0; // value stored in cm^3/mol if (length_unit == units::LengthUnit::meter) scaling = 1e-6; else if (length_unit == units::LengthUnit::decimeter) scaling = 1e-3; return scaling; } scalar_t DataContainer::scaling_molar_volume(const units::UnitsSet& units_set) const { scalar_t scaling = 1.0; // value stored in cm^3/mol if (units_set.length == units::LengthUnit::meter) scaling = 1e-6; else if (units_set.length == units::LengthUnit::decimeter) scaling = 1e-3; if (units_set.quantity == units::QuantityUnit::millimoles) scaling *= 1e-3; return scaling; } //! \brief Return the molar volume (m^3/mol) of a mineral scalar_t DataContainer::molar_volume_mineral(index_t m) const { const auto& molar_volume = minerals.molar_volume(m); if (molar_volume < 0) { throw db_noninitialized_value("molar volume", minerals.get_label(m)); } return 1e-6*molar_volume; } //! \brief Return the molar volume (m^3/mol) of a mineral governed by kinetic scalar_t DataContainer::molar_volume_mineral_kinetic(index_t m) const { const auto& molar_volume = minerals_kinetic.molar_volume(m); if (molar_volume < 0) { throw db_noninitialized_value("molar volume", minerals_kinetic.get_label(m)); } return 1e-6*molar_volume; } //! Return the molar mass of 'component' in 'mass_unit'/mol scalar_t DataContainer::molar_mass_basis(index_t component, units::MassUnit mass_unit) const NOEXCEPT { const scalar_t scaling = scaling_factor_molar_mass(mass_unit); return components.molar_mass(component)*scaling; } //! Return the molar mass of 'component' in 'mass_unit'/mol scalar_t DataContainer::molar_mass_basis(index_t component, const units::UnitsSet& units_set) const NOEXCEPT { const scalar_t scaling = scaling_factor_molar_mass(units_set); return components.molar_mass(component)*scaling; } //! \brief Return the molar mass (kg/mol) of a mineral scalar_t DataContainer::molar_mass_mineral(index_t mineral) const { return 1e-3*components.molar_mass_compounds(minerals.get_nu_row(mineral)); } //! \brief Return the molar mass (kg/mol) of a mineral governed by kinetic scalar_t DataContainer::molar_mass_mineral_kinetic(index_t mineral) const { return 1e-3*components.molar_mass_compounds(minerals_kinetic.get_nu_row(mineral)); } //! Return the molar mass of 'mineral' in 'mass_unit'/mol scalar_t DataContainer::molar_mass_mineral(index_t mineral, units::MassUnit mass_unit) const { scalar_t scaling = scaling_factor_molar_mass(mass_unit); return scaling*components.molar_mass_compounds(minerals.get_nu_row(mineral)); } //! Return the molar mass of 'mineral' in 'mass_unit'/'mol_unit' scalar_t DataContainer::molar_mass_mineral(index_t mineral, const units::UnitsSet& units_set) const { scalar_t scaling = scaling_factor_molar_mass(units_set); return scaling*components.molar_mass_compounds(minerals.get_nu_row(mineral)); } //! Return the molar mass of 'mineral_kinetic' in 'mass_unit'/mol scalar_t DataContainer::molar_mass_mineral_kinetic(index_t mineral_kinetic, units::MassUnit mass_unit) const { scalar_t scaling = scaling_factor_molar_mass(mass_unit); return scaling*components.molar_mass_compounds(minerals_kinetic.get_nu_row(mineral_kinetic)); } //! Return the molar mass of 'mineral_kinetic' in 'mass_unit'/'mol_unit' scalar_t DataContainer::molar_mass_mineral_kinetic(index_t mineral_kinetic, const units::UnitsSet& units_set) const { scalar_t scaling = scaling_factor_molar_mass(units_set); return scaling*components.molar_mass_compounds(minerals_kinetic.get_nu_row(mineral_kinetic)); } //! Return the molar mass (kg/mol) of a compound scalar_t DataContainer::molar_mass_compound(index_t j) const { return 1e-3*components.molar_mass_compounds(compounds.get_nu_row(j)); } //! Return the molar mass of a compound scalar_t DataContainer::molar_mass_compound(index_t j, units::MassUnit mass_unit) const { scalar_t scaling = scaling_factor_molar_mass(mass_unit); return scaling*components.molar_mass_compounds(compounds.get_nu_row(j)); } //! Return the molar mass of a compound scalar_t DataContainer::molar_mass_compound(index_t j, const units::UnitsSet& units_set) const { scalar_t scaling = scaling_factor_molar_mass(units_set); return scaling*components.molar_mass_compounds(compounds.get_nu_row(j)); } //! Return the molar mass (kg/mol) of an aqueous species scalar_t DataContainer::molar_mass_aqueous(index_t j) const { return 1e-3*components.molar_mass_compounds(aqueous.get_nu_row(j)); } //! Return the molar mass of an aqueous species scalar_t DataContainer::molar_mass_aqueous(index_t j, units::MassUnit mass_unit) const { scalar_t scaling = scaling_factor_molar_mass(mass_unit); return scaling*components.molar_mass_compounds(aqueous.get_nu_row(j)); } //! Return the molar mass of an aqueous species scalar_t DataContainer::molar_mass_aqueous(index_t j, const units::UnitsSet& units_set) const { scalar_t scaling = scaling_factor_molar_mass(units_set); return scaling*components.molar_mass_compounds(aqueous.get_nu_row(j)); } //! Return the molar mass (kg/mol) of a sorbed species scalar_t DataContainer::molar_mass_sorbed(index_t j) const { return 1e-3*components.molar_mass_compounds(sorbed.get_nu_row(j)); } //! Return the molar mass of a sorbed species scalar_t DataContainer::molar_mass_sorbed(index_t j, units::MassUnit mass_unit) const { scalar_t scaling = scaling_factor_molar_mass(mass_unit); return scaling*components.molar_mass_compounds(sorbed.get_nu_row(j)); } //! Return the molar mass of a sorbed species scalar_t DataContainer::molar_mass_sorbed(index_t j, const units::UnitsSet& units_set) const { scalar_t scaling = scaling_factor_molar_mass(units_set); return scaling*components.molar_mass_compounds(sorbed.get_nu_row(j)); } bool DataContainer::is_valid() const { bool is_valid = (components.is_valid() and aqueous.is_valid() and minerals.is_valid() and minerals_kinetic.is_valid() and gas.is_valid() and sorbed.is_valid() and compounds.is_valid() and elements.size() == nb_component() ); if (m_fixed_hash > 0) is_valid = is_valid and (get_hash() == m_fixed_hash); return is_valid; } size_t DataContainer::get_hash() const { size_t hash_db = std::hash()(metadata); // the factors 2 are to distinguish cases were species are simply moved to another list hash_db += ( components.get_hash() + 2*aqueous.get_hash() + minerals.get_hash() + 2*minerals_kinetic.get_hash() + gas.get_hash() + sorbed.get_hash() + compounds.get_hash() ); return hash_db; } } // end namespace database } // end namespace specmicp diff --git a/src/specmicp_database/data_container.hpp b/src/specmicp_database/data_container.hpp index a8e320e..5563970 100644 --- a/src/specmicp_database/data_container.hpp +++ b/src/specmicp_database/data_container.hpp @@ -1,500 +1,502 @@ /* ============================================================================= 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_DATABASE_DATACONTAINER_HPP #define SPECMICP_DATABASE_DATACONTAINER_HPP //! \file data_container.hpp //! \brief Storage class for the thermodynamics database #include "specmicp_common/types.hpp" #include "specmicp_common/physics/units.hpp" #include "species/element_list.hpp" #include "species/component_list.hpp" #include "species/aqueous_list.hpp" #include "species/mineral_list.hpp" #include "species/gas_list.hpp" #include "species/sorbed_list.hpp" #include "species/compounds_list.hpp" namespace specmicp { namespace database { extern const std::string water_label; //!< The water label in the database constexpr index_t water_id{0}; //!< Index of water in the database extern const std::string electron_label; //!< The electron label in the database constexpr index_t electron_id{1}; //!< Index of the electron in the database +extern const units::UnitsSet database_units; // The units used in the database + //! \brief Information used to trace the database struct SPECMICP_DLL_PUBLIC Metadata { std::string path; //!< path to the database std::string name; //!< name of the database std::string version; //!< version of the database }; //! \brief Storage class - Contains the database //! //! The database is shared by (almost) everything else using a shared_ptr. //! This class is only a container. It should not be modified by hand but //! using the algorithms provided by specimicp::database::Database. //! //! \sa specimicp::database::Database struct SPECMICP_DLL_PUBLIC DataContainer { DataContainer() {} Metadata metadata; //!< Metada, name path and version of the database //! \name Element //! \brief The element list // ======================== //! @{ ElementList elements; //!< The elements //! \brief Return the id of a component given the element index_t get_id_component_from_element(const std::string& element) const { return elements.get_id_component(element); } //! \brief Return the label of a component given the element std::string get_label_component_from_element(const std::string& element) const { return get_label_component(get_id_component_from_element(element)); } //! @} //! \name Basis //! \brief The basis contains the components // ========================================== //! @{ ComponentList components; //!< The basis //! \brief Return the number of components in the basis index_t nb_component() const {return components.size();} //! \brief Return the number of all aqueous components, not including water and electron index_t nb_aqueous_components() const noexcept {return nb_component()-2;} //! \brief Return the id of component 'label' //! //! Return no_species if the component does not exist index_t get_id_component(const std::string& label) const { return components.get_id(label); } //! \brief Return the id of component 'label' std::string get_label_component(index_t id) const{ return components.get_label(id); } //! \brief Return the molar mass of 'component' in kg/mol scalar_t molar_mass_basis(index_t component) const NOEXCEPT {return 1e-3*components.molar_mass(component);} //! \brief Return the molar mass of 'component' in 'mass_unit'/mol scalar_t molar_mass_basis(index_t component, units::MassUnit mass_unit) const NOEXCEPT SPECMICP_DEPRECATED("use complete unit"); //! \brief Return the molar mass of 'component' in 'mass_unit'/'quantity unit' scalar_t molar_mass_basis(index_t component, const units::UnitsSet& units_set) const NOEXCEPT; //! \brief Return the charge of a component const scalar_t& charge_component(index_t i) const NOEXCEPT {return components.charge(i);} //! \brief Return the 'a_i' Debye-Huckel parameter for a component const scalar_t& a_debye_component(index_t i) const NOEXCEPT {return components.a_debye(i);} //! \brief Return the 'b_i' extended Debye-Huckel parameter for a component const scalar_t& b_debye_component(index_t i) const NOEXCEPT {return components.b_debye(i);} //! \brief Return the index of the water in the basis constexpr static index_t water_index() noexcept { return water_id; } //! \brief return the index of the electron in the basis constexpr static index_t electron_index() noexcept { return electron_id; } //! \brief Range over the components range_t range_component() const { return components.range();} //! \brief Range over the aqueous components range_t range_aqueous_component() const { return range_t(2, nb_component()); } //! @} //! \name Secondary aqueous species //! \brief The secondary aqueous species // ========================================= //! @{ AqueousList aqueous; //!< The list of aqueous species //! \brief Return the number of aqueous species in the system (not counting components) index_t nb_aqueous() const {return aqueous.size();} //! \brief Return the stoichiometric coefficient of 'i' in the dissociation reaction of species 'j' const scalar_t& nu_aqueous(index_t j, index_t i) const {return aqueous.nu_ji(j, i);} //! \brief Return the logk of dissociation reaction of species 'j' const scalar_t& logk_aqueous(index_t j) const {return aqueous.logk(j);} //! \brief Return the id of aqueous species 'label' //! //! Return no_species if the aqueous species does not exist index_t get_id_aqueous(const std::string& label) const{ return aqueous.get_id(label); } //! \brief Return the id of aqueous species 'label' std::string get_label_aqueous(index_t id) const { return aqueous.get_label(id); } //! \brief Return the charge of a secondary aqueous species const scalar_t& charge_aqueous(index_t j) const NOEXCEPT {return aqueous.charge(j);} //! \brief Return the 'a_i' Debye-Huckel parameter for a secondary aqueous species const scalar_t& a_debye_aqueous(index_t j) const NOEXCEPT {return aqueous.a_debye(j);} //! \brief Return the 'b_i' extended Debye-Huckel parameter for a secondary aqueous species const scalar_t& b_debye_aqueous(index_t j) const NOEXCEPT {return aqueous.b_debye(j);} //! \brief Return true if the corresponding equation is a half-cell reaction bool is_half_cell_reaction(index_t aqueous_species) const NOEXCEPT { return (nu_aqueous(aqueous_species, electron_index()) != 0.0); } //! \brief Range over the secondary aqueous species range_t range_aqueous() const { return aqueous.range();} //! Return the molar mass (kg/mol) of an aqueous species scalar_t molar_mass_aqueous(index_t j) const; //! Return the molar mass of an aqueous species scalar_t molar_mass_aqueous(index_t j, units::MassUnit mass_unit) const SPECMICP_DEPRECATED("use complete unit"); //! Return the molar mass of an aqueous species scalar_t molar_mass_aqueous(index_t j, const units::UnitsSet& units_set) const; //! @} //! \name Compounds species //! \brief The 'compounds' species : strong electrolytes //! ==================================================== //! @{ CompoundList compounds; //!< List of compounds //! \brief return the number of compounds index_t nb_compounds() const {return compounds.size();} //! \brief Return the stoichiometric coefficient of 'i' in the dissociation reaction of species 'j' const scalar_t& nu_compound(index_t j, index_t i) const {return compounds.nu_ji(j, i);} //! \brief Return the id of compounds 'label' //! //! Return 'no_species' if the compound does not exist index_t get_id_compound(const std::string& label) const { return compounds.get_id(label); } //! \brief Return the id of compound 'label' std::string get_label_compound(index_t id) const { return compounds.get_label(id); } //! \brief Range over the sorbed species range_t range_compounds() const { return compounds.range();} //! Return the molar mass (kg/mol) of a compound scalar_t molar_mass_compound(index_t j) const; //! Return the molar mass of a compound scalar_t molar_mass_compound(index_t j, units::MassUnit mass_unit) const SPECMICP_DEPRECATED("use complete unit"); //! Return the molar mass of a compound scalar_t molar_mass_compound(index_t j, const units::UnitsSet& units_set) const; //! @} //! \name Sorbed species //! \brief The adsorbed species // ========================================= //! @{ SorbedList sorbed; //!< The list of sorbed species //! \brief Return the number of sorbed species index_t nb_sorbed() const {return sorbed.size();} //! \brief Return the stoichiometric coefficient of 'i' in the dissociation reaction of species 'j' const scalar_t& nu_sorbed(index_t j, index_t i) const {return sorbed.nu_ji(j, i);} //! \brief Return the logk of dissociation reaction of species 'j' const scalar_t& logk_sorbed(index_t j) const {return sorbed.logk(j);} //! \brief Return the number of sorption sites occupied by a sorbed species const scalar_t& nb_sorption_sites(index_t sorbed_species) const { return sorbed.nb_sorption_site_occupied(sorbed_species); } //! \brief Return the id of sorbed species 'label' //! //! Return no_species if the sorbed species does not exist index_t get_id_sorbed(const std::string& label) const { return sorbed.get_id(label); } //! \brief Return the id of sorbed species 'label' std::string get_label_sorbed(index_t id) const { return sorbed.get_label(id); } //! \brief Range over the sorbed species range_t range_sorbed() const { return sorbed.range();} //! \brief Return true if the corresponding equation is a half-cell reaction bool is_sorbed_half_cell_reaction(index_t sorbed_species) const { return (nu_sorbed(sorbed_species, electron_index()) != 0.0); } //! Return the molar mass (kg/mol) of a sorbed species scalar_t molar_mass_sorbed(index_t j) const; //! Return the molar mass of a sorbed species scalar_t molar_mass_sorbed(index_t j, units::MassUnit mass_unit) const SPECMICP_DEPRECATED("use complete unit"); //! Return the molar mass of a sorbed species scalar_t molar_mass_sorbed(index_t j, const units::UnitsSet& units_set) const ; //! @} //! \name Minerals //! \brief The solid phases // ========================================= //! @{ MineralList minerals; //!< The list of solid phases at equilibrium MineralList minerals_kinetic; //!< The list of solid phases governed by kinetic laws //! \brief Returns the number of solid phases at equilibrium index_t nb_mineral() {return minerals.size();} //! \brief Returns the number of solid phases governed by kinetic laws index_t nb_mineral_kinetic() {return minerals_kinetic.size();} //! \brief Return the stoichiometric coefficient for 'component' in the dissolution reaction of 'mineral' const scalar_t& nu_mineral(index_t mineral, index_t component) const { return minerals.nu_ji(mineral, component); } //! \brief Return the stoichiometric coefficient for 'component' in the dissolution reaction of 'mineral' const scalar_t& nu_mineral_kinetic(index_t mineral, index_t component) const { return minerals_kinetic.nu_ji(mineral, component); } //! \brief Return the logk for the dissolution reaction of 'mineral' const scalar_t& logk_mineral(index_t mineral) const { return minerals.logk(mineral); } //! \brief Return the logk for dissolution reaction of 'mineral' const scalar_t& logk_mineral_kinetic(index_t mineral) const { return minerals_kinetic.logk(mineral); } //! \brief Return true if the corresponding equation is a half-cell reaction bool is_mineral_half_cell_reaction(index_t mineral_species) const { return (nu_mineral(mineral_species, electron_index()) != 0.0); } //! \brief Return true if the corresponding equation is a half-cell reaction bool is_mineral_kinetic_half_cell_reaction(index_t mineral_species) const { return (nu_mineral_kinetic(mineral_species, electron_index()) != 0.0); } //! \brief Return the id of solid phase 'label' //! //! Return no_species if the solid phase does not exist index_t get_id_mineral(const std::string& label) const { return minerals.get_id(label); } //! \brief Return the id of solid phase 'label' std::string get_label_mineral(index_t id) const { return minerals.get_label(id); } //! \brief Return the id of solid phase 'label' //! //! Return no_species if the solid phase does not exist index_t get_id_mineral_kinetic(const std::string& label) const { return minerals_kinetic.get_id(label); } //! \brief Return the id of solid phase 'label' std::string get_label_mineral_kinetic(index_t id) const { return minerals_kinetic.get_label(id); } //! \brief Range over the solid phases (at equilibrium) range_t range_mineral() const { return minerals.range();} //! \brief Range over the solid phases governed by equilibrium range_t range_mineral_kinetic() const { return minerals_kinetic.range();} //! \brief Return the molar mass (kg/mol) of a mineral scalar_t molar_mass_mineral(index_t mineral) const; //! \brief Return the molar mass (kg/mol) of a mineral governed by kinetic scalar_t molar_mass_mineral_kinetic(index_t mineral) const; //! \brief Return the molar mass of 'mineral' in 'mass_unit'/mol scalar_t molar_mass_mineral(index_t mineral, units::MassUnit mass_unit) const SPECMICP_DEPRECATED("use complete unit"); //! \brief Return the molar mass of 'mineral_kinetic' in 'mass_unit'/mol scalar_t molar_mass_mineral_kinetic(index_t mineral_kinetic, units::MassUnit mass_unit) const SPECMICP_DEPRECATED("use complete unit"); //! \brief Return the molar mass of 'mineral' in 'mass_unit'/'mol_unit' scalar_t molar_mass_mineral(index_t mineral, const units::UnitsSet& units_set) const; //! \brief Return the molar mass of 'mineral_kinetic' in 'mass_unit'/'mol_unit' scalar_t molar_mass_mineral_kinetic(index_t mineral_kinetic, const units::UnitsSet& units_set) const; //! \brief Return the scaling factor for the molar volume scalar_t scaling_molar_volume(units::LengthUnit length_unit) const SPECMICP_DEPRECATED("use complete unit"); //! \brief Return the scaling factor for the molar volume scalar_t scaling_molar_volume(const units::UnitsSet& units_set) const; //! \brief Return the molar volume whatever it is scalar_t unsafe_molar_volume_mineral(index_t m) const { return minerals.molar_volume(m); } //! \brief Return the molar volume whatever it is scalar_t unsafe_molar_volume_mineral_kinetic(index_t m) const { return minerals_kinetic.molar_volume(m); } //! \brief Return the molar volume (m^3/mol) of a solid phase scalar_t molar_volume_mineral(index_t m) const; //! \brief Return the molar volume (m^3/mol) of a solid phase governed by kinetic scalar_t molar_volume_mineral_kinetic(index_t m) const; //! \brief Return the molar volume of a solid phase in mol/(length_unit)^3 scalar_t molar_volume_mineral(index_t m, units::LengthUnit length_unit) const SPECMICP_DEPRECATED("use complete unit"); //! \brief Return the molar volume of a solid_phase governed by kinetics in mol/(length_unit)^3 scalar_t molar_volume_mineral_kinetic(index_t m, units::LengthUnit length_unit) const SPECMICP_DEPRECATED("use complete unit"); //! \brief Return the molar volume of a solid phase in 'mol_unit'/(length_unit)^3 scalar_t molar_volume_mineral(index_t m, const units::UnitsSet& units_set) const; //! \brief Return the molar volume of a solid_phase governed by kinetics in 'mol_unit'/(length_unit)^3 scalar_t molar_volume_mineral_kinetic(index_t m, const units::UnitsSet& units_set) const; //! @} //! \name Gas //! \brief The gas present in the system // ========================================= //! @{ GasList gas; //!< The list of gas //! \brief Return the number of gas in the system index_t nb_gas() const {return gas.size();} //! \brief Return the stoichiometric coefficient of 'component' in the dissolution reaction of 'gas_id' const scalar_t& nu_gas(index_t gas_id, index_t component) const {return gas.nu_ji(gas_id, component);} //! \brief Return the logk of he dissolution reaction of 'gas_id' const scalar_t& logk_gas(index_t gas_id) const {return gas.logk(gas_id);} //! \brief Return true if the corresponding equation is a half-cell reaction bool is_gas_half_cell_reaction(index_t gas_species) const { return (nu_gas(gas_species, electron_index()) != 0.0); } //! \brief Return the id of gas 'label' //! //! Return no_species if the gas does not exist index_t get_id_gas(const std::string& label) const { return gas.get_id(label); } //! \brief Return the id of solid phase 'label' std::string get_label_gas(index_t id) const { return gas.get_label(id); } //! \brief Range over the gas phases range_t range_gas() const { return gas.range();} //! @} //! \brief Return true if the database is equal to 'other' //! This is just a test on the names in the database not all the values bool operator ==(const DataContainer& other) { return (get_hash() == other.get_hash()); } // Status // ------ //! \brief Return true if the database is valid; bool is_valid() const; //! \brief Freeze the database void freeze_db() {m_fixed_hash = get_hash();} //! \brief Return a hash of the database //! This only take into account the labels, not the values size_t get_hash() const; private: size_t m_fixed_hash {0}; }; } // end namespace database } // end namespace specmicp #include namespace specmicp { namespace database { //! \brief Pointer to a database //! //! This is a smart pointer so we don't have to worry about memory leaks. //! It is intented to be shared between all the modules that needs it. using RawDatabasePtr = std::shared_ptr; } // end namespace database // export symbol to main namespace using RawDatabasePtr = database::RawDatabasePtr; } // end namespace specmicp //! \name dbBoundsAssert //! \brief assert macros to check the bounds of species // ==================================================== //! @{ //! \def specmicp_assert_component_bounds //! Check the bounds of a compoenent //! //! \param component index of a component //! \param raw_database a valid database #define specmicp_assert_component_bounds(component, raw_database) \ specmicp_assert(component >= 0 and component < raw_database->nb_component()) //! \def specmicp_assert_aqueous_bounds //! Check the bounds of a secondary aqueous species //! //! \param aqueous index of an aqueous species //! \param raw_database a valid database #define specmicp_assert_aqueous_bounds(aqueous, raw_database) \ specmicp_assert(aqueous >= 0 and aqueous < raw_database->nb_aqueous()) //! \def specmicp_assert_compound_bounds //! Check the bounds of a compound //! //! \param compound index of a compound //! \param raw_database a valid database #define specmicp_assert_compound_bounds(compound, raw_database) \ specmicp_assert(compound >= 0 and compound < raw_database->nb_compounds()) //! \def specmicp_assert_mineral_bounds //! Check the bounds of a solid phase with respect to raw_database //! //! \param mineral index of a solid phase //! \param raw_database a valid database #define specmicp_assert_mineral_bounds(mineral, raw_database) \ specmicp_assert(mineral >= 0 and mineral < raw_database->nb_mineral()) //! \def specmicp_assert_mineral_kinetic_bounds //! Check the bounds of a solid phase with respect to raw_database //! //! \param mineral index of a solid phase governed by kinetics //! \param raw_database a valid database #define specmicp_assert_mineral_kinetic_bounds(mineral, raw_database) \ specmicp_assert(mineral >= 0 and mineral < raw_database->nb_mineral_kinetic()) //! \def specmicp_assert_gas_bounds //! Check the bounds of a gas with respect to raw_database //! //! \param gas index of a gas //! \param raw_database a valid database #define specmicp_assert_gas_bounds(gas, raw_database) \ specmicp_assert(gas >= 0 and gas < raw_database->nb_gas()) //! @} #endif // SPECMICP_DATABASE_DATACONTAINER_HPP