/// Sets the temperature of system. /// /// Selects atom velocities randomly from a boltzmann (equilibrium) /// distribution that corresponds to the specified temperature. This /// random process will typically result in a small, but non zero center /// of mass velocity and a small difference from the specified /// temperature. For typical MD runs these small differences are /// unimportant, However, to avoid possible confusion, we set the center /// of mass velocity to zero and scale the velocities to exactly match /// the input temperature. void setTemperature(SimFlat* s, real_t temperature) { // set initial velocities for the distribution printf("CnC: Inside setTemperature %f, %d\n",temperature, s->boxes->nLocalBoxes); for (int iBox=0; iBox<s->boxes->nLocalBoxes; ++iBox) { for (int iOff=MAXATOMS*iBox, ii=0; ii<s->boxes->nAtoms[iBox]; ++ii, ++iOff) { int iType = s->atoms->iSpecies[iOff]; real_t mass = s->species[iType].mass; real_t sigma = sqrt(kB_eV * temperature/mass); uint64_t seed = mkSeed(s->atoms->gid[iOff], 123); #ifndef CNCOCR_TG // Manu: gasdev not working with TG s->atoms->p[iOff][0] = mass * sigma * gasdev(&seed); s->atoms->p[iOff][1] = mass * sigma * gasdev(&seed); s->atoms->p[iOff][2] = mass * sigma * gasdev(&seed); #else s->atoms->p[iOff][0] = mass * sigma; s->atoms->p[iOff][1] = mass * sigma; s->atoms->p[iOff][2] = mass * sigma; #endif } } // compute the resulting temperature // kinetic energy = 3/2 kB * Temperature if (temperature == 0.0) return; real_t vZero[3] = {0., 0., 0.}; setVcm(s, vZero); kineticEnergy(s); real_t temp = (s->eKinetic/s->atoms->nGlobal)/kB_eV/1.5; // scale the velocities to achieve the target temperature real_t scaleFactor = sqrt(temperature/temp); // real_t scaleFactor =1; for (int iBox=0; iBox<s->boxes->nLocalBoxes; ++iBox) { for (int iOff=MAXATOMS*iBox, ii=0; ii<s->boxes->nAtoms[iBox]; ++ii, ++iOff) { s->atoms->p[iOff][0] *= scaleFactor; s->atoms->p[iOff][1] *= scaleFactor; s->atoms->p[iOff][2] *= scaleFactor; } } kineticEnergy(s); temp = s->eKinetic/s->atoms->nGlobal/kB_eV/1.5; }
/// Add a random displacement to the atom positions. /// Atoms are displaced by a random distance in the range /// [-delta, +delta] along each axis. /// \param [in] delta The maximum displacement (along each axis). void randomDisplacements(SimFlat* s, real_t delta) { for (int iBox=0; iBox<s->boxes->nLocalBoxes; ++iBox) { for (int iOff=MAXATOMS*iBox, ii=0; ii<s->boxes->nAtoms[iBox]; ++ii, ++iOff) { uint64_t seed = mkSeed(s->atoms->gid[iOff], 457); s->atoms->r[iOff][0] += (2.0*lcg61(&seed)-1.0) * delta; s->atoms->r[iOff][1] += (2.0*lcg61(&seed)-1.0) * delta; s->atoms->r[iOff][2] += (2.0*lcg61(&seed)-1.0) * delta; } } }