Skip to content

UUID manager needs to be designed #3892

Open
@jngrad

Description

@jngrad

Shape-based constraints have a particle representation Particle ShapeBasedConstraint::part_rep which is default-constructed, therefore its particle id is always -1. This causes an issue when a real particle interacts with two shape-based constraints via the DPD interaction, which requires random numbers. Philox maps a tuple (counter, seed, salt, pid1, pid2) to a unique 4-tuple of 64bit integers. If a particle with id pid1 interacts with e.g. two parallel walls via the DPD interaction, pid2 will be -1 for both walls and the noise will be correlated.

Currently we work around this issue by incrementing the DPD thermostat counter. This has several issues:

  • simulation reproducibility: the order by which the constraints are traversed in the short-range loop matters
  • running system.integrator.run(0, recalc_forces=True) to update the forces alters the system state by incrementing the RNG counter
  • we cannot use a single, monotonically increasing global counter

A couple ideas I and @KaiSzuttor came up with to solve the issue:

  1. Instantiate "pseudo particles" such as the one used as a representation of shape-based constraints with the help of a function int get_maximal_pseudo_particle_id() that would work like the existing int get_maximal_particle_id() function. This function would be used to decrement the particle id, e.g. create a series -2, -3, -4, ..., because we must generate particle ids that live in the 32bit range while not colliding with particle ids from "real" particles (otherwise the correlation is not solved but moved to a different place). If such a function cannot be created, a global counter for "pseudo particles" could be used. Things to keep in mind:
    • nothing prevents the user from creating particles with values close to 2^32
  2. Let the user instantiate real particles and use them as a parameter to objects that need a particle representation. For example, a wall constraint would be created with:
    p = system.part.add(pos=[0, 0, 0], type=2)
    shape_constraint = espressomd.constraints.ShapeBasedConstraint(shape=my_shape)
    constraint = system.constraints.add(shape=shape_constraint, particle_representation=p)
    instead of:
    shape_constraint = espressomd.constraints.ShapeBasedConstraint(shape=my_shape)
    constraint = system.constraints.add(shape=shape_constraint, particle_type=2)
    The constraint object would contain a shared pointer to the particle. Things to keep in mind:
    • the pseudo particle now lives in the cell system
    • particle slices will contain this particle, e.g. system.part[:].f now contains the constraint's particle "force" (it's unclear what its value should be)
    • integrators should not calculate its force, nor propagate it, nor use it to halt integration (steepest descent)
    • no particle coupling in LB
    • most members of the pseudo particle are meaningless (e.g. mass), possible issues with observables?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions