Skip to content

Colloids

Sebastian Schmieschek edited this page Aug 12, 2015 · 2 revisions

= Colloids Code Design == Particle Configuration

The first version of particle configuration will include information that defines the particle (a unique identifier, two radii and an initial position vector).

This basic information is sufficient to get particles to exist and move within the simulation. At this stage, tests can be performed to ensure that transitions from one processor domain to another work correctly and to measure the performance impact relative to the same simulation without particles. In addition, boundary conditions and visualisation for particles can be added and tested at this stage.

The second version will add a magnetic dipole vector, which will allow particles to interact with the magnetic field in the simulation, if any.

The magnetic field is not specific to colloids and should be added as a separate component. This component may be steerable and may produce a constant magnetic field (i.e. has an identical for each lattice site and any position in between) or a variable one (i.e. has a different value for each lattice site and any position in between). It should expose a function that returns the magnetic field vector at any given position for the current time-step, which will be used by the colloid code when calculating the body force on particles due to magnetism. Gravitational force can be added at this stage as well. Gravity is a constant field for the scales required by this simulation code (both in time and lattice-space) but its effects are modified by viscosity, which is a property of the fluid.

The third version will add an initial time-step, i.e. when the particle first enters the simulation.

Injection of particles at a certain rate during the simulation will be achieved by calculating the initial positions and the initial time-step parameters pre-simulation, i.e. this is an extension to the setup tool. This approach allows random positioning within a region of the simulation domain and dynamic creation of particles during the simulation but maintains repeatability (the positions are pseudo-random but also pre-determined), avoids the problems associated with the injection region being distributed across multiple processors and avoids problems with dynamic creation of particles.

== Particle Configuration File Format === Version 1

<Particles>
 <SubGridParticle>
  <ParticleId value=”int”/>
  <InputRadiusA0 value=”double”/>
  <HydrostaticRadiusAh value=”double”/>
  <InitialPosition xValue=”double” yValue=”double” zValue=”double”/> 
 </SubGridParticle>
</Particles>

=== Version 2

<Particles>
 <SubGridParticle>
  <ParticleId value=”int”/>
  <InputRadiusA0 value=”double”/>
  <HydrostaticRadiusAh value=”double”/>
  <InitialPosition xValue=”double” yValue=”double” zValue=”double”/> 
  <MagneticSpin xValue=”double” yValue=”double” zValue=”double”/> 
 </SubGridParticle>
</Particles>

=== Version 3

<Particles>
 <SubGridParticle>
  <ParticleId value=”int”/>
  <InputRadiusA0 value=”double”/>
  <HydrostaticRadiusAh value=”double”/>
  <InitialPosition xValue=”double” yValue=”double” zValue=”double”/> 
  <MagneticSpin xValue=”double” yValue=”double” zValue=”double”/> 
  <TimestepRange minValue=”int” maxValue=”int”/>
 </SubGridParticle>
</Particles>

== Functions From subgrid.c in Ludwig:-

Vector3D<double> InterpolateLocalFluidVelocity(
	const MacroscopicPropertyCache cachedLatticeData,
	const Neighbourhood neighbourhood,
	const Vector3D<double> positionOfParticle)
void Particle::UpdatePosition(
	const Vector3D<double> fluidVelocity,
	const Vector3D<double> bodyForce1)
void Particle::AccumulateForceOnFluid(
	const Vector3D<double> bodyForce2,
	MacroscopicPropertyCache cachedLatticeData)
double deltaPeskin(double r)
double deltaPeskin(Vector3D<double> r)

Notes:-

bodyForce1 = drag * g = reta * (1/a0 – 1/ah) * g = (1/a0 – 1/ah) / (6*pi*etaShear) * g
bodyForce2 = g
deltaPeskin( r[i] ) = deltaPeskin( positionOfParticle - latticeSiteLocation[i] )
positionOfParticle - latticeSiteLocation[i] = neighbourhood[i] // for 0 <= i < neighbourhood.size
g = gravity force vector, initialisation constant, default value (0.0, 0.0, 0.0)
etaShear = initialisation constant, default value 1.0/6.0

== Particle Communication There are two types of information that must be communicated each time-step for colloids: the information about each local particle (id, radii, position and the force on particle due to body forces) and the contributions to the fluid velocity interpolation for each remote particle. Both of these messages involve the exchange of variable length lists of data items. This communication pattern can be achieved with the following point-to-point functions, per time-step: a) Send the number of local particles, N, to each neighbour processor. b) Receive the number of remote particles, M, from each neighbour processor. c) Send the list (length N) of local particle structures to each neighbour processor. d) Receive the list (length M) of remote particle structures from each neighbour processor. e) Send the local contribution to the fluid velocity interpolation for each remote particle to the appropriate neighbour processor – a list of velocity vectors of length M. f) Receive the remote contribution to the fluid velocity interpolation for each local particle from the appropriate neighbour processor – a list of velocity vectors of length N. == Particle Calculation There are two parts to the calculation for colloid simulation in each time-step: determining the change of position for each local particle and determining the cumulative force on each local fluid site due to particles (local and remote). Determining the change of position for a local particle involves the following steps:

  1. Calculate the body force(s) at the position of the particle.
  2. Interpolate the fluid velocity using sites within the effective region around the particle.
  3. Combine the fluid velocity and the body force(s). Determining the cumulative force due to particles for a local lattice site involves the following steps:
  4. Calculate the effect of body force(s) for particles within the effective region around the site.
  5. Accumulate the contribution to the force on the lattice site from each particle. The fluid velocity at each lattice site must be consistent, i.e. all values must be from the same LBM time-step. These velocity values are updated in the property cache as the new value is calculated. The new values are calculated for edge sites first (in the PreSend method), then for mid-domain sites (in the PreReceive method) and finally some sites are modified with information received from neighbour processes (in the PostReceive method). The whole lattice data state is swapped between old and new during the EndIteration method. Therefore, the only time that another IteratedAction “actor” is guaranteed to get a consistent state of the fluid (that does not depend on the order in which the actors are handled) is during its RequestComms method. In addition, the force on lattice sites due to particles is needed in the LBM calculation, i.e. in the PreSend and the PreReceive methods, which requires that this information is also calculated during the RequestComms method. == Code Design The ColloidController will inherit from IteratedAction and override the RequestComms method only. All the calculation and communication for a single colloid time-step will be happen in this method. The various calculation and communication steps will be written as separate functions. This allows them to be called by the RequestComms method initially but also simplifies refactoring the code if the communication pattern in the rest of !HemeLB changes in future.

== Object Model (incomplete - TODO: elaborate) Particle – an individual particle, storing basic information plus transient values such as velocity.

ParticleSet – the set of particles known to a particular process.

MpiTypeParticle – the MPI type describing the memory layout of a particle object.

ParticleConfigurator – reads and writes particle information (XML file to/from property bag).

Clone this wiki locally