OpenMPCD
StarPolymers.hpp
Go to the documentation of this file.
1 /**
2  * @file
3  * Defines the `OpenMPCD::CUDA::MPCSolute::StarPolymers` class.
4  */
5 
6 #ifndef OPENMPCD_CUDA_MPCSOLUTE_STARPOLYMERS_HPP
7 #define OPENMPCD_CUDA_MPCSOLUTE_STARPOLYMERS_HPP
8 
10 
12 
16 #include <OpenMPCD/PairPotentials/FENE.hpp>
18 #include <OpenMPCD/PairPotentials/WeeksChandlerAndersen_DistanceOffset.hpp>
20 
21 #include <boost/scoped_array.hpp>
22 
23 namespace OpenMPCD
24 {
25 namespace CUDA
26 {
27 namespace MPCSolute
28 {
29 
30 /**
31  * Class representing star polymers.
32  *
33  * A star polymer consists of one central core particle, attached to which there
34  * are a number of linear, homogeneous polymer chains, called "arms". The ends
35  * of the arms may be functionalized, by attaching an additional particle that
36  * carries a magnetic dipole moment.
37  *
38  * The following three interaction potentials (magnetic, FENE, and WCA) are
39  * cumulative, i.e. a pair of particles can be subject to interaction due to two
40  * or more interactions at the same time.
41  *
42  * The functionalized magnetic particles interact with one another via the
43  * `OpenMPCD::PairPotentials::MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles`
44  * interaction.
45  * The `prefactor` property of the interaction class is set according to the
46  * `interactionParameters.magneticPrefactor` configuration property.
47  * The orientation of the dipoles may be set via the
48  * `interactionParameters.dipoleOrientation` setting, which must be an array of
49  * three floating-point values which define an axis. The vector formed by these
50  * three values need not be normalized; its magnitude is of no relevance.
51  *
52  * Bonded particles -- i.e. next neighbors in an arm, the central core particle
53  * and the particles attached to it, or the functionalized particles with their
54  * direct neighbor in the corresponding arm -- interact via the
55  * `OpenMPCD::PairPotentials::FENE` potential.
56  * The interaction parameters `K`, `l_0` and `R` are set to \f$ K_{\mu\nu} \f$,
57  * \f$ l_{\mu\nu} \f$, and \f$ R_{\mu\nu} \f$, respectively, which will be
58  * described below. The indices \f$ \mu \f$ and \f$ \nu \f$ denote between which
59  * kinds of particles (i.e. core, arm, or magnetic) the interaction effects a
60  * force.
61  *
62  * Finally, each pair of particles interacts via the
63  * `OpenMPCD::PairPotentials::WeeksChandlerAndersen_DistanceOffset` (WCA)
64  * potential.
65  * The interaction parameters `epsilon`, `sigma`, and `d` are set to
66  * \f$ \varepsilon_{\mu\nu} \f$, \f$ \sigma_{\mu\nu} \f$, and
67  * \f$ D_{\mu\nu} \f$, respectively, which will be described below.
68  * The indices \f$ \mu \f$ and \f$ \nu \f$ have the same meaning as with the
69  * FENE potential.
70  *
71  * In the configuration group `interactionParameters`, one has to set
72  * `epsilon_core`, `epsilon_arm`, and `epsilon_magnetic`, which will be referred
73  * to as \f$ \varepsilon_C \f$, \f$ \varepsilon_A \f$, and
74  * \f$ \varepsilon_M \f$, respectively.
75  * Similarly, the properties `sigma_core`, `sigma_arm`, and `sigma_magnetic`
76  * define \f$ \sigma_C \f$, \f$ \sigma_A \f$, and \f$ \sigma_M \f$, and
77  * `D_core`, `D_arm`, and `D_magnetic` define \f$ D_C \f$, \f$ D_A \f$, and
78  * \f$ D_M \f$.
79  * Finally, one also has to set `magneticPrefactor` in the
80  * `interactionParameters` group. The `dipoleOrientation` array, if not set,
81  * will be assumed to be `[0, 0, 1]`.
82  *
83  * From these quantities, the values for \f$ \varepsilon_{\mu\nu} \f$,
84  * \f$ \sigma{\mu\nu} \f$, and \f$ D_{\mu\nu} \f$, where each \f$ \mu \f$ and
85  * \f$ \nu \f$ can take on the values \f$ C \f$ for core particles, \f$ A \f$
86  * for non-functionalized arm particles, and \f$ M \f$ for functionalized
87  * magnetic particles, can be calculated according to the Lorentz-Berthelot
88  * mixing rules:
89  * \f[ \varepsilon_{\mu\nu} = \sqrt{ \varepsilon_\mu \varepsilon_\nu } \f]
90  * \f[ \sigma_{\mu\nu} = \frac{ \sigma_\mu + \sigma_\nu }{ 2 } \f]
91  * \f[ D_{\mu\nu} = \frac{ D_\mu + D_\nu }{ 2 } \f]
92  *
93  * Finally, the parameters \f$ l_{\mu\nu} \f$, \f$ R_{\mu\nu} \f$, and
94  * \f$ K_{\mu\nu} \f$, are defined via
95  * \f[ l_{\mu\nu} = D_{\mu\nu} \f]
96  * \f[ R_{\mu\nu} = 1.5 \sigma_{\mu\nu} \f]
97  * \f[ K_{\mu\nu} = 30 \varepsilon_{\mu\nu} \sigma_{\mu\nu}^{-2} \f]
98  *
99  *
100  * In addition to the `interactionParmeters` settings group, the configuration
101  * passed to the constructor is expected to contain the `structure` group,
102  * which contains in `starCount` the number of stars, in `armCountPerStar` how
103  * many arms each star has, in `armParticlesPerArm` how many ordinary arm
104  * particles there are in each arm, and in `hasMagneticParticles` whether
105  * each arm should be terminated with a magnetic particle (in addition
106  * to the ordinary arm particles). Furthermore, `particleMass` contains the mass
107  * each individual particle has.
108  *
109  * Furthermore, one must set `mdTimeStepSize` to the number of MPC time units
110  * one should advance per MD time-step, which must be a positive number.
111  *
112  * If the configuration contains the value `initialState`, its value is
113  * taken as a path of a VTF snapshot file (see `OpenMPCD::VTFSnapshotFile`) that
114  * specifies the initial configuration of the stars. If the snapshot does not
115  * contain velocity information, initial velocities are assumed to be zero.
116  *
117  * @tparam PositionCoordinate The type to store position coordinates.
118  * @tparam VelocityCoordinate The type to store velocity coordinates.
119  */
120 template<
121  typename PositionCoordinate = MPCParticlePositionType,
122  typename VelocityCoordinate = MPCParticleVelocityType>
124  : public MPCSolute::Base<PositionCoordinate, VelocityCoordinate>
125 {
126 public:
127  typedef PositionCoordinate ForceCoordinate;
128  ///< The type to store force coordinates.
129 
131  ///< Holds the enumeration of particle types.
132 
133 public:
134  /**
135  * The constructor.
136  *
137  * @throw OpenMPCD::InvalidConfigurationException
138  * Throws if the configuration is not valid.
139  *
140  * @param[in] settings
141  * The configuration for this instance.
142  * @param[in] boundaryCondition
143  * The boundary conditions that have been configured. Currently,
144  * only LeesEdwards boundary conditions are supported.
145  */
146  StarPolymers(
147  const Configuration::Setting& settings,
148  const BoundaryCondition::Base* const boundaryCondition);
149 
150 private:
151  StarPolymers(const StarPolymers&); ///< The copy constructor.
152 
153 public:
154  /**
155  * The destructor.
156  */
157  virtual ~StarPolymers();
158 
159 public:
160  /**
161  * Performs, on the Device, an MD timestep of size `getMDTimeStepSize()`.
162  */
163  void performMDTimestep();
164 
165  /**
166  * Returns the total number of polymer stars in this instance.
167  */
168  std::size_t getStarCount() const
169  {
170  return 1;
171  }
172 
173  /**
174  * Returns the number of arms per star.
175  */
176  std::size_t getArmCountPerStar() const;
177 
178  /**
179  * Returns the number of particles per arm.
180  */
181  std::size_t getParticleCountPerArm() const;
182 
183  /**
184  * Returns whether arms have an additional magnetic particle attached.
185  */
186  bool hasMagneticParticles() const;
187 
188  /**
189  * Returns the number of particles per arm, including magnetic particles.
190  */
192 
193  /**
194  * Returns the total number of individual particles per star.
195  */
196  std::size_t getParticleCountPerStar() const;
197 
198  /**
199  * Returns the total number of individual particles in all stars.
200  */
201  std::size_t getParticleCount() const;
202 
203  /**
204  * Returns the number of logical entities in the solute.
205  */
206  std::size_t getNumberOfLogicalEntities() const
207  {
208  return getStarCount();
209  }
210 
211  /**
212  * Returns the mass of a particle, which is assumed to be equal for all
213  * particles in this instance.
214  */
215  virtual FP getParticleMass() const
216  {
217  return particleMass;
218  }
219 
220  /**
221  * Writes structure information to the given snapshot file.
222  *
223  * @throw OpenMPCD::NULLPointerException
224  * Throws if `snapshot == nullptr`.
225  * @throw OpenMPCD::InvalidArgumentException
226  * Throws if the given snapshot is not in write mode, or if the
227  * structure block already has been processed.
228  *
229  * @param[in,out] snapshot The snapshot file.
230  */
231  void writeStructureToSnapshot(VTFSnapshotFile* const snapshot) const;
232 
233  /**
234  * Writes the particle positions and velocities to the given snapshot file.
235  *
236  * This function will call `fetchFromDevice`, and write the current Device
237  * data to the given snapshot file.
238  *
239  * @throw OpenMPCD::NULLPointerException
240  * Throws if `snapshot == nullptr`.
241  * @throw OpenMPCD::InvalidArgumentException
242  * Throws if the number of atoms declared in the snapshot does not
243  * match the number of particles in this instance.
244  * @throw OpenMPCD::InvalidArgumentException
245  * Throws if the given snapshot is not in write mode.
246  *
247  * @param[in,out] snapshot The snapshot file.
248  */
249  void writeStateToSnapshot(VTFSnapshotFile* const snapshot) const;
250 
251  /**
252  * Reads the next timestep block from the given snapshot file, and uses it
253  * as the current state.
254  *
255  * If no velocities are specified, the current ones are kept.
256  *
257  * @throw OpenMPCD::NULLPointerException
258  * If `OPENMPCD_DEBUG` is defined, throws if `snapshot == nullptr`.
259  * @throw OpenMPCD::InvalidArgumentException
260  * Throws if `!snapshotStructureIsCompatible()`.
261  *
262  * @param[in,out] snapshot The snapshot file to read from.
263  */
264  void readStateFromSnapshot(VTFSnapshotFile* const snapshot);
265 
266  /**
267  * Returns whether the given snapshot file is compatible with the star
268  * polymer architecture, e.g. whether the number of stars, arms per star,
269  * etc. match.
270  *
271  * If `!snapshot.isInReadMode()`, `false` is returned.
272  *
273  * @param[in] snapshot The snapshot to check for compatibility.
274  */
275  bool snapshotStructureIsCompatible(const VTFSnapshotFile& snapshot) const;
276 
277 private:
278  StarPolymers& operator=(const StarPolymers); ///< The assignment operator.
279 
280 private:
281  /**
282  * Returns whether the given particle ID is valid, i.e. whether
283  * `particleID < getParticleCount()`.
284  *
285  * @param[in] particleID The particle ID to query.
286  */
287  bool isValidParticleID(const std::size_t particleID) const;
288 
289  /**
290  * Returns the particle type that corresponds to the given ID.
291  *
292  * @throw OpenMPCD::OutOfBoundsException
293  * If `OPENMPCD_DEBUG` is defined, throws if
294  * `!isValidParticleID(particleID)`.
295  *
296  * @param[in] particleID The particle ID to get the type for.
297  */
298  typename ParticleType::Enum
299  getParticleType(const std::size_t particleID) const;
300 
301  /**
302  * Returns the particle ID for the given input.
303  *
304  * Use of this function implies that the particle in question is part of an
305  * arm.
306  *
307  * @throw OpenMPCD::OutOfBoundsException
308  * If `OPENMPCD_DEBUG` is defined, throws if `star >= getStarCount()`.
309  * @throw OpenMPCD::OutOfBoundsException
310  * If `OPENMPCD_DEBUG` is defined, throws if
311  * `arm >= getArmCountPerStar()`.
312  * @throw OpenMPCD::OutOfBoundsException
313  * If `OPENMPCD_DEBUG` is defined, throws if
314  * `particleInArm >= getParticleCountPerArm()`.
315  *
316  * @param[in] star The ID of the star, starting at `0`.
317  * @param[in] arm The ID of the arm, starting at `0`.
318  * @param[in] particleInArm The ID of the particle in the arm, starting at
319  * `0`.
320  */
321  std::size_t getParticleID(
322  const std::size_t star, const std::size_t arm,
323  const std::size_t particleInArm) const;
324 
325  /**
326  * Returns the particle ID for the given input.
327  *
328  * Use of this function implies that the particle in question is a magnetic
329  * particle.
330  *
331  * @throw OpenMPCD::OutOfBoundsException
332  * If `OPENMPCD_DEBUG` is defined, throws if `star >= getStarCount()`.
333  * @throw OpenMPCD::OutOfBoundsException
334  * If `OPENMPCD_DEBUG` is defined, throws if
335  * `arm >= getArmCountPerStar()`.
336  *
337  * @param[in] star The ID of the star, starting at `0`.
338  * @param[in] arm The ID of the arm, starting at `0`.
339  */
340  std::size_t getParticleID(
341  const std::size_t star, const std::size_t arm) const;
342 
343  /**
344  * Returns the particle ID for the given input.
345  *
346  * Use of this function implies that the particle in question is a core
347  * particle.
348  *
349  * @throw OpenMPCD::OutOfBoundsException
350  * If `OPENMPCD_DEBUG` is defined, throws if `star >= getStarCount()`.
351  *
352  * @param[in] star The ID of the star, starting at `0`.
353  */
354  std::size_t getParticleID(const std::size_t star) const;
355 
356 
357  /**
358  * Initializes the positions on the Host.
359  */
360  void initializePositionsOnHost();
361 
362  /**
363  * Initializes the velocities on the Host.
364  */
365  void initializeVelocitiesOnHost();
366 
367 private:
368  std::size_t starCount; ///< The number of stars.
369  std::size_t armCountPerStar; ///< The number of arms per star.
370  std::size_t armParticlesPerArm; ///< The number of particles per arm.
371  bool hasMagneticParticles_; ///< Whether the arms have magnetic ends.
372 
373  FP particleMass; ///< The mass of any one particle.
374 
375  ForceCoordinate* d_forces1; ///< Work buffer storing forces.
376  ForceCoordinate* d_forces2; ///< Work buffer storing forces.
377 
379  wcaPotentials; ///< The general particle-particle interactions.
381  fenePotentials; ///< The interactions for bonded pairs.
382  PairPotentials::
383  MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles<
384  ForceCoordinate>**
385  magneticPotential;
386  ///< The interactions for pairs of magnetic particles.
387 
388 private:
392 
399 }; //class StarPolymers
400 
401 } //namespace MPCSolute
402 } //namespace CUDA
403 } //namespace OpenMPCD
404 
405 #endif //OPENMPCD_CUDA_MPCSOLUTE_STARPOLYMERS_HPP
OpenMPCD::PairPotentials::WeeksChandlerAndersen_DistanceOffset< ForceCoordinate >
OpenMPCD::CUDA::MPCSolute::StarPolymers::getParticleCountPerArmIncludingMagneticParticles
std::size_t getParticleCountPerArmIncludingMagneticParticles() const
Returns the number of particles per arm, including magnetic particles.
OpenMPCD::CUDA::MPCSolute::StarPolymers::ForceCoordinate
PositionCoordinate ForceCoordinate
The type to store force coordinates.
Definition: StarPolymers.hpp:127
OpenMPCD::CUDA::MPCSolute::StarPolymers::StarPolymers
StarPolymers(const Configuration::Setting &settings, const BoundaryCondition::Base *const boundaryCondition)
The constructor.
OpenMPCD::CUDA::MPCSolute::ImplementationDetails::StarPolymers::ParticleType
Holds the enumeration of particle types for star polymers.
Definition: StarPolymers_ParticleType.hpp:24
OpenMPCD::CUDA::MPCSolute::StarPolymers::getStarCount
std::size_t getStarCount() const
Returns the total number of polymer stars in this instance.
Definition: StarPolymers.hpp:168
Base.hpp
OpenMPCD::CUDA::MPCSolute::StarPolymers::getArmCountPerStar
std::size_t getArmCountPerStar() const
Returns the number of arms per star.
OpenMPCD::CUDA::MPCSolute::StarPolymers::writeStateToSnapshot
void writeStateToSnapshot(VTFSnapshotFile *const snapshot) const
Writes the particle positions and velocities to the given snapshot file.
OpenMPCD::MPCParticlePositionType
FP MPCParticlePositionType
The data type for the positions of MPC particles.
Definition: Types.hpp:15
OpenMPCD::CUDA::MPCSolute::ImplementationDetails::StarPolymers::ParticleType::Enum
Enum
Enumerates particle types.
Definition: StarPolymers_ParticleType.hpp:30
OpenMPCD::CUDA::MPCSolute::StarPolymers::getParticleMass
virtual FP getParticleMass() const
Returns the mass of a particle, which is assumed to be equal for all particles in this instance.
Definition: StarPolymers.hpp:215
OpenMPCD::CUDA::MPCSolute::Base
Base class for MPC solutes.
Definition: CUDA/MPCSolute/Base.hpp:35
VTFSnapshotFile.hpp
OpenMPCD::CUDA::MPCSolute::StarPolymers::~StarPolymers
virtual ~StarPolymers()
The destructor.
LeesEdwards.hpp
OpenMPCD::CUDA::MPCSolute::StarPolymers::performMDTimestep
void performMDTimestep()
Performs, on the Device, an MD timestep of size getMDTimeStepSize().
OpenMPCD::CUDA::MPCSolute::StarPolymers::writeStructureToSnapshot
void writeStructureToSnapshot(VTFSnapshotFile *const snapshot) const
Writes structure information to the given snapshot file.
OpenMPCD::CUDA::MPCSolute::StarPolymers::hasMagneticParticles
bool hasMagneticParticles() const
Returns whether arms have an additional magnetic particle attached.
DeviceMemoryManager.hpp
OpenMPCD::PairPotentials::FENE< ForceCoordinate >
OpenMPCD::FP
double FP
Default floating point type.
Definition: Types.hpp:13
StarPolymers_ParticleType.hpp
OpenMPCD::MPCParticleVelocityType
FP MPCParticleVelocityType
The data type for the velocities of MPC particles.
Definition: Types.hpp:16
OpenMPCD::CUDA::MPCSolute::StarPolymers::getNumberOfLogicalEntities
std::size_t getNumberOfLogicalEntities() const
Returns the number of logical entities in the solute.
Definition: StarPolymers.hpp:206
OpenMPCD::CUDA::MPCSolute::StarPolymers::getParticleCount
std::size_t getParticleCount() const
Returns the total number of individual particles in all stars.
OpenMPCD::CUDA::MPCSolute::StarPolymers::getParticleCountPerArm
std::size_t getParticleCountPerArm() const
Returns the number of particles per arm.
OpenMPCD::Configuration::Setting
Represents a setting in the configuration.
Definition: Configuration.hpp:36
Configuration.hpp
OpenMPCD::VTFSnapshotFile
Representation of a simulation snapshot file in the VTF format.
Definition: VTFSnapshotFile.hpp:49
MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles.hpp
OpenMPCD::CUDA::MPCSolute::StarPolymers::getParticleCountPerStar
std::size_t getParticleCountPerStar() const
Returns the total number of individual particles per star.
OpenMPCD::CUDA::MPCSolute::StarPolymers
Class representing star polymers.
Definition: StarPolymers.hpp:123
OpenMPCD::CUDA::MPCSolute::StarPolymers::ParticleType
ImplementationDetails::StarPolymers::ParticleType ParticleType
Holds the enumeration of particle types.
Definition: StarPolymers.hpp:130
OpenMPCD::CUDA::BoundaryCondition::Base
Base class for boundary condition.
Definition: CUDA/BoundaryCondition/Base.hpp:26
OpenMPCD::CUDA::MPCSolute::StarPolymers::snapshotStructureIsCompatible
bool snapshotStructureIsCompatible(const VTFSnapshotFile &snapshot) const
Returns whether the given snapshot file is compatible with the star polymer architecture,...
OpenMPCD::CUDA::MPCSolute::StarPolymers::readStateFromSnapshot
void readStateFromSnapshot(VTFSnapshotFile *const snapshot)
Reads the next timestep block from the given snapshot file, and uses it as the current state.