diff --git a/include/tadah/mlip/structure.h b/include/tadah/mlip/structure.h index b47cfa7acac39eb0a724019eef06797010e23669..f0c665370585f0505772312aa11bfb3549eebfcc 100644 --- a/include/tadah/mlip/structure.h +++ b/include/tadah/mlip/structure.h @@ -6,7 +6,7 @@ #include <string> #include <fstream> #include <stdexcept> -#include <iterator> +#include <iterator> // for std::forward_iterator_tag // HPC types (Matrix3d, stress_type) come from here: #include <tadah/core/periodic_table.h> @@ -16,8 +16,8 @@ // Forward-declare classes to avoid circular includes namespace tadah { namespace mlip { -class Atom; // Defined in "atom.h" -class StructureDB; // Defined in "structure_db.h" +class Atom; // We'll define it in "atom.h" +class StructureDB; // We'll define it in "structure_db.h" } // namespace mlip } // namespace tadah @@ -25,7 +25,7 @@ namespace tadah { namespace mlip { /** - * @brief Manages a subrange of SoA arrays used for storing atoms. + * @brief Represents a subrange of SoA arrays for storing atoms. */ class Structure { public: @@ -42,16 +42,26 @@ public: double T = 0.0; double eweight = 1.0, fweight = 1.0, sweight = 1.0; - // Tracks how many atoms are currently stored in this structure’s subrange + /** + * @brief Returns the number of atoms currently stored in this structure’s subrange. + */ size_t natoms() const { return size_; } + /** + * @brief Exposes the SoA offset for mapping local atom indices to global arrays. + * + * This method is added to allow external classes (e.g. neighbor logic) + * to compute global indices: globalAtom = offset() + localAtom. + */ + inline size_t offset() const { return offset_; } + // -------------------------------------------------- // Access to individual Atom // -------------------------------------------------- Atom operator()(size_t i); const Atom operator()(size_t i) const; - // Adds an atom to the SoA subrange + // Add an atom to SoA void addAtom(int Z, double xVal, double yVal, double zVal, double fxVal, double fyVal, double fzVal); @@ -89,16 +99,16 @@ public: class iterator { public: using iterator_category = std::forward_iterator_tag; - using value_type = Atom; + using value_type = Atom; ///< Dereference yields an Atom using difference_type = std::ptrdiff_t; - using pointer = Atom*; - using reference = Atom; + using pointer = Atom*; ///< Not strictly used + using reference = Atom; ///< Returns by value (a lightweight handle) iterator(Structure* structure = nullptr, size_t index = 0) : structure_(structure), index_(index) {} - // Declaration only; definition is in structure_inl.h + // Declaration only; definition will be in structure_inl.h reference operator*() const; // Pre-increment @@ -130,7 +140,7 @@ public: class const_iterator { public: using iterator_category = std::forward_iterator_tag; - using value_type = Atom; + using value_type = Atom; using difference_type = std::ptrdiff_t; using pointer = const Atom*; using reference = const Atom; @@ -139,7 +149,7 @@ public: : structure_(structure), index_(index) {} - // Declaration only; definition is in structure_inl.h + // Declaration only; definition will be in structure_inl.h reference operator*() const; // Pre-increment @@ -166,7 +176,6 @@ public: const Structure* structure_ = nullptr; size_t index_ = 0; }; - inline iterator begin() { return iterator(this, 0); } inline iterator end() { return iterator(this, size_); } diff --git a/include/tadah/mlip/structure_inl.h b/include/tadah/mlip/structure_inl.h index 29e320b293625599c43bdfaeb502a3f72d5d61f6..b49cfb89dc4b02e3ccb97ee27e4dd73cf226062a 100644 --- a/include/tadah/mlip/structure_inl.h +++ b/include/tadah/mlip/structure_inl.h @@ -11,8 +11,6 @@ namespace tadah { namespace mlip { -// Inline definitions of Structure methods that reference Atom or SoA: - inline Structure::Structure() : db_(nullptr), offset_(0), size_(0), capacity_(0) {} @@ -25,9 +23,6 @@ inline Atom Structure::operator()(size_t i) { return Atom(this, i); } inline const Atom Structure::operator()(size_t i) const { - // Const-cast is used so Atom can reference internal data. - // The handle itself does not permit non-const modifications unless - // the structure is also non-const. return Atom(const_cast<Structure*>(this), i); } @@ -117,7 +112,6 @@ inline int Structure::read(std::ifstream &ifs) int zVal; double xx,yy,zz, fxx,fyy,fzz; tmp >> zVal >> xx >> yy >> zz >> fxx >> fyy >> fzz; if (tmp.fail()) { - // revert ifs.seekg(pos); break; } diff --git a/include/tadah/mlip/structure_neighbor_view.h b/include/tadah/mlip/structure_neighbor_view.h index 78dc5c72e56efc88a6a2e9be34ac1657961a21a6..277f317871d7dc9441bfd07a3b0303b9159dc216 100644 --- a/include/tadah/mlip/structure_neighbor_view.h +++ b/include/tadah/mlip/structure_neighbor_view.h @@ -4,119 +4,116 @@ #include <stdexcept> #include "neighbor_list.h" #include "structure_db.h" +#include "structure.h" +#include "neighbor_list_db.h" namespace tadah { namespace mlip { /** * @class StructureNeighborView - * @brief Creates a read-only slice of the global NeighborList for a single Structure. + * @brief Creates a read-only slice of a global NeighborList for a single Structure. * - * This design references a specific "Structure" (with known offset_ and natoms()) - * and a global "NeighborList" that covers all atoms in the HPC arrays. - * Methods compute each atom's global index on the fly (structure.offset_ + localIndex) - * and retrieve the neighbor data from the HPC neighbor list. + * This design references a specific "Structure" (which knows offset_ and natoms()) + * plus a global HPC neighbor list. Methods compute globalIdx = structure.offset() + localAtom + * and fetch neighbor data from the HPC arrays. + * Shifts (X,Y,Z) and mirror index are included for a complete local subset query. * - * No duplication of neighbor arrays occurs. - * This allows queries on "per-structure" neighbor data while still leveraging - * the single global HPC neighbor list in memory. + * A second constructor accepts a NeighborhoodListDB plus a structure index, + * eliminating the need to pass a Structure reference directly. */ class StructureNeighborView { public: /** - * @brief Constructs the view with references to a single Structure and the global HPC list. - * - * The code checks that the Structure's database pointer matches the DB - * that the "NeighborList" belongs to, if desired. That step is optional - * and can be enforced by additional runtime checks if multiple DBs exist. - * - * @param globalList Reference to the global HPC neighbor list. - * @param structure Reference to the specific Structure for local atom offsets. + * @brief Constructs from an existing global HPC neighbor list and a target Structure. */ StructureNeighborView(const NeighborList &globalList, const Structure &structure) : globalList_(globalList), str_(structure) { - // Optional: check that str_.db_ matches the DB used by the globalList if needed. + // Optionally verify that str_.db_ matches the DB that the HPC neighbor list uses. } /** - * @brief Returns how many atoms this structure possesses in its subrange. + * @brief Constructs by picking a structure from NeighborListDB.db()(structureIndex), + * then referencing the HPC neighbor list from nlDB.nlist(). + * + * This avoids manually retrieving the Structure from StructureDB first. + * + * @param nlDB The neighbor-list DB that references a single HPC neighbor list & DB. + * @param structureIndex The index of the desired structure in nlDB.db(). */ - inline std::size_t numAtoms() const + StructureNeighborView(const NeighborListDB &nlDB, std::size_t structureIndex) + : globalList_(nlDB.nlist()), str_(nlDB.db()(structureIndex)) { + // Minimal checks can be added if needed. + } + + /** + * @brief Returns how many atoms are in this structure’s subrange. + */ + inline std::size_t numAtoms() const { return str_.natoms(); } /** - * @brief Returns how many neighbors atom (localAtomIndex) has within this structure's sub-slice. - * - * Internally, the HPC neighbor list is indexed by a global atom index. - * The method computes: globalIdx = str_.offset_ + localAtomIndex. + * @brief Returns how many neighbors localAtomIndex has in the HPC arrays. */ - inline std::size_t numNeighbors(std::size_t localAtomIndex) const - { + inline std::size_t numNeighbors(std::size_t localAtomIndex) const { if (localAtomIndex >= str_.natoms()) { - throw std::out_of_range("StructureNeighborView::numNeighbors: local atom index out of range"); + throw std::out_of_range("StructureNeighborView::numNeighbors: local index out of range"); } - std::size_t gIdx = str_.offset_ + localAtomIndex; + std::size_t gIdx = str_.offset() + localAtomIndex; return globalList_.numNeighbors(gIdx); } /** - * @brief Returns a pointer to the neighbor indices for atom (localAtomIndex) in this structure. - * - * The caller typically pairs this with numNeighbors() to iterate over neighbor indices. + * @brief Returns a pointer to neighbors for localAtomIndex. */ - inline const std::size_t* getNeighborsPtr(std::size_t localAtomIndex) const - { + inline const std::size_t* getNeighborsPtr(std::size_t localAtomIndex) const { if (localAtomIndex >= str_.natoms()) { - throw std::out_of_range("StructureNeighborView::getNeighborsPtr: local atom index out of range"); + throw std::out_of_range("StructureNeighborView::getNeighborsPtr: local index out of range"); } - std::size_t gIdx = str_.offset_ + localAtomIndex; + std::size_t gIdx = str_.offset() + localAtomIndex; return globalList_.getNeighborsPtr(gIdx); } /** - * @brief Returns a pointer to the mirror index array for symmetrical pairs, if needed. + * @brief Returns the mirror index pointer for symmetrical pairs. */ - inline const std::size_t* getMirrorIndexPtr(std::size_t localAtomIndex) const - { + inline const std::size_t* getMirrorIndexPtr(std::size_t localAtomIndex) const { if (localAtomIndex >= str_.natoms()) { - throw std::out_of_range("StructureNeighborView::getMirrorIndexPtr: local atom index out of range"); + throw std::out_of_range("StructureNeighborView::getMirrorIndexPtr: local index out of range"); } - std::size_t gIdx = str_.offset_ + localAtomIndex; + std::size_t gIdx = str_.offset() + localAtomIndex; return globalList_.getMirrorIndexPtr(gIdx); } /** - * @brief Retrieves X shift array pointer for atom (localAtomIndex). - * Similar methods can be added for Y, Z, etc. + * @brief Returns the X-shift pointer, if HPC code uses shifts. */ - inline const int* getShiftXPtr(std::size_t localAtomIndex) const - { + inline const int* getShiftXPtr(std::size_t localAtomIndex) const { if (localAtomIndex >= str_.natoms()) { - throw std::out_of_range("StructureNeighborView::getShiftXPtr: local atom index out of range"); + throw std::out_of_range("StructureNeighborView::getShiftXPtr: local index out of range"); } - std::size_t gIdx = str_.offset_ + localAtomIndex; + std::size_t gIdx = str_.offset() + localAtomIndex; return globalList_.getShiftXPtr(gIdx); } - // Additional shiftYPtr, shiftZPtr, etc., can be provided if your code needs them. - -private: /** - * @brief Reference to the global HPC neighbor list that covers all atoms. + * @brief Returns the Y-shift pointer. */ - const NeighborList &globalList_; + inline const int* getShiftYPtr(std::size_t localAtomIndex) const { + if (localAtomIndex >= str_.natoms()) { + throw std::out_of_range("StructureNeighborView::getShiftYPtr: local index out of range"); + } + std::size_t gIdx = str_.offset() + localAtomIndex; + return globalList_.getShiftYPtr(gIdx); + } /** - * @brief Reference to the specific structure. - * offset_ + localIndex => global HPC neighbor index. + * @brief Returns the Z-shift pointer. */ - const Structure &str_; -}; - -} // namespace mlip -} // namespace tadah + inline const int* getShiftZPtr(std::size_t localAtomIndex) const { + if (localAtomIndex >= str_.nat