Fix potential problem in Messenger related to MPI window
[hoomd-blue.git] / libhoomd / data_structures / RandomGenerator.h
blob3c11f02fe3b808fadc16ee7c4aef297a277f8d4c
1 /*
2 Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
3 (HOOMD-blue) Open Source Software License Copyright 2009-2014 The Regents of
4 the University of Michigan All rights reserved.
6 HOOMD-blue may contain modifications ("Contributions") provided, and to which
7 copyright is held, by various Contributors who have granted The Regents of the
8 University of Michigan the right to modify and/or distribute such Contributions.
10 You may redistribute, use, and create derivate works of HOOMD-blue, in source
11 and binary forms, provided you abide by the following conditions:
13 * Redistributions of source code must retain the above copyright notice, this
14 list of conditions, and the following disclaimer both in the code and
15 prominently in any materials provided with the distribution.
17 * Redistributions in binary form must reproduce the above copyright notice, this
18 list of conditions, and the following disclaimer in the documentation and/or
19 other materials provided with the distribution.
21 * All publications and presentations based on HOOMD-blue, including any reports
22 or published results obtained, in whole or in part, with HOOMD-blue, will
23 acknowledge its use according to the terms posted at the time of submission on:
24 http://codeblue.umich.edu/hoomd-blue/citations.html
26 * Any electronic documents citing HOOMD-Blue will link to the HOOMD-Blue website:
27 http://codeblue.umich.edu/hoomd-blue/
29 * Apart from the above required attributions, neither the name of the copyright
30 holder nor the names of HOOMD-blue's contributors may be used to endorse or
31 promote products derived from this software without specific prior written
32 permission.
34 Disclaimer
36 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND
37 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR ANY
39 WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.
41 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
42 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
43 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
45 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
46 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
47 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 // Maintainer: joaander
52 /*! \file RandomGenerator.h
53 \brief Contains declarations for RandomGenerator and related classes.
56 #ifdef NVCC
57 #error This header cannot be compiled by nvcc
58 #endif
60 #include "ParticleData.h"
62 #include "SnapshotSystemData.h"
64 #include <string>
65 #include <vector>
66 #include <map>
68 #include <boost/shared_ptr.hpp>
69 #include <boost/random.hpp>
71 #ifndef __RANDOM_GENERATOR_H__
72 #define __RANDOM_GENERATOR_H__
74 //! Stores particles as they are generated in RandomGenerator
75 /*! \ingroup data_structs
76 GeneratedParticles is a holding area where particles are stored when
77 being generated by RandomGenerator and ParticleGenerator instances.
79 It includes helper functions and data structures for placing particles
80 that do not overlap. These helpers use the radius for each particle type
81 as specified by setSeparationRadius(). Every particle type that will be
82 generated must be specified before generation can begin.
84 After all particles are placed in GeneratedParticles, RandomGenerator will
85 then translate that data over to ParticleData in the initializer.
87 class GeneratedParticles
89 public:
90 //! Stores a single particle in GeneratedParticles
91 struct particle
93 //! Default constructor
94 particle() : x(0.0), y(0.0), z(0.0), ix(0), iy(0), iz(0), type("") {}
95 Scalar x; //!< X-coordinate
96 Scalar y; //!< Y-coordinate
97 Scalar z; //!< Z-coordinate
98 int ix; //!< Shift in x direction
99 int iy; //!< Shift in y direction
100 int iz; //!< Shift in z direction
101 std::string type; //!< Particle's type name
102 unsigned int type_id; //!< Particle's type id
105 //! Constructor
106 GeneratedParticles(boost::shared_ptr<const ExecutionConfiguration> exec_conf, unsigned int n_particles, const BoxDim& box, const std::map< std::string, Scalar >& radii);
107 //! Empty constructor
108 /*! Included so that GeneratedParticles can be stored in a vector.
110 GeneratedParticles() { }
112 //! Check if a particle can be placed while obeying the separation radii
113 bool canPlace(const particle& p);
115 //! Place a particle
116 void place(const particle& p, unsigned int idx);
118 //! Undo the placement of a particle
119 void undoPlace(unsigned int idx);
121 //! Get the box
122 const BoxDim& getBox()
124 return m_box;
127 //! Add a bond
128 void addBond(unsigned int a, unsigned int b, const std::string& type="");
130 private:
131 friend class RandomGenerator;
133 boost::shared_ptr<const ExecutionConfiguration> m_exec_conf; //!< The execution configuration
134 std::vector<particle> m_particles; //!< The generated particles
135 BoxDim m_box; //!< Box the particles are in
136 std::vector< std::vector<unsigned int> > m_bins; //!< Bins the particles are placed in for efficient distance checks
137 int m_Mx; //!< Number of bins in the x direction
138 int m_My; //!< Number of bins in the y direction
139 int m_Mz; //!< Number of bins in the z direction
140 std::map< std::string, Scalar > m_radii; //!< Separation radii accessed by particle type
142 //! Structure representing a single bond
143 struct bond
145 //! Default constructor
146 bond() : tag_a(0), tag_b(0), type(""), type_id(0)
150 //! Construct a bond between two particles
151 /*! \param a tag of the first particle in the bond
152 \param b tag of the second particle in the bond
153 \param _type the type name of the bond
155 bond(unsigned int a, unsigned int b, const std::string& _type) : tag_a(a), tag_b(b), type(_type), type_id(0)
158 unsigned int tag_a; //!< First particle in the bond
159 unsigned int tag_b; //!< Second particle in the bond
160 std::string type; //!< Type of the bond
161 unsigned int type_id; //!< Type id of the bond (assigned in RandomGenerator::generate())
164 std::vector< bond > m_bonds; //!< Bonds read in from the file
167 //! Abstract interface for classes that generate particles
168 /*! \ingroup data_structs
169 A ParticleGenerator is the workhorse that actually chooses where to place particles.
170 A single ParticleGenerator should only place a small number of inter-related particles
171 on each call to generateParticles() (i.e. a single polymer or a small cluster of particles).
172 Larger systems are to be built from multiple calls of generateParticles() by RandomGenerator.
174 class ParticleGenerator
176 public:
177 //! Destructor
178 virtual ~ParticleGenerator() {}
180 //! Returns the number of particles that will be generated
181 /*! Derived classes must implement this method so that RandomGenerator
182 can properly allocate the space for the particles.
184 The value returned by this function cannot vary from call to call
185 for a particular instance of ParticleGenerator. Once instantiated,
186 a ParticleGenerator must always generate the same number of particles
187 each time it is called.
189 virtual unsigned int getNumToGenerate()=0;
191 //! Actually generate the requested particles
192 /*! \param particles Place generated particles here after a GeneratedParticles::canPlace() check
193 \param rnd Random number generator to use
194 \param start_idx Starting index to generate particles at
195 Derived classes must implement this method. RandomGenerator will
196 call it to generate the particles. Particles should be placed at indices
197 \a start_idx, \a start_idx + 1, ... \a start_idx + getNumToGenerate()-1
199 virtual void generateParticles(GeneratedParticles& particles, boost::mt19937& rnd, unsigned int start_idx)=0;
202 //! Generates random polymers
203 /*! \ingroup data_structs
204 This ParticleGenerator can be used to generate systems of bead-spring polymers of any combination of
205 partile types specified in an array.
207 class PolymerParticleGenerator : public ParticleGenerator
209 public:
210 //! Constructor
211 PolymerParticleGenerator(boost::shared_ptr<const ExecutionConfiguration> exec_conf,
212 Scalar bond_len,
213 const std::vector<std::string>& types,
214 const std::vector<unsigned int>& bond_a,
215 const std::vector<unsigned int>& bond_b,
216 const std::vector<string>& bond_type,
217 unsigned int max_attempts,
218 unsigned int dimensions);
220 //! Returns the number of particles in each polymer
221 virtual unsigned int getNumToGenerate()
223 return (unsigned int)m_types.size();
226 //! Generates a single polymer
227 virtual void generateParticles(GeneratedParticles& particles, boost::mt19937& rnd, unsigned int start_idx);
229 private:
230 boost::shared_ptr<const ExecutionConfiguration> m_exec_conf; //!< Execution configuration for messaging
231 Scalar m_bond_len; //!< Bond length
232 std::vector<std::string> m_types; //!< Particle types for each polymer bead
233 std::vector<unsigned int> m_bond_a; //!< First particle in the bond pair
234 std::vector<unsigned int> m_bond_b; //!< Second particle in the bond pair
235 std::vector<string> m_bond_type; //!< Type name of the bond
236 unsigned int m_max_attempts; //!< Number of attemps to make for each particle placement
237 unsigned int m_dimensions; //!< Number of dimensions
239 //! helper function to place particles recursively
240 bool generateNextParticle(GeneratedParticles& particles, boost::mt19937& rnd, unsigned int i, unsigned int start_idx, const GeneratedParticles::particle& prev_particle);
245 //! Generates a random particle system given a set of ParticleGenerator classes
246 /*! \ingroup data_structs
247 RandomGenerator is the high level Initializer that brings all the pieces together to
248 generate a random system of particles. The structure and types of the particles generated
249 (i.e. a polymer system of A6B7A6 polymers) is determined by the ParticleGenerator classes
250 that are added.
252 Mixture systems can be created by adding more than one ParticleGenerator.
253 class. Testing should be done to confirm this, but it is probably best to
254 add the largest objects first so that smaller ones can be generated around them.
256 By default, bonds are named "bond". This can be changed by calling setBondType().
258 \b Usage:<br>
259 Before the initializer can be passed to a ParticleData for initialization, the following
260 steps must be performed.
261 -# Contstruct a RandomGenerator (duh) with a given box size
262 -# Set radii for all particle types to be generated
263 -# Construct and add any number of ParticleGenerator instances to the RandomGenerator
264 -# Call generate() to actually place the particles
266 class RandomGenerator
268 public:
269 //! Set the parameters
270 RandomGenerator(boost::shared_ptr<const ExecutionConfiguration> exec_conf,
271 const BoxDim& box,
272 unsigned int seed,
273 unsigned int dimensions);
275 //! Empty Destructor
276 virtual ~RandomGenerator() { }
278 //! initializes a snapshot with the particle data
279 virtual boost::shared_ptr<SnapshotSystemData> getSnapshot() const;
281 //! Sets the separation radius for a particle
282 void setSeparationRadius(string type, Scalar radius);
284 //! Adds a generator
285 void addGenerator(unsigned int repeat, boost::shared_ptr<ParticleGenerator> generator);
287 //! Place the particles
288 void generate();
290 private:
291 boost::shared_ptr<const ExecutionConfiguration> m_exec_conf; //!< The execution configuration
292 BoxDim m_box; //!< Precalculated box
293 unsigned int m_seed; //!< Random seed to use
294 GeneratedParticles m_data; //!< Actual particle data genreated
295 std::map< std::string, Scalar > m_radii; //!< Separation radii accessed by particle type
296 std::vector< boost::shared_ptr<ParticleGenerator> > m_generators; //!< Generators to place particles
297 std::vector< unsigned int > m_generator_repeat; //!< Repeat count for each generator
298 std::vector<std::string> m_type_mapping; //!< The created mapping between particle types and ids
299 std::vector<std::string> m_bond_type_mapping; //!< The created mapping between bond types and ids
300 unsigned int m_dimensions; //!< Number of dimensions
302 //! Helper function for identifying the particle type id
303 unsigned int getTypeId(const std::string& name);
304 //! Helper function for identifying the bond type id
305 unsigned int getBondTypeId(const std::string& name);
308 //! Exports RandomGenerator and related classes to python
309 void export_RandomGenerator();
311 #endif