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

Fixes for parallel collision detection #2195

Merged
merged 22 commits into from
Aug 30, 2018

Conversation

RudolfWeeber
Copy link
Contributor

  • three particle binding:
    Only work on cells available on the local node, but use p.l.p_old as a fallback (from @hirschsn)
  • virtual sites based methods:
    • Skip collision on a node which does not see both particles
      and at least one is non-ghost.
    • Add bonds only on the node where the particle is present
    • For glue to surface: A particle can only be glued once. To ensure this,
      delay the creationof the bond between the centers to occur at the smae
      time the glued particle is made iner by changing its type.
      Also execute the type change, on non-ghost particles, if only
      one of the particles is available on the node. The actual collision
      will be handled on the left neighbor which sees both particles.
  • Testcase: set box_l to (1,1,1) so that the clusters in the test actually
    span several nodes.
    Add Lennard-Jones-liquid based tests for virtual-sites based schemes to catch
    corner cases

RudolfWeeber and others added 7 commits August 20, 2018 11:32
* three particle binding:
  Only work on cells available on the local node
* virtual sites based methods:
  * Skip collision on a node which does not see both particles
    and at least one is non-ghost.
  * Add bonds only on the node where the particle is present
  * For glue to surface: A particle can only be glued once. To ensure this,
    delay the creationof the bond between the centers to occur at the smae
    time the glued particle is made iner by changing its type.
    Also execute the type change, on non-ghost particles, if only
    one of the particles is available on the node. The actual collision
    will be handled on the left neighbor which sees both particles.
* Testcase: set box_l to (1,1,1) so that the clusters in the test actually
  span several nodes.
  Add Lennard-Jones-liquid based tests for virtual-sites based schemes to  catch
  corner cases

This needs to be integrated with espressomd#2156

Fixes espressomd#2102
* three particle binding:
  Only work on cells available on the local node
* virtual sites based methods:
  * Skip collision on a node which does not see both particles
    and at least one is non-ghost.
  * Add bonds only on the node where the particle is present
  * For glue to surface: A particle can only be glued once. To ensure this,
    delay the creationof the bond between the centers to occur at the smae
    time the glued particle is made iner by changing its type.
    Also execute the type change, on non-ghost particles, if only
    one of the particles is available on the node. The actual collision
    will be handled on the left neighbor which sees both particles.
* Testcase: set box_l to (1,1,1) so that the clusters in the test actually
  span several nodes.
  Add Lennard-Jones-liquid based tests for virtual-sites based schemes to  catch
  corner cases

This needs to be integrated with espressomd#2156

Fixes espressomd#2102
@RudolfWeeber
Copy link
Contributor Author

@fweik, @hirschsn

@codecov
Copy link

codecov bot commented Aug 23, 2018

Codecov Report

❗ No coverage uploaded for pull request base (python@210fba0). Click here to learn what that means.
The diff coverage is 90%.

Impacted file tree graph

@@           Coverage Diff            @@
##             python   #2195   +/-   ##
========================================
  Coverage          ?     69%           
========================================
  Files             ?     474           
  Lines             ?   31972           
  Branches          ?       0           
========================================
  Hits              ?   22071           
  Misses            ?    9901           
  Partials          ?       0
Impacted Files Coverage Δ
src/core/cells.hpp 100% <ø> (ø)
src/core/nsquare.cpp 99% <100%> (ø)
src/core/layered.cpp 79% <100%> (ø)
src/core/domain_decomposition.cpp 92% <100%> (ø)
src/core/cells.cpp 92% <80%> (ø)
src/core/collision.cpp 81% <91%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 210fba0...00cff13. Read the comment docs.

Copy link
Contributor

@fweik fweik left a comment

Choose a reason for hiding this comment

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

Overall I think this is correct now. The current_vs_pid construction seems somewhat brittle to me, but changing this requires some refactoring, I think we can keep it for now.

// * or we have only one and it is a ghost
// we only increase the counter for the ext id to use based on the
// number of particles created by other nodes
if ((!p1 and !p2) ||
Copy link
Contributor

Choose a reason for hiding this comment

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

This condition is to complex. Please split it up.

@@ -507,6 +513,19 @@ static void three_particle_binding_do_search(Cell *basecell, Particle &p1,
}
}

Cell *responsible_collision_cell(Particle& p)
Copy link
Contributor

Choose a reason for hiding this comment

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

This should go into cells.cpp, and can be reused there e.g. to make removing a particle O(1). It should also be renamed to something like find_current_cell. This finds the actual cell a particles is in, as opposed to the cell a particle should be in (which is what position_to_cell returns).

// number of particles created by other nodes
if ((!p1 and !p2) ||
((p1 && p1->l.ghost) && (p2 && p2->l.ghost)) ||
(!p1 && p2->l.ghost) || (!p2 && p1->l.ghost)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Couldn't this whole conditional be rewritten as: ((!p1 || p1->l.ghost) && (!p2 || p2->l.ghost))


} else { // We have at least one
} else { // We consider teh pair
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo: "the". We could add here: "because at least one of p1 and p2 is local to this node".


// place virtual sites on the node where the base particle is not a
// ghost
if (!p1->l.ghost)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it safe to deref p1 here (and p2 in the following)?

There is the corner case that one of the two particle pointers is null and the other is local which is not caught by the if. This should not happen as the two particles got queued by a short_range_loop? Should we at least comment on that fact?

// but we still increase the particle counters, as other nodes
// can not always know whether or not a vs is placed
if ((p1->p.type == collision_params.part_type_after_glueing) ||
(p2->p.type == collision_params.part_type_after_glueing)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

One conditional would suffice:

if (p1->p.type != collision_params.part_type_to_be_glued
    || p2->p.type != collision_params.part_type_to_be_glued) {
//...
}

However, keep both the comments.


// Add a bond between the centers of the colliding particles
// The bond is placed on the node that has p1
if (!local_particles[c.pp1]->l.ghost) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we use local_particles[c.pp1] here and not simply p1?
Also below, there is another occurrence of a deref via local_particles. But also a direct use of p1.

@RudolfWeeber
Copy link
Contributor Author

RudolfWeeber commented Aug 29, 2018 via email

@RudolfWeeber
Copy link
Contributor Author

RudolfWeeber commented Aug 29, 2018 via email

@@ -598,7 +598,7 @@ void handle_collisions() {
// ore one is ghost and one is not accessible
// we only increase the counter for the ext id to use based on the
// number of particles created by other nodes
if ((!p1 or p1->l.ghost) and (!p2 or p2->l.ghost)) {
if ((!p1 or p1->l.ghost) and (!p2 or p2->l.ghost) or !p1 or !p2) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the two !px in the and are now superfluous. This should be equivalent to:

if (!p1 || !p2 || (p1->l.ghost && p2->l.ghost))

@fweik fweik merged commit d310670 into espressomd:python Aug 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants