Skip to content

2. I.c.1 Creating a cubic lattice

Joshua S Brown edited this page Feb 6, 2019 · 1 revision

1. Creating a cubic lattice

CubicLattice

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_;
    }
};