Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Molecules class #648

Merged
merged 7 commits into from
Jul 14, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions avogadro/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ set(HEADERS
matrix.h
mesh.h
molecule.h
moleculegraph.h
mutex.h
nameatomtyper.h
residue.h
Expand Down Expand Up @@ -69,7 +68,6 @@ set(SOURCES
mesh.cpp
mdlvalence_p.h
molecule.cpp
moleculegraph.cpp
mutex.cpp
nameatomtyper.cpp
residue.cpp
Expand Down
5 changes: 5 additions & 0 deletions avogadro/core/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,11 @@ class Array
swap(d, other.d);
}

/**
* @param index array position to delete
* if the index is valid swap it with the last position and pop back.
* This function does not preserve the elements order.
*/
void swapAndPop(Index index)
ghutchis marked this conversation as resolved.
Show resolved Hide resolved
{
if (index >= d->data.size()) {
Expand Down
102 changes: 51 additions & 51 deletions avogadro/core/connectedgroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,131 +20,131 @@ namespace Core {

ConnectedGroup::ConnectedGroup() {}

ConnectedGroup::ConnectedGroup(size_t n) : m_groupToElement(n)
ConnectedGroup::ConnectedGroup(size_t n) : m_groupToNode(n)
{
resetToSize(n);
}

ConnectedGroup::~ConnectedGroup() {}

void ConnectedGroup::addElement(size_t index)
void ConnectedGroup::addNode(size_t index)
{
if (m_elementToGroup.find(index) == m_elementToGroup.end()) {
m_elementToGroup[index] = m_groupToElement.size();
if (m_nodeToGroup.find(index) == m_nodeToGroup.end()) {
m_nodeToGroup[index] = m_groupToNode.size();
std::set<size_t> group;
group.insert(index);
m_groupToElement.push_back(group);
m_groupToNode.push_back(group);
}
}

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

void ConnectedGroup::addConnection(size_t a, size_t b)
{
assert(m_elementToGroup.find(a) != m_elementToGroup.end());
assert(m_elementToGroup.find(b) != m_elementToGroup.end());
assert(m_nodeToGroup.find(a) != m_nodeToGroup.end());
assert(m_nodeToGroup.find(b) != m_nodeToGroup.end());

size_t group_a = m_elementToGroup[a];
size_t group_b = m_elementToGroup[b];
size_t group_a = m_nodeToGroup[a];
size_t group_b = m_nodeToGroup[b];
if (group_a != group_b) {
for (size_t element : m_groupToElement[group_b]) {
m_elementToGroup[element] = group_a;
m_groupToElement[group_a].insert(element);
for (size_t node : m_groupToNode[group_b]) {
m_nodeToGroup[node] = group_a;
m_groupToNode[group_a].insert(node);
}
m_groupToElement[group_b].clear();
checkRemove(m_groupToElement);
m_groupToNode[group_b].clear();
checkRemove(m_groupToNode);
}
}

void ConnectedGroup::removeElement(size_t index)
void ConnectedGroup::removeNode(size_t index)
{
assert(m_elementToGroup.find(index) != m_elementToGroup.end());
assert(m_nodeToGroup.find(index) != m_nodeToGroup.end());
removeConnection(index);
size_t group = m_elementToGroup[index];
m_elementToGroup.erase(group);
size_t group = m_nodeToGroup[index];
m_nodeToGroup.erase(group);
}

void ConnectedGroup::removeConnections()
{
size_t n = m_elementToGroup.size();
size_t n = m_nodeToGroup.size();
clear();
resetToSize(n);
}

void ConnectedGroup::removeConnection(size_t index)
{
assert(m_elementToGroup.find(index) != m_elementToGroup.end());
size_t group = m_elementToGroup[index];
m_elementToGroup.erase(index);
m_groupToElement[group].erase(index);
addElement(index);
checkRemove(m_groupToElement);
assert(m_nodeToGroup.find(index) != m_nodeToGroup.end());
size_t group = m_nodeToGroup[index];
m_nodeToGroup.erase(index);
m_groupToNode[group].erase(index);
addNode(index);
checkRemove(m_groupToNode);
}

void ConnectedGroup::removeConnection(size_t a, size_t b,
const std::set<size_t>& neighbors)
{
assert(m_elementToGroup.find(a) != m_elementToGroup.end());
assert(m_elementToGroup.find(b) != m_elementToGroup.end());
if (m_elementToGroup[a] != m_elementToGroup[b]) {
assert(m_nodeToGroup.find(a) != m_nodeToGroup.end());
assert(m_nodeToGroup.find(b) != m_nodeToGroup.end());
if (m_nodeToGroup[a] != m_nodeToGroup[b]) {
return;
}
removeConnection(a);
size_t aGroup = m_elementToGroup[a];
size_t bGroup = m_elementToGroup[b];
size_t aGroup = m_nodeToGroup[a];
size_t bGroup = m_nodeToGroup[b];
for (const auto& n : neighbors) {
m_groupToElement[bGroup].erase(n);
m_groupToElement[aGroup].insert(n);
m_elementToGroup[n] = aGroup;
m_groupToNode[bGroup].erase(n);
m_groupToNode[aGroup].insert(n);
m_nodeToGroup[n] = aGroup;
}
checkRemove(m_groupToElement);
checkRemove(m_groupToNode);
}

void ConnectedGroup::clear()
{
m_elementToGroup.clear();
m_groupToElement.clear();
m_nodeToGroup.clear();
m_groupToNode.clear();
}

size_t ConnectedGroup::getGroup(size_t element) const
size_t ConnectedGroup::getGroup(size_t node) const
{
assert(m_elementToGroup.find(element) != m_elementToGroup.end());
return m_elementToGroup.at(element);
assert(m_nodeToGroup.find(node) != m_nodeToGroup.end());
return m_nodeToGroup.at(node);
}

std::set<size_t> ConnectedGroup::getElements(size_t group) const
std::set<size_t> ConnectedGroup::getNodes(size_t group) const
{
assert(group < m_groupToElement.size());
return m_groupToElement[group];
assert(group < m_groupToNode.size());
return m_groupToNode[group];
}

std::vector<std::set<size_t>> ConnectedGroup::getAllGroups() const
{
return m_groupToElement;
return m_groupToNode;
}

void ConnectedGroup::resetToSize(size_t n)
{
for (size_t i = 0; i < n; ++i) {
m_elementToGroup[i] = i;
m_groupToElement[i].insert(i);
m_nodeToGroup[i] = i;
m_groupToNode[i].insert(i);
}
}

size_t ConnectedGroup::groupCount() const
{
return m_groupToElement.size();
return m_groupToNode.size();
}

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

} // namespace Core
Expand Down
42 changes: 23 additions & 19 deletions avogadro/core/connectedgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ namespace Core {
/**
* @class ConnectedGroup bimap.h <avogadro/core/graph.h>
* @brief The ConnectedGroup class represents a bidirectional Map data structure
* between size_t and a size_t set.
* between size_t (group) and a size_t set (nodes).
* @example graph.h where it computes the bonded atom sets
*/
class AVOGADROCORE_EXPORT ConnectedGroup
{
Expand All @@ -32,19 +33,19 @@ class AVOGADROCORE_EXPORT ConnectedGroup
/** Destroys the ConnectedGroup. */
~ConnectedGroup();

/** Adds a element to the graph and returns its index. */
void addElement(size_t index);
/** check if @p index is already in a group otherwise create one for it */
void addNode(size_t index);

/** Adds N element to the graph and returns its index. */
void addElements(size_t n);
/** create @p n groups with 1 node each */
void addNodes(size_t n);

/** Merge the two groups between two IDs @p a and @p b. */
/** node @p a and @p b will be in the same group */
void addConnection(size_t a, size_t b);

/** Removes the element at @p index. */
void removeElement(size_t index);
/** Removes the node at @p index. */
void removeNode(size_t index);

/** Makes all the element individual groups. */
/** Makes all the nodes individual groups. */
void removeConnections();

/** Makes @p index an individual group. */
Expand All @@ -54,27 +55,30 @@ class AVOGADROCORE_EXPORT ConnectedGroup
* they don't */
void removeConnection(size_t a, size_t b, const std::set<size_t>& neighbors);

/** Removes all elements and groups. */
/** Removes everything. */
void clear();

/** Get the group ID from the element. */
size_t getGroup(size_t element) const;
/** @return the group ID from the node . */
size_t getGroup(size_t node) const;

/** Get the group size from the element. */
size_t getGroupSize(size_t element) const;
/** @return the group size from the node. */
size_t getGroupSize(size_t node) const;

/** Get all the groups and their elemenets. */
/** @return all groups and their nodes */
std::vector<std::set<size_t>> getAllGroups() const;

/** Get all the elements in the @p group. */
std::set<size_t> getElements(size_t group) const;
/** @return all the nodes in the @p group. */
std::set<size_t> getNodes(size_t group) const;

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

/** */
size_t groupCount() const;

private:
std::map<size_t, size_t> m_elementToGroup;
std::vector<std::set<size_t>> m_groupToElement;
std::map<size_t, size_t> m_nodeToGroup;
std::vector<std::set<size_t>> m_groupToNode;

void resetToSize(size_t n);
void mergeGroups(size_t a, size_t b);
Expand Down
Loading