HG-MD
1
|
00001 #ifndef CHUTEBOTTOM_H 00002 #define CHUTEBOTTOM_H 00003 #include "Chute.h" 00004 00011 class ChuteBottom : public Chute { 00012 00013 public: 00015 ChuteBottom() {constructor();} 00016 00018 ChuteBottom(MD& other) : MD(other), Chute(other) {constructor();} 00019 ChuteBottom(HGRID_base& other) : MD(other), Chute(other) {constructor();} 00020 ChuteBottom(HGRID_3D& other) : MD(other), Chute(other) {constructor();} 00021 ChuteBottom(Chute& other) : MD(other), Chute(other) {constructor();} 00022 00024 void constructor(){ 00025 set_name("roughbottom"); 00026 set_options_fstat(0); //set to 0 for no data creation 00027 set_options_data(1); 00028 set_options_restart(1); 00029 set_thickness(2.4); 00030 set_periodicbottom(true); 00031 } 00032 00033 void make_rough_bottom(ParticleHandler& ChuteParticleHandler) 00034 { 00035 // set all parameters that should be different from the original chute 00036 set_ChuteAngle(0.0); 00037 set_InflowHeight(25.*get_InflowParticleRadius()); 00038 //~ set_InflowHeight(45.*get_InflowParticleRadius()); note: Changing the Inflow height was an attempt to make the bottom density homogeneous, but it did not have the desired effect 00039 set_RandomizedBottom(1); 00040 set_FixedParticleRadius(get_InflowParticleRadius()); 00041 00042 set_collision_time_and_restitution_coefficient(get_collision_time()*10.0, 0.2); 00043 set_mu(0); 00044 00045 set_dt(); 00046 set_dt(get_dt()*10.0); 00047 set_tmax(get_dt()*2e3); 00048 //set_number_of_saves(2); 00049 set_savecount(100); 00050 00051 //solve 00052 solve(); 00053 00054 //create_bottom 00055 Mdouble height = 0; 00056 for (vector<Particle*>::iterator it=get_ParticleHandler().begin(); it!=get_ParticleHandler().end(); it++) { 00057 height = max(height,(*it)->get_Position().Z); 00058 } 00059 00060 cout << "Thickness" << thickness << endl; 00062 //now cut a slice of width 2*MaxInflowParticleRadius 00063 for (vector<Particle*>::iterator it=get_ParticleHandler().begin(); it!=get_ParticleHandler().end();) { 00064 if ((*it)->get_Position().Z < height - (1.0+thickness)*MaxInflowParticleRadius || (*it)->get_Position().Z > height - MaxInflowParticleRadius) { 00065 //delete particles outside the given range 00066 //*it = get_ParticleHandler().back(); 00067 //get_ParticleHandler().removeLastParticle(); 00068 get_ParticleHandler().removeParticle((*it)->get_Index()); 00069 } else { 00070 //fix the remaining particles on the floor 00071 (*it)->get_Position().Z -= height - MaxInflowParticleRadius; 00072 (*it)->fixParticle(); 00073 it++; 00074 } 00075 } 00076 00077 //copy the rough bottom over 00078 ChuteParticleHandler.set_StorageCapacity(get_ParticleHandler().get_NumberOfParticles()); 00079 cout << "Chute bottom finished, consisting of " << get_ParticleHandler().get_NumberOfParticles() << " Particles" << endl; 00080 00081 ChuteParticleHandler = get_ParticleHandler(); 00082 } 00083 00084 void setup_particles_initial_conditions() { 00085 00086 00087 get_ParticleHandler().set_StorageCapacity((int)min(3.0*get_xmax()*get_ymax()*get_zmax()/cubic(2.0*get_InflowParticleRadius()),1e6)); 00088 00089 00090 create_bottom(); 00091 00092 if (periodicbottom) { 00093 Walls.resize(1); 00094 Walls.back().set(Vec3D(0.0, 0.0, -1.0), -get_zmin()+get_InflowParticleRadius()); 00095 WallsPeriodic.resize(2); 00096 WallsPeriodic[0].set(Vec3D( 1.0, 0.0, 0.0), get_xmin(), get_xmax()); 00097 WallsPeriodic[1].set(Vec3D( 0.0, 1.0, 0.0), get_ymin(), get_ymax()); 00098 } else { 00099 WallsPeriodic.resize(0); 00100 Walls.resize(5); 00101 Walls[0].set(Vec3D(0.0, 0.0, -1.0), -get_zmin()+get_InflowParticleRadius()); 00102 Walls[Walls.size()-4].set(Vec3D(-1.0, 0.0, 0.0), -get_xmin()); 00103 Walls[Walls.size()-3].set(Vec3D( 1.0, 0.0, 0.0), get_xmax()); 00104 Walls[Walls.size()-2].set(Vec3D( 0.0,-1.0, 0.0), -get_ymin()); 00105 Walls[Walls.size()-1].set(Vec3D( 0.0, 1.0, 0.0), get_ymax()); 00106 } 00107 00108 //add particles 00109 HGRID_actions_before_time_loop(); 00110 int failed = 0, max_failed = 500; 00111 //try max_failed times to find new insertable particle 00112 while (failed<=max_failed){ 00113 P0.set_Radius(FixedParticleRadius); 00114 P0.compute_particle_mass(Species); 00115 00116 P0.get_Position().X = random.get_RN(P0.get_Radius(), get_xmax()-P0.get_Radius()); 00117 P0.get_Position().Y = random.get_RN(P0.get_Radius(), get_ymax()-P0.get_Radius()); 00118 P0.get_Position().Z = random.get_RN(2*P0.get_Radius(), get_zmax()-P0.get_Radius()); 00119 P0.set_Velocity(Vec3D(0.0,0.0,0.0)); 00120 00121 if (IsInsertable(P0)) 00122 { 00123 failed = 0; 00125 /*if (Particles.capacity()==Particles.size()) 00126 { 00127 00128 cerr << "Error in creating bottom; exceeded capacity: " << Particles.size() << endl; exit(-1); 00129 }*/ 00130 //Particles.push_back (P0); 00131 //Undate the link list so this particle is back in the grid 00132 //grid->objectBucket[Particles[Particles.size()-1].bucket] = Particles.size()-1; 00133 //grid->objectBucket[Particles[Particles.size()-1].bucket] = &Particles[Particles.size()-1]; 00134 num_created++; 00135 } 00136 else failed++; 00137 } 00138 //set_Nmax(get_ParticleHandler().get_NumberOfParticles()); 00139 cout << "N=" << get_ParticleHandler().get_NumberOfParticles() << endl; 00140 00141 //fix hgrid (there is still an issue when particles are polydispersed) 00142 //assume 1-2 levels are optimal (which is the case for mono and bidispersed) and set the cell size to min and max 00143 // !this is not optimal for polydispersed 00144 Mdouble minCell = 2.*min(get_FixedParticleRadius(),get_MinInflowParticleRadius()); 00145 Mdouble maxCell = 2.*max(get_FixedParticleRadius(),get_MaxInflowParticleRadius()); 00146 if ((minCell==maxCell)|(minCell==0.)) set_HGRID_max_levels(1); 00147 else set_HGRID_max_levels(2); 00148 set_HGRID_cell_to_cell_ratio (1.0000000001*maxCell/minCell); 00149 //optimize number of buckets 00150 set_HGRID_num_buckets_to_power(get_ParticleHandler().get_NumberOfParticles()*1.5); 00151 //end: fix hgrid 00152 00153 //~ info(); 00154 } 00155 00156 void actions_before_time_step() { }; 00157 00158 Mdouble get_thickness(){return thickness;} 00159 void set_thickness(Mdouble new_){ 00160 if (new_>0.0) thickness=new_; 00161 else {cerr<<"Error: thickness " << new_ << " negative"<<endl; exit(-1);} 00162 } 00163 Mdouble get_periodicbottom(){return periodicbottom;} 00164 void set_periodicbottom(bool new_){periodicbottom=new_;} 00165 00166 private: 00167 Mdouble thickness; 00168 bool periodicbottom; 00169 }; 00170 #endif