-
Notifications
You must be signed in to change notification settings - Fork 3
2. I.c.1 Creating a cubic lattice
Here we demonstrate a cubic lattice of sites. A normal or Gaussian distribution is then used to assign energies randomly to each of the sites in the lattice. Thank fully the c++ library comes with a very nice random number generator. To create our lattice we will begin by creating an object called Lattice that is able to store the sites. Ok, I know it looks a bit overwhelming but really its function is quite simple. This class essentially given a three dimensional lattice point defined by x, y and z will simply return a unique identifier. It will also do the opposite, given the unique id it will turn the position on the lattice as a vector. The only other thing the class does is assign energies randomly to a lattice based on a Normal distribution.
#include <cassert>
#include <vector>
#include <random>
using namespace std;
class Lattice{
public:
Lattice() {};
~Lattice(){};
void setNormalDistribution(double mean, double std_deviation){
mean_ = mean;
std_deviation_ = std_deviation;
}
void setDimensions(int length, int width, int height) {
length_ = length;
width_ = width;
height_ = height;
energies_.resize(length*width*height);
}
void setRandomNumberGeneratorsForXPlane(){
assert(height_>0 && width_>0);
auto distribution_y_ = std::uniform_int_distribution<int>(0,width_-1);
auto distribution_z_ = std::uniform_int_distribution<int>(0,height_-1);
}
void setInterSiteDistance(double distance){
inter_site_distance_ = distance;
}
int getLength() { return length_; }
int getWidth() { return width_; }
int getHeight() { return height_; }
double getInterSiteDistance() { return inter_site_distance_;}
double getSiteEnergy(int index){
return energies_.at(index);
}
int getIndex(int x,int y, int z){
y = getYPeriodic_(y);
z = getZPeriodic_(z);
return (z*length_*width_)+(y*length_)+x;
}
int getIndex(vector<int> site_position){
return getIndex(site_position.at(0),
getYPeriodic_(site_position.at(1)),
getZPeriodic_(site_position.at(2)));
}
int getRandomSiteOnXPlane(int x_plane){
assert(x_plane>=0 && x_plane<length_);
int y_lattice_position = distribution_y_(generator_);
int z_lattice_position = distribution_z_(generator_);
return getIndex(x_plane,y_lattice_position,z_lattice_position);
}
vector<int> getPosition(int index){
int z = index / (length_*width_);
index -= (length_*width_*z);
int y = index / (length_);
int x = index % length_;
return vector<int>{x,y,z};
}
void assignEnergies(){
default_random_engine generator;
normal_distribution<double> distribution(mean_,std_deviation_);
for(size_t index = 0;index<energies_.size();++index){
energies_.at(index) = distribution(generator);
}
}
private:
int length_ = 0;
int width_ = 0;
int height_ = 0;
double mean_ = 0.0;
double std_deviation_ = 0.0;
double inter_site_distance_ = 1.0; // nm nanometers
vector<double> energies_; // eV electron volts
uniform_int_distribution<int> distribution_y_;
uniform_int_distribution<int> distribution_z_;
default_random_engine generator_;
int getZPeriodic_(int z){
if(z<0){
return z+(z/height_)*-1*height_+height_;
}
return z % height_;
}
int getYPeriodic_(int y){
if(y<0){
return y+width_+ (y/width_)*-1*width_;
}
return y % width_;
}
};