Skip to content

Commit

Permalink
Layer system (#709)
Browse files Browse the repository at this point in the history
* layer system, including save and load layer info from CJSON

Signed-off-by: Marc Prat Masó <marc.prat.maso@estudiantat.upc.edu>
  • Loading branch information
serk12 authored Aug 10, 2021
1 parent 0a3e642 commit b30e202
Show file tree
Hide file tree
Showing 63 changed files with 2,135 additions and 555 deletions.
4 changes: 4 additions & 0 deletions avogadro/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ set(HEADERS
gaussianset.h
gaussiansettools.h
graph.h
layer.h
layermanager.h
matrix.h
mesh.h
molecule.h
Expand Down Expand Up @@ -66,6 +68,8 @@ set(SOURCES
gaussianset.cpp
gaussiansettools.cpp
graph.cpp
layer.cpp
layermanager.cpp
mesh.cpp
mdlvalence_p.h
molecule.cpp
Expand Down
74 changes: 70 additions & 4 deletions avogadro/core/connectedgroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ ConnectedGroup::ConnectedGroup(size_t n) : m_groupToNode(n)
resetToSize(n);
}

void ConnectedGroup::addGroup(size_t group)
{
for (auto& nodeGroup : m_nodeToGroup) {
if (nodeGroup.second >= group) {
++nodeGroup.second;
}
}
m_groupToNode.insert(m_groupToNode.begin() + group, std::set<size_t>());
}

ConnectedGroup::~ConnectedGroup() {}

void ConnectedGroup::addNode(size_t index)
Expand All @@ -37,6 +47,23 @@ void ConnectedGroup::addNode(size_t index)
}
}

void ConnectedGroup::addNode(size_t node, size_t group)
{
assert(group < m_groupToNode.size());
auto it = m_nodeToGroup.find(node);
// if node already exists, remove it
if (it == m_nodeToGroup.end()) {
m_nodeToGroup[node] = group;
m_groupToNode[group].insert(node);
} else {
auto old_group = m_nodeToGroup[node];
m_nodeToGroup[node] = group;

m_groupToNode[old_group].erase(node);
m_groupToNode[group].insert(node);
}
}

void ConnectedGroup::addNodes(size_t n)
{
size_t offset = m_nodeToGroup.size();
Expand All @@ -45,6 +72,14 @@ void ConnectedGroup::addNodes(size_t n)
}
}

void ConnectedGroup::addNodes(size_t n, size_t group)
{
size_t offset = m_nodeToGroup.size();
for (size_t i = 0; i < n; ++i) {
addNode(i + offset, group);
}
}

void ConnectedGroup::addConnection(size_t a, size_t b)
{
assert(m_nodeToGroup.find(a) != m_nodeToGroup.end());
Expand All @@ -64,10 +99,13 @@ void ConnectedGroup::addConnection(size_t a, size_t b)

void ConnectedGroup::removeNode(size_t index)
{
assert(m_nodeToGroup.find(index) != m_nodeToGroup.end());
removeConnection(index);
size_t group = m_nodeToGroup[index];
m_nodeToGroup.erase(group);
auto it = m_nodeToGroup.find(index);
if (it != m_nodeToGroup.end()) {
size_t group = it->second;
m_nodeToGroup.erase(it);
m_groupToNode[group].erase(index);
checkRemove(m_groupToNode);
}
}

void ConnectedGroup::removeConnections()
Expand Down Expand Up @@ -106,6 +144,24 @@ void ConnectedGroup::removeConnection(size_t a, size_t b,
checkRemove(m_groupToNode);
}

void ConnectedGroup::removeGroup(size_t group)
{
assert(group < m_nodeToGroup.size());
auto it = m_nodeToGroup.begin();
while (it != m_nodeToGroup.end()) {
if (it->second > group) {
--it->second;
++it;
} else if (it->second == group) {
it = m_nodeToGroup.erase(it);
} else {
++it;
}
}

m_groupToNode.erase(m_groupToNode.begin() + group);
}

void ConnectedGroup::clear()
{
m_nodeToGroup.clear();
Expand Down Expand Up @@ -142,10 +198,20 @@ size_t ConnectedGroup::groupCount() const
return m_groupToNode.size();
}

size_t ConnectedGroup::atomCount() const
{
return m_nodeToGroup.size();
}

size_t ConnectedGroup::getGroupSize(size_t node) const
{
return m_groupToNode.at(m_nodeToGroup.at(node)).size();
}

bool ConnectedGroup::hasAtom(size_t atom) const
{
return m_nodeToGroup.find(atom) != m_nodeToGroup.end();
}

} // namespace Core
} // namespace Avogadro
11 changes: 10 additions & 1 deletion avogadro/core/connectedgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Avogadro {
namespace Core {

/**
* @class ConnectedGroup bimap.h <avogadro/core/graph.h>
* @class ConnectedGroup ConnectedGroup.h <avogadro/core/ConnectedGroup.h>
* @brief The ConnectedGroup class represents a bidirectional Map data structure
* between size_t (group) and a size_t set (nodes).
* @example graph.h where it computes the bonded atom sets
Expand All @@ -35,9 +35,11 @@ class AVOGADROCORE_EXPORT ConnectedGroup

/** check if @p index is already in a group otherwise create one for it */
void addNode(size_t index);
void addNode(size_t node, size_t group);

/** create @p n groups with 1 node each */
void addNodes(size_t n);
void addNodes(size_t n, size_t group);

/** node @p a and @p b will be in the same group */
void addConnection(size_t a, size_t b);
Expand All @@ -55,6 +57,10 @@ class AVOGADROCORE_EXPORT ConnectedGroup
* they don't */
void removeConnection(size_t a, size_t b, const std::set<size_t>& neighbors);

void removeGroup(size_t group);

void addGroup(size_t group);

/** Removes everything. */
void clear();

Expand All @@ -72,6 +78,9 @@ class AVOGADROCORE_EXPORT ConnectedGroup

/** @return the total groups existing */
size_t groupCount() const;
size_t atomCount() const;

bool hasAtom(size_t atom) const;

private:
std::map<size_t, size_t> m_nodeToGroup;
Expand Down
125 changes: 125 additions & 0 deletions avogadro/core/layer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/******************************************************************************
This source file is part of the Avogadro project.
This source code is released under the 3-Clause BSD License, (see "LICENSE").
******************************************************************************/

#include "layer.h"
#include <cassert>

namespace Avogadro {
namespace Core {

using std::swap;

Layer::Layer() : m_activeLayer(0), m_maxLayer(0) {}

void Layer::addAtom(size_t layer)
{
addAtom(layer, m_atomAndLayers.size());
}

void Layer::addAtom(size_t layer, Index atom)
{
assert(layer <= m_maxLayer);
if (atom == m_atomAndLayers.size()) {
m_atomAndLayers.push_back(layer);
} else if (atom > m_atomAndLayers.size()) {
m_atomAndLayers.resize(layer + 1, MaxIndex);
m_atomAndLayers[atom] = layer;
} else {
m_atomAndLayers[atom] = layer;
}
}

void Layer::addAtomToActiveLayer(Index atom)
{
addAtom(m_activeLayer, atom);
}

void Layer::setActiveLayer(size_t layer)
{
assert(layer <= m_maxLayer + 1);
m_activeLayer = layer;
}

void Layer::removeAtom(Index atom)
{
m_atomAndLayers.swapAndPop(atom);
}

void Layer::addLayer()
{
++m_maxLayer;
}

void Layer::addLayer(size_t layer)
{
assert(layer <= m_maxLayer + 1);
for (auto& atomLayer : m_atomAndLayers) {
if (atomLayer >= layer) {
++atomLayer;
}
}
++m_maxLayer;
}

size_t Layer::getLayerID(Index atom) const
{
if (atom >= m_atomAndLayers.size()) {
return MaxIndex;
} else {
return m_atomAndLayers[atom];
}
}

void Layer::clear()
{
m_atomAndLayers.clear();
m_activeLayer = m_maxLayer = 0;
}

size_t Layer::activeLayer() const
{
return m_activeLayer;
}

size_t Layer::maxLayer() const
{
return m_maxLayer;
}

size_t Layer::atomCount() const
{
return m_atomAndLayers.size();
}

void Layer::removeLayer(size_t layer)
{
assert(layer <= m_maxLayer);
if (m_maxLayer >= 1) {
for (auto it = m_atomAndLayers.begin(); it != m_atomAndLayers.end();) {
if (*it == layer) {
it = m_atomAndLayers.erase(it);
} else {
if (*it > layer) {
--(*it);
}
++it;
}
}
--m_maxLayer;
}
}

void Layer::swapLayer(Index a, Index b)
{
swap(m_atomAndLayers[a], m_atomAndLayers[b]);
}

size_t Layer::layerCount() const
{
return m_maxLayer + 1;
}

} // namespace Core
} // namespace Avogadro
75 changes: 75 additions & 0 deletions avogadro/core/layer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/******************************************************************************
This source file is part of the Avogadro project.
This source code is released under the 3-Clause BSD License, (see "LICENSE").
******************************************************************************/

#ifndef AVOGADRO_CORE_LAYER_H
#define AVOGADRO_CORE_LAYER_H

#include "avogadrocore.h"

#include <avogadro/core/array.h>
#include <avogadro/core/connectedgroup.h>

namespace Avogadro {
namespace Core {

/**
* @class Layer layer.h <avogadro/core/layer.h>
* @brief The Layer class represents a relation one to one between atoms ID
* and layer ID, and stores the unique active layer.
* Layer's ID are consecutively and there can't be a ID bigger than @p
* m_maxLayer.
*/
class AVOGADROCORE_EXPORT Layer
{
public:
Layer();

// att atom to param layer
void addAtom(size_t layer);
void addAtom(size_t layer, Index atom);
void addAtomToActiveLayer(Index atom);
void removeAtom(Index atom);
void removeLayer(size_t layer);

/** @return the layer ID from the @p atom. */
size_t getLayerID(Index atom) const;
/** @return the active Layer. */
size_t activeLayer() const;

/** @return the maximum layer allowed. */
size_t maxLayer() const;

/** @return the number of layers. */
size_t layerCount() const;

/** @return The number of atoms. */
size_t atomCount() const;

/** remove all IDs. */
void clear();

/** increase the maximum layer allowed .*/
void addLayer();

/** insert a layer at @p layer, equal or bigger previous layers will be
* shifted. */
void addLayer(size_t layer);

/** change @p m_activeLayer. */
void setActiveLayer(size_t layer);

/** swap the layer ID from @p a and @p b. */
void swapLayer(Index a, Index b);

private:
Core::Array<size_t> m_atomAndLayers;
size_t m_activeLayer;
size_t m_maxLayer;
};

} // namespace Core
} // namespace Avogadro

#endif
Loading

0 comments on commit b30e202

Please sign in to comment.