Path Integral Quantum Monte Carlo
Public Member Functions
GrapheneLUT3DPotential Class Reference

Returns van der Waals' potential between a helium adatom and a graphene sheet using summation in reciprocal space. More...

#include <potential.h>

+ Inheritance diagram for GrapheneLUT3DPotential:
+ Collaboration diagram for GrapheneLUT3DPotential:

Public Member Functions

 GrapheneLUT3DPotential (const string, const Container *)
 Constructor.
 
 ~GrapheneLUT3DPotential ()
 Destructor.
 
double V (const dVec &)
 Return the value of the van der Waals' interaction between a graphene sheet and a helium adatom at a position, r, above the sheet. More...
 
dVec gradV (const dVec &)
 Return the gradient of the van der Waals' interaction between a graphene sheet and a helium adatom at a position, r, above the sheet. More...
 
double grad2V (const dVec &)
 Return the gradient of the van der Waals' interaction between a graphene sheet and a helium adatom at a position, r, above the sheet. More...
 
Array< dVec, 1 > initialConfig (const Container *, MTRand &, const int)
 Initial configuration corresponding to graphene-helium vdW potential. More...
 
Array< dVec, 1 > initialConfig1 (const Container *, MTRand &, const int)
 Return an initial particle configuration. More...
 
void put_in_uc (dVec &, double, double)
 
void cartesian_to_uc (dVec &, double, double, double, double)
 
double trilinear_interpolation (Array< double, 3 >, dVec, double, double, double)
 
double direct_lookup (Array< double, 3 >, dVec, double, double, double)
 
- Public Member Functions inherited from PotentialBase
 PotentialBase ()
 Constructor.
 
virtual ~PotentialBase ()
 Destructor.
 
virtual double V (const dVec &, const dVec &)
 The effective potential for the pair product approximation.
 
virtual double dVdlambda (const dVec &, const dVec &)
 The derivative of the effective potential with respect to lambda and tau.
 
virtual double dVdtau (const dVec &, const dVec &)
 
void output (const double)
 A debug method that output's the potential to a supplied separation. More...
 
virtual Array< double, 1 > getExcLen ()
 Array to hold data elements. More...
 

Additional Inherited Members

- Data Fields inherited from PotentialBase
double tailV
 Tail correction factor.
 
- Protected Member Functions inherited from PotentialBase
double deltaSeparation (double sep1, double sep2) const
 Return the minimum image difference for 1D separations.
 

Detailed Description

Returns van der Waals' potential between a helium adatom and a graphene sheet using summation in reciprocal space.

Author: Nathan Nichols Returns the potential energy resulting from a van der Waals' interaction between a helium adatom and a fixed infinite graphene lattice

Definition at line 1296 of file potential.h.

Member Function Documentation

◆ grad2V()

double GrapheneLUT3DPotential::grad2V ( const dVec r)
virtual

Return the gradient of the van der Waals' interaction between a graphene sheet and a helium adatom at a position, r, above the sheet.

Parameters
rthe position of a helium particle
Returns
the gradient of the van der Waals' potential for graphene-helium

Reimplemented from PotentialBase.

Definition at line 3120 of file potential.cpp.

3120  {
3121  double _grad2V = 0.0;
3122  if (r[2] + Lzo2 < zmin){
3123  return 0.0;
3124  }
3125  dVec _r = r;
3126  _r[2] += Lzo2 - zmin;
3127 
3128  cartesian_to_uc(_r, A11, A12, A21, A22);
3129  put_in_uc(_r, cell_length_a, cell_length_b);
3130  _grad2V = trilinear_interpolation(grad2V3d, _r, dx, dy, dz);
3131  //_grad2V = direct_lookup(grad2V3d, _r, dx, dy, dz);
3132  return _grad2V;
3133 }
TinyVector< double, NDIM > dVec
A NDIM-vector of type double.
Definition: common.h:111

◆ gradV()

dVec GrapheneLUT3DPotential::gradV ( const dVec r)
virtual

Return the gradient of the van der Waals' interaction between a graphene sheet and a helium adatom at a position, r, above the sheet.

Parameters
rthe position of a helium particle
Returns
the gradient of the van der Waals' potential for graphene-helium

Reimplemented from PotentialBase.

Definition at line 3091 of file potential.cpp.

3091  {
3092  dVec _gradV = 0.0;
3093  if (r[2] + Lzo2 < zmin){
3094  return _gradV;
3095  }
3096  dVec _r = r;
3097  _r[2] += Lzo2 - zmin;
3098 
3099  cartesian_to_uc(_r, A11, A12, A21, A22);
3100  put_in_uc(_r, cell_length_a, cell_length_b);
3101  double _gradV_x = trilinear_interpolation(gradV3d_x, _r, dx, dy, dz);
3102  double _gradV_y = trilinear_interpolation(gradV3d_y, _r, dx, dy, dz);
3103  double _gradV_z = trilinear_interpolation(gradV3d_z, _r, dx, dy, dz);
3104  //double _gradV_x = direct_lookup(gradV3d_x, _r, dx, dy, dz);
3105  //double _gradV_y = direct_lookup(gradV3d_y, _r, dx, dy, dz);
3106  //double _gradV_z = direct_lookup(gradV3d_z, _r, dx, dy, dz);
3107  _gradV(0) = _gradV_x;
3108  _gradV(1) = _gradV_y;
3109  _gradV(2) = _gradV_z;
3110  return _gradV;
3111 }

◆ initialConfig()

Array< dVec, 1 > GrapheneLUT3DPotential::initialConfig ( const Container boxPtr,
MTRand &  random,
const int  numParticles 
)
virtual

Initial configuration corresponding to graphene-helium vdW potential.

Return an initial particle configuration.

We create particles at random locations above the graphene sheet.

Reimplemented from PotentialBase.

Definition at line 3222 of file potential.cpp.

3223  {
3224 
3225  /* The particle configuration */
3226  Array<dVec,1> initialPos(numParticles);
3227  initialPos = 0.0;
3228 
3229  dVec side_;
3230  side_ = boxPtr->side;
3231 
3232  /* The first particle is randomly placed inside the box */
3233  for (int i = 0; i < NDIM-1; i++)
3234  initialPos(0)[i] = side_[i]*(-0.5 + random.rand());
3235  initialPos(0)[NDIM-1] = -0.5*side_[NDIM-1]+zmin + (zWall-zmin)*random.rand();
3236 
3237  double hardCoreRadius = 1.00;
3238 
3239  /* We keep trying to insert particles with no overlap */
3240  int numInserted = 1;
3241  int numAttempts = 0;
3242  int maxNumAttempts = ipow(10,6);
3243  dVec trialPos,sep;
3244  double rsep;
3245  while ((numInserted < numParticles) && (numAttempts < maxNumAttempts)) {
3246  numAttempts += 1;
3247 
3248  /* Generate a random position inside the box */
3249  for (int i = 0; i < NDIM-1; i++)
3250  trialPos[i] = side_[i]*(-0.5 + random.rand());
3251  trialPos[NDIM-1] = -0.5*side_[NDIM-1]+zmin + (zWall-zmin)*random.rand();
3252 
3253  /* Make sure it doesn't overlap with any existing particles. If not,
3254  * add it, otherwise, break */
3255  bool acceptParticle = true;
3256  for (int n = 0; n < numInserted; n++) {
3257  sep = trialPos - initialPos(n);
3258  boxPtr->putInBC(sep);
3259  rsep = sqrt(dot(sep,sep));
3260  if (rsep < 2*hardCoreRadius) {
3261  acceptParticle = false;
3262  break;
3263  }
3264  }
3265 
3266  if (acceptParticle) {
3267  initialPos(numInserted) = trialPos;
3268  numInserted += 1;
3269  }
3270 
3271  }
3272 
3273  if (numAttempts == maxNumAttempts) {
3274  cerr << "Could not construct a valid initial configuration." << endl;
3275  exit(EXIT_FAILURE);
3276  }
3277 
3278  /* Output configuration to terminal suitable for plotting with python */
3279  /* cout << "np.array(["; */
3280  /* for (int n = 0; n < numParticles; n++) { */
3281  /* cout << "["; */
3282  /* for (int i = 0; i < NDIM-1; i++) */
3283  /* cout << initialPos(n)[i] << ", "; */
3284  /* cout << initialPos(n)[NDIM-1] << "]," << endl; */
3285  /* } */
3286  /* cout << "])" << endl; */
3287  /* exit(EXIT_FAILURE); */
3288 
3289  return initialPos;
3290 }
void putInBC(dVec &r) const
Place a vector in boundary conditions.
Definition: container.h:50
dVec side
The linear dimensions of the box.
Definition: container.h:31
#define NDIM
Number of spatial dimnsions.
Definition: common.h:71
int ipow(int base, int power)
Return the integer value of a number raised to a power.
Definition: common.h:136
+ Here is the call graph for this function:

◆ initialConfig1()

Array< dVec, 1 > GrapheneLUT3DPotential::initialConfig1 ( const Container boxPtr,
MTRand &  random,
const int  numParticles 
)

Return an initial particle configuration.

We create particles at random locations above the graphene sheet.

Definition at line 3140 of file potential.cpp.

3141  {
3142  //FIXME We initialize on grid here above zmin, should I do C_1/3 here. I think not because might
3143  // be hard to get out of if other configurations are more favorable
3144 
3145  /* The particle configuration */
3146  Array<dVec,1> initialPos(numParticles);
3147  initialPos = 0.0;
3148 
3149  /* Get the average inter-particle separation in the accessible volume. */
3150  double initSide = pow((1.0*numParticles/boxPtr->volume),-1.0/(1.0*NDIM));
3151 
3152  /* We determine the number of initial grid boxes there are in
3153  * in each dimension and compute their size */
3154  int totNumGridBoxes = 1;
3155  iVec numNNGrid;
3156  dVec sizeNNGrid;
3157 
3158  for (int i = 0; i < NDIM; i++) {
3159  numNNGrid[i] = static_cast<int>(ceil((boxPtr->side[i] / initSide) - EPS));
3160 
3161  /* Make sure we have at least one grid box */
3162  if (numNNGrid[i] < 1)
3163  numNNGrid[i] = 1;
3164 
3165  /* Compute the actual size of the grid */
3166  sizeNNGrid[i] = boxPtr->side[i] / (1.0 * numNNGrid[i]);
3167 
3168  /* Modify due to the graphene and hard wall */
3169  if (i == NDIM - 1) {
3170  sizeNNGrid[i] = (zWall - zmin) / (1.0 * numNNGrid[i]);
3171  }
3172 
3173  /* Determine the total number of grid boxes */
3174  totNumGridBoxes *= numNNGrid[i];
3175  }
3176 
3177  /* Now, we place the particles at the middle of each box */
3178  PIMC_ASSERT(totNumGridBoxes>=numParticles);
3179  dVec pos;
3180  for (int n = 0; n < totNumGridBoxes; n++) {
3181 
3182  iVec gridIndex;
3183  for (int i = 0; i < NDIM; i++) {
3184  int scale = 1;
3185  for (int j = i+1; j < NDIM; j++)
3186  scale *= numNNGrid[j];
3187  gridIndex[i] = (n/scale) % numNNGrid[i];
3188  }
3189 
3190  /* We treat the z-direction differently due to the graphene and wall */
3191  for (int i = 0; i < NDIM; i++)
3192  pos[i] = (gridIndex[i]+0.5)*sizeNNGrid[i] - 0.5*boxPtr->side[i];
3193  pos[NDIM-1] += zmin;
3194 
3195  boxPtr->putInside(pos);
3196 
3197  if (n < numParticles)
3198  initialPos(n) = pos;
3199  else
3200  break;
3201  }
3202 
3203  /* Output for plotting in python */
3204  /* cout << "np.array(["; */
3205  /* for (int n = 0; n < numParticles; n++) { */
3206  /* cout << "["; */
3207  /* for (int i = 0; i < NDIM-1; i++) */
3208  /* cout << initialPos(n)[i] << ", "; */
3209  /* cout << initialPos(n)[NDIM-1] << "]," << endl; */
3210  /* } */
3211  /* cout << "])" << endl; */
3212  /* exit(-1); */
3213 
3214  return initialPos;
3215 }
double volume
The volume of the container in A^3.
Definition: container.h:35
virtual void putInside(dVec &) const =0
Place a vector inside the simulation cell.
#define EPS
A small number.
Definition: common.h:94
#define PIMC_ASSERT(X)
Rename assert method.
Definition: common.h:64
TinyVector< int, NDIM > iVec
A NDIM-vector of type integer.
Definition: common.h:114
+ Here is the call graph for this function:

◆ V()

double GrapheneLUT3DPotential::V ( const dVec r)
virtual

Return the value of the van der Waals' interaction between a graphene sheet and a helium adatom at a position, r, above the sheet.

Parameters
rthe position of a helium particle
Returns
the van der Waals' potential for graphene-helium

Reimplemented from PotentialBase.

Definition at line 3062 of file potential.cpp.

3062  {
3063  double z = r[2]+Lzo2;
3064 
3065  /* Check for extremal values of z */
3066  if (z < zmin)
3067  return V_zmin;
3068 
3069  /* A sigmoid to represent the hard-wall */
3070  double VWall = V_zmin/(1.0+exp(-invWallWidth*(z-zWall)));
3071 
3072  dVec _r = r;
3073  _r[2] += Lzo2 - zmin;
3074 
3075  cartesian_to_uc(_r, A11, A12, A21, A22);
3076  put_in_uc(_r, cell_length_a, cell_length_b);
3077  double _V = trilinear_interpolation(V3d, _r, dx, dy, dz);
3078  //double _V = direct_lookup(V3d, _r, dx, dy, dz);
3079  //std::cout << _r << " " << _V << std::endl;
3080 
3081  return _V + VWall;
3082 }

The documentation for this class was generated from the following files: