1 // Voro++, a 3D cell-based Voronoi library
2 //
3 // Author   : Chris H. Rycroft (LBL / UC Berkeley)
4 // Email    : chr@alum.mit.edu
5 // Date     : August 30th 2011
6 
7 /** \file pre_container.hh
8  * \brief Header file for the pre_container and related classes. */
9 
10 #ifndef VOROPP_PRE_CONTAINER_HH
11 #define VOROPP_PRE_CONTAINER_HH
12 
13 #include <cstdio>
14 
15 #include "c_loops.hh"
16 #include "container.hh"
17 
18 namespace voro {
19 
20 /** \brief A class for storing an arbitrary number of particles, prior to setting
21  * up a container geometry.
22  *
23  * The pre_container_base class can dynamically import and store an arbitrary
24  * number of particles. Once the particles have been read in, an appropriate
25  * container class can be set up with the optimal grid size, and the particles
26  * can be transferred.
27  *
28  * The pre_container_base class is not intended for direct use, but forms the
29  * base of the pre_container and pre_container_poly classes, that add routines
30  * depending on whether particle radii need to be tracked or not. */
31 class pre_container_base {
32 	public:
33 		/** The minimum x coordinate of the container. */
34 		const double ax;
35 		/** The maximum x coordinate of the container. */
36 		const double bx;
37 		/** The minimum y coordinate of the container. */
38 		const double ay;
39 		/** The maximum y coordinate of the container. */
40 		const double by;
41 		/** The minimum z coordinate of the container. */
42 		const double az;
43 		/** The maximum z coordinate of the container. */
44 		const double bz;
45 		/** A boolean value that determines if the x coordinate in
46 		 * periodic or not. */
47 		const bool xperiodic;
48 		/** A boolean value that determines if the y coordinate in
49 		 * periodic or not. */
50 		const bool yperiodic;
51 		/** A boolean value that determines if the z coordinate in
52 		 * periodic or not. */
53 		const bool zperiodic;
54 		void guess_optimal(int &nx,int &ny,int &nz);
55 		pre_container_base(double ax_,double bx_,double ay_,double by_,double az_,double bz_,bool xperiodic_,bool yperiodic_,bool zperiodic_,int ps_);
56 		~pre_container_base();
57 		/** Calculates and returns the total number of particles stored
58 		 * within the class.
59 		 * \return The number of particles. */
total_particles()60 		inline int total_particles() {
61 			return (end_id-pre_id)*pre_container_chunk_size+(ch_id-*end_id);
62 		}
63 	protected:
64 		/** The number of doubles associated with a single particle
65 		 * (three for the standard container, four when radius
66 		 * information is stored). */
67 		const int ps;
68 		void new_chunk();
69 		void extend_chunk_index();
70 		/** The size of the chunk index. */
71 		int index_sz;
72 		/** A pointer to the chunk index to store the integer particle
73 		 * IDs. */
74 		int **pre_id;
75 		/** A pointer to the last allocated integer ID chunk. */
76 		int **end_id;
77 		/** A pointer to the end of the integer ID chunk index, used to
78 		 * determine when the chunk index is full. */
79 		int **l_id;
80 		/** A pointer to the next available slot on the current
81 		 * particle ID chunk. */
82 		int *ch_id;
83 		/** A pointer to the end of the current integer chunk. */
84 		int *e_id;
85 		/** A pointer to the chunk index to store the floating point
86 		 * information associated with particles. */
87 		double **pre_p;
88 		/** A pointer to the last allocated chunk of floating point
89 		 * information. */
90 		double **end_p;
91 		/** A pointer to the next available slot on the current
92 		 * floating point chunk. */
93 		double *ch_p;
94 };
95 
96 /** \brief A class for storing an arbitrary number of particles without radius
97  * information, prior to setting up a container geometry.
98  *
99  * The pre_container class is an extension of the pre_container_base class for
100  * cases when no particle radius information is available. */
101 class pre_container : public pre_container_base {
102 	public:
103 		/** The class constructor sets up the geometry of container,
104 		 * initializing the minimum and maximum coordinates in each
105 		 * direction.
106 		 * \param[in] (ax_,bx_) the minimum and maximum x coordinates.
107 		 * \param[in] (ay_,by_) the minimum and maximum y coordinates.
108 		 * \param[in] (az_,bz_) the minimum and maximum z coordinates.
109 		 * \param[in] (xperiodic_,yperiodic_,zperiodic_ ) flags setting whether the
110 		 *                                                container is periodic in
111 		 *                                                each coordinate direction. */
pre_container(double ax_,double bx_,double ay_,double by_,double az_,double bz_,bool xperiodic_,bool yperiodic_,bool zperiodic_)112 		pre_container(double ax_,double bx_,double ay_,double by_,double az_,double bz_,
113 				bool xperiodic_,bool yperiodic_,bool zperiodic_)
114 			: pre_container_base(ax_,bx_,ay_,by_,az_,bz_,xperiodic_,yperiodic_,zperiodic_,3) {};
115 		void put(int n,double x,double y,double z);
116 		void import(FILE *fp=stdin);
117 		/** Imports particles from a file.
118 		 * \param[in] filename the name of the file to read from. */
import(const char * filename)119 		inline void import(const char* filename) {
120 			FILE *fp=safe_fopen(filename,"r");
121 			import(fp);
122 			fclose(fp);
123 		}
124 		void setup(container &con);
125 		void setup(particle_order &vo,container &con);
126 };
127 
128 /** \brief A class for storing an arbitrary number of particles with radius
129  * information, prior to setting up a container geometry.
130  *
131  * The pre_container_poly class is an extension of the pre_container_base class
132  * for cases when particle radius information is available. */
133 class pre_container_poly : public pre_container_base {
134 	public:
135 		/** The class constructor sets up the geometry of container,
136 		 * initializing the minimum and maximum coordinates in each
137 		 * direction.
138 		 * \param[in] (ax_,bx_) the minimum and maximum x coordinates.
139 		 * \param[in] (ay_,by_) the minimum and maximum y coordinates.
140 		 * \param[in] (az_,bz_) the minimum and maximum z coordinates.
141 		 * \param[in] (xperiodic_,yperiodic_,zperiodic_ ) flags setting whether the
142 		 *                                                container is periodic in
143 		 *                                                each coordinate direction. */
pre_container_poly(double ax_,double bx_,double ay_,double by_,double az_,double bz_,bool xperiodic_,bool yperiodic_,bool zperiodic_)144 		pre_container_poly(double ax_,double bx_,double ay_,double by_,double az_,double bz_,
145 				bool xperiodic_,bool yperiodic_,bool zperiodic_)
146 			: pre_container_base(ax_,bx_,ay_,by_,az_,bz_,xperiodic_,yperiodic_,zperiodic_,4) {};
147 		void put(int n,double x,double y,double z,double r);
148 		void import(FILE *fp=stdin);
149 		/** Imports particles from a file.
150 		 * \param[in] filename the name of the file to read from. */
import(const char * filename)151 		inline void import(const char* filename) {
152 			FILE *fp=safe_fopen(filename,"r");
153 			import(fp);
154 			fclose(fp);
155 		}
156 		void setup(container_poly &con);
157 		void setup(particle_order &vo,container_poly &con);
158 };
159 
160 }
161 
162 #endif
163