From 9c9d3e044a5d5fde71d3f9606a1f939a96be5905 Mon Sep 17 00:00:00 2001 From: Ingmar Schoegl Date: Tue, 6 Sep 2022 11:27:42 -0500 Subject: [PATCH] [base] Augment C++ SolutionArray API --- include/cantera/base/SolutionArray.h | 41 +++++++++++++++++++++------ src/base/SolutionArray.cpp | 42 ++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 8 deletions(-) diff --git a/include/cantera/base/SolutionArray.h b/include/cantera/base/SolutionArray.h index c2a3aaa76c2..e87942de3c0 100644 --- a/include/cantera/base/SolutionArray.h +++ b/include/cantera/base/SolutionArray.h @@ -21,7 +21,7 @@ namespace Cantera class Solution; -/** +/*! * A container class providing a convenient interface for representing many * thermodynamic states using the same Solution object. C++ SolutionArray objects are * one-dimensional by design; extensions to multi-dimensional arrays need to be @@ -45,14 +45,14 @@ class SolutionArray new SolutionArray(sol, size, meta)); } - /** + /*! * Initialize SolutionArray with independent memory management * * @param extra Names of auxiliary data */ void initialize(const std::vector& extra={}); - /** + /*! * Initialize SolutionArray object with mapped memory * * @param data Pointer to mapped memory address @@ -65,14 +65,38 @@ class SolutionArray size_t stride, const std::vector>& offsets); - /** + /*! * Size of SolutionArray (number of entries) */ int size() const { return m_size; } - /** + /*! + * SolutionArray meta data. + */ + AnyMap& meta() { + return m_meta; + } + + /*! + * Update the buffered index used to access entries. + */ + void setIndex(size_t index); + + /*! + * Retrieve the state vector for a single entry. If index is valid, it is updated; + * otherwise, the last previously used index is referenced. + */ + vector_fp getState(size_t index=npos); + + /*! + * Retrieve auxiliary data for a single entry. If index is valid, it is updated; + * otherwise, the last previously used index is referenced. + */ + std::map getAuxiliary(size_t index=npos); + + /*! * Save the current SolutionArray to a container file. * * @param fname Name of output container file @@ -80,7 +104,7 @@ class SolutionArray */ void save(const std::string& fname, const std::string& id); - /** + /*! * Restore SolutionArray from a container file. * * @param fname Name of container file @@ -99,8 +123,9 @@ class SolutionArray size_t m_size; //!< Number of entries in SolutionArray size_t m_stride; //!< Stride between SolutionArray entries AnyMap m_meta; //!< Metadata - bool m_managed = false; //!< Flag indicating whether memory is externally managed + size_t m_index = npos; //!< Buffered index + bool m_managed = false; //!< Flag indicating whether memory is externally managed shared_ptr m_work; //!< Work vector holding states (if not managed) double* m_data; //!< Memory location holding state information (may be augmented) std::map> m_other; //!< Auxiliary data @@ -109,7 +134,7 @@ class SolutionArray }; -// /** +// /*! // * Create a SolutionArray object with independent memory management // * // * @param sol The Solution object associated with state information diff --git a/src/base/SolutionArray.cpp b/src/base/SolutionArray.cpp index 640f021215f..b06937c94f1 100644 --- a/src/base/SolutionArray.cpp +++ b/src/base/SolutionArray.cpp @@ -109,6 +109,48 @@ void SolutionArray::initialize( } } +void SolutionArray::setIndex(size_t index) +{ + if (m_size == 0) { + throw CanteraError("SolutionArray::setIndex", + "Unable to set index in empty SolutionArray."); + } else if (index == npos) { + if (m_index == npos) { + throw CanteraError("SolutionArray::setIndex", + "Both current and buffered indices are invalid."); + } + return; + } else if (index == m_index) { + return; + } else if (index >= m_size) { + throw IndexError("SolutionArray::setIndex", "entries", index, m_size - 1); + } + m_index = index; + size_t nState = m_sol->thermo()->stateSize(); + m_sol->thermo()->restoreState(nState, &m_data[m_index * m_stride]); +} + +vector_fp SolutionArray::getState(size_t index) +{ + setIndex(index); + size_t nState = m_sol->thermo()->stateSize(); + vector_fp out(nState); + m_sol->thermo()->saveState(out); + // std::copy(&m_data[offset], &m_data[offset + nState], out.begin()); + return out; +} + +std::map SolutionArray::getAuxiliary(size_t index) +{ + setIndex(index); + std::map out; + for (auto& item : m_other) { + auto& extra = *item.second; + out[item.first] = extra[m_index]; + } + return out; +} + void SolutionArray::save(const std::string& fname, const std::string& id) { throw CanteraError("SolutionArray::save", "Not implemented.");