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

Feature/cull pairs #333

Draft
wants to merge 7 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
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
8 changes: 6 additions & 2 deletions src/FSISPH/SolidFSISPHEvaluateDerivatives.cc
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ secondDerivativesLoop(const typename Dimension::Scalar time,
j = pairs[kk].j_node;
nodeListi = pairs[kk].i_list;
nodeListj = pairs[kk].j_list;
if (pairs[kk].f_couple < 1.0e-16)
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this will break fsi. Depending upon the node coupling algorithm, f_couple can be zero at damage interfaces and this will give non-physical behavior when compression happens along a damage interface. FSI has it's own decoupling logic to handle damage fronts.

What was the need for the additional decoupling?

continue;
}

// Get the state for node i.
const auto& interfaceFlagsi = interfaceFlags(nodeListi,i);
Expand Down Expand Up @@ -556,8 +560,8 @@ secondDerivativesLoop(const typename Dimension::Scalar time,
if (freeParticle) {
DvDti += mj*deltaDvDt;
DvDtj -= mi*deltaDvDt;
}
}

// Velocity Gradient
//-----------------------------------------------------------
// construct our interface velocity
Expand Down
5 changes: 4 additions & 1 deletion src/FSISPH/SolidFSISPHHydroBase.cc
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,8 @@ preStepInitialize(const DataBase<Dimension>& dataBase,
TIME_BEGIN("SolidFSISPHpreStepInitialize");
if (mApplySelectDensitySum){
switch(this->densityUpdate()){
case FSIMassDensityMethod::FSIConsistentSumMassDensity:
// fallthrough intended
case FSIMassDensityMethod::FSISumMassDensity:
{
const auto& W = this->kernel();
Expand All @@ -528,7 +530,8 @@ preStepInitialize(const DataBase<Dimension>& dataBase,
const auto mass = state.fields(HydroFieldNames::mass, 0.0);
const auto H = state.fields(HydroFieldNames::H, SymTensor::zero);
auto massDensity = state.fields(HydroFieldNames::massDensity, 0.0);
computeFSISPHSumMassDensity(connectivityMap, W, mSumDensityNodeLists, position, mass, H, massDensity);
const auto consistentSum = (this->densityUpdate() == FSIMassDensityMethod::FSIConsistentSumMassDensity);
computeFSISPHSumMassDensity(connectivityMap, W, mSumDensityNodeLists, position, mass, H, consistentSum, massDensity);
for (auto boundaryItr = this->boundaryBegin(); boundaryItr < this->boundaryEnd(); ++boundaryItr) (*boundaryItr)->applyFieldListGhostBoundary(massDensity);
for (auto boundaryItr = this->boundaryBegin(); boundaryItr < this->boundaryEnd(); ++boundaryItr) (*boundaryItr)->finalizeGhostBoundary();
break;
Expand Down
1 change: 1 addition & 0 deletions src/FSISPH/SolidFSISPHHydroBase.hh
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ enum class FSIMassDensityMethod {
FSISumMassDensity = 0,
PressureCorrectSumMassDensity = 1,
HWeightedSumMassDensity = 2,
FSIConsistentSumMassDensity = 3,
};

template<typename Dimension> class State;
Expand Down
6 changes: 4 additions & 2 deletions src/FSISPH/computeFSISPHSumMassDensity.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ computeFSISPHSumMassDensity(const ConnectivityMap<Dimension>& connectivityMap,
const FieldList<Dimension, typename Dimension::Vector>& position,
const FieldList<Dimension, typename Dimension::Scalar>& mass,
const FieldList<Dimension, typename Dimension::SymTensor>& H,
const bool consistentSum,
FieldList<Dimension, typename Dimension::Scalar>& massDensity) {

// Pre-conditions.
Expand Down Expand Up @@ -61,14 +62,15 @@ computeFSISPHSumMassDensity(const ConnectivityMap<Dimension>& connectivityMap,
const auto& ri = position(nodeListi, i);
const auto& rj = position(nodeListj, j);
const auto rij = ri - rj;
const auto normalSum = (nodeListi == nodeListj) || consistentSum;

if(sumDensityNodeLists[nodeListi]==1){
const auto& Hi = H(nodeListi, i);
const auto Hdeti = Hi.Determinant();
const auto etai = (Hi*rij).magnitude();
const auto Wi = W.kernelValue(etai, Hdeti);

massDensity_thread(nodeListi, i) += (nodeListi == nodeListj ? mj : mi)*Wi;
massDensity_thread(nodeListi, i) += (normalSum ? mj : mi)*Wi;
}

if(sumDensityNodeLists[nodeListj]==1){
Expand All @@ -77,7 +79,7 @@ computeFSISPHSumMassDensity(const ConnectivityMap<Dimension>& connectivityMap,
const auto etaj = (Hj*rij).magnitude();
const auto Wj = W.kernelValue(etaj, Hdetj);

massDensity_thread(nodeListj, j) += (nodeListi == nodeListj ? mi : mj)*Wj;
massDensity_thread(nodeListj, j) += (normalSum ? mi : mj)*Wj;
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/FSISPH/computeFSISPHSumMassDensity.hh
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ computeFSISPHSumMassDensity(const ConnectivityMap<Dimension>& connectivityMap,
const FieldList<Dimension, typename Dimension::Vector>& position,
const FieldList<Dimension, typename Dimension::Scalar>& mass,
const FieldList<Dimension, typename Dimension::SymTensor>& H,
const bool consistentSum,
FieldList<Dimension, typename Dimension::Scalar>& massDensity);

}


#endif
#endif
1 change: 1 addition & 0 deletions src/FSISPH/computeFSISPHSumMassDensityInst.cc.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
const FieldList<Dim< %(ndim)s >, Dim< %(ndim)s >::Vector>&,
const FieldList<Dim< %(ndim)s >, Dim< %(ndim)s >::Scalar>&,
const FieldList<Dim< %(ndim)s >, Dim< %(ndim)s >::SymTensor>&,
const bool consistentSum,
FieldList<Dim< %(ndim)s >, Dim< %(ndim)s >::Scalar>&);
}
"""
67 changes: 61 additions & 6 deletions src/Neighbor/ConnectivityMap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ ConnectivityMap():
mNodeTraversalIndices(),
mKeys(FieldStorageType::CopyFields),
mCouplingPtr(std::make_shared<NodeCoupling>()),
mIntersectionConnectivity() {
mIntersectionConnectivity(),
mExcludePairs([](int, int, int, int) { return false; }){
}

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -269,10 +270,9 @@ patchConnectivity(const FieldList<Dimension, int>& flags,
const auto jNodeList = mNodePairList[k].j_list;
const auto i = mNodePairList[k].i_node;
const auto j = mNodePairList[k].j_node;
if (flags(iNodeList, i) != 0 and flags(jNodeList, j) != 0) {
if (flags(iNodeList, i) != 0 and flags(jNodeList, j) != 0)
culledPairs_thread.push_back(NodePairIdxType(old2new(iNodeList, i), iNodeList,
old2new(jNodeList, j), jNodeList));
}
}
#pragma omp critical
{
Expand Down Expand Up @@ -919,9 +919,14 @@ computeConnectivity() {

// We don't include self-interactions.
if ((iNodeList != jNodeList) or (i != j)) {
neighbors[jNodeList].push_back(j);
if (calculatePairInteraction(iNodeList, i, jNodeList, j, firstGhostNodej)) nodePairs_private.push_back(NodePairIdxType(i, iNodeList, j, jNodeList));
if (domainDecompIndependent) keys[jNodeList].push_back(pair<int, Key>(j, mKeys(jNodeList, j)));

// Exclude specified pairs.
if (!mExcludePairs(iNodeList, i, jNodeList, j))
{
neighbors[jNodeList].push_back(j);
if (calculatePairInteraction(iNodeList, i, jNodeList, j, firstGhostNodej)) nodePairs_private.push_back(NodePairIdxType(i, iNodeList, j, jNodeList));
if (domainDecompIndependent) keys[jNodeList].push_back(pair<int, Key>(j, mKeys(jNodeList, j)));
}
}
}
}
Expand Down Expand Up @@ -1126,6 +1131,8 @@ computeConnectivity() {
// }
// }

mNodePairList.makeUnique();

// Post conditions.
BEGIN_CONTRACT_SCOPE
// Make sure that the correct number of nodes have been completed.
Expand All @@ -1145,4 +1152,52 @@ computeConnectivity() {
TIME_END("ConnectivityMap_computeConnectivity");
}

//------------------------------------------------------------------------------
// Remove given pairs from the connectivity in place
//------------------------------------------------------------------------------
template<typename Dimension>
void
ConnectivityMap<Dimension>::
removeConnectivity(std::function<bool(int, int, int, int)> excludePairs)
{
const auto domainDecompIndependent = NodeListRegistrar<Dimension>::instance().domainDecompositionIndependent();
const auto numNodeLists = mNodeLists.size();
for (auto iNodeList = 0u; iNodeList != numNodeLists; ++iNodeList) {
const auto numNodes = ((domainDecompIndependent or mBuildGhostConnectivity or mBuildOverlapConnectivity) ?
mNodeLists[iNodeList]->numNodes() :
mNodeLists[iNodeList]->numInternalNodes());
for (auto i = 0u; i < numNodes; ++i) {
auto& neighbors = mConnectivity[i];
CHECK(neighbors.size() == numNodeLists);
for (auto jNodeList = 0u; jNodeList < numNodeLists; ++jNodeList) {
auto& neighborsj = neighbors[jNodeList];
auto l = 0u;
for (auto k = 0u; k < neighborsj.size(); ++k)
{
const auto j = neighborsj[k];
if (!excludePairs(iNodeList, i, jNodeList, j))
{
neighborsj[l++] = neighborsj[k];
}
}
neighborsj.resize(l);
}
}
}

const auto npairs = mNodePairList.size();
auto l = 0u;
for (auto k = 0u; k < npairs; ++k) {
const auto iNodeList = mNodePairList[k].i_list;
const auto jNodeList = mNodePairList[k].j_list;
const auto i = mNodePairList[k].i_node;
const auto j = mNodePairList[k].j_node;
if (!excludePairs(iNodeList, i, jNodeList, j))
{
mNodePairList[l++] = mNodePairList[k];
}
}
mNodePairList.resize(l);
}

}
10 changes: 9 additions & 1 deletion src/Neighbor/ConnectivityMap.hh
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ public:
// member of a pair (maintaining symmetry).
void removeConnectivity(const FieldList<Dimension, std::vector<std::vector<int>>>& neighborsToCut);

// Remove pairs based on a function
void removeConnectivity(std::function<bool(int, int, int, int)> excludePairs);

// Are we computing neighbors for ghosts?
bool buildGhostConnectivity() const;

Expand Down Expand Up @@ -171,9 +174,11 @@ public:
// Return which NodeList index in order the given one would be in our connectivity.
unsigned nodeListIndex(const NodeList<Dimension>* nodeListPtr) const;

// Exclude (nodeListi, nodei, nodeListj, nodej) pairs if this returns false
void setNodePairExclusion(std::function<bool(int, int, int, int)> excludePairs);

// Check that the internal data structure is valid.
bool valid() const;

private:
//--------------------------- Private Interface ---------------------------//
// The set of NodeLists.
Expand Down Expand Up @@ -208,6 +213,9 @@ private:
using IntersectionConnectivityContainer = std::unordered_map<NodePairIdxType, std::vector<std::vector<int>>>;
IntersectionConnectivityContainer mIntersectionConnectivity;

// Exclude pairs matching this function
std::function<bool(int, int, int, int)> mExcludePairs;

// Internal method to fill in the connectivity, once the set of NodeLists
// is determined.
void computeConnectivity();
Expand Down
11 changes: 11 additions & 0 deletions src/Neighbor/ConnectivityMapInline.hh
Original file line number Diff line number Diff line change
Expand Up @@ -390,4 +390,15 @@ intersectionConnectivity(const NodePairIdxType& pair) const {
return itr->second;
}

//------------------------------------------------------------------------------
// Set the function for excluding node pairs
//------------------------------------------------------------------------------
template<typename Dimension>
void
ConnectivityMap<Dimension>::
setNodePairExclusion(std::function<bool(int, int, int, int)> excludePairs)
{
mExcludePairs = excludePairs;
}

}
29 changes: 29 additions & 0 deletions src/Neighbor/NodePairList.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "NodePairList.hh"

#include <algorithm>

namespace Spheral {

NodePairIdxType::NodePairIdxType(int i_n, int i_l, int j_n, int j_l, double f) :
Expand All @@ -15,4 +17,31 @@ namespace Spheral {
mNodePairList.clear();
}

void NodePairList::makeUnique() {
// Make sure the node pairs are ordered correctly
for (auto kk = 0u; kk < mNodePairList.size(); ++kk)
{
auto& pair = mNodePairList[kk];
if (pair.i_list > pair.j_list)
{
const auto temp_list = pair.j_list;
const auto temp_node = pair.j_node;
pair.j_list = pair.i_list;
pair.j_node = pair.i_node;
pair.i_list = temp_list;
pair.i_node = temp_node;
}
if (pair.i_list == pair.j_list && pair.i_node > pair.j_node)
{
const auto temp = pair.j_node;
pair.j_node = pair.i_node;
pair.i_node = temp;
}
}

// Remove duplicates
std::sort(mNodePairList.begin(), mNodePairList.end());
mNodePairList.erase(std::unique(mNodePairList.begin(), mNodePairList.end()), mNodePairList.end());
}

}
4 changes: 3 additions & 1 deletion src/Neighbor/NodePairList.hh
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ public:

NodePairList();
void push_back(NodePairIdxType nodePair);
void clear();
void clear();
void resize(const size_t n) { mNodePairList.resize(n, NodePairIdxType(-1,-1,-1,-1)); }
size_t size() const { return mNodePairList.size(); }
void makeUnique();

// Iterators
iterator begin() { return mNodePairList.begin(); }
Expand Down