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