/// 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; }
double totalEnergy(particle * particles, int n){ double out = 0; double kinetic = kineticEnergy(particles, n); double potential = potentialEnergy(particles, n); //printf("kinetic = %g, potential = %g\n", kinetic, potential); out += kineticEnergy(particles, n); out += potentialEnergy(particles, n); return out; }
void dumpStats() { PotentialEnergies pe = calcPotentialEnergies(); /* Output in electron volt */ pe.bond /= ELECTRON_VOLT; pe.angle /= ELECTRON_VOLT; pe.dihedral /= ELECTRON_VOLT; pe.stack /= ELECTRON_VOLT; pe.basePair /= ELECTRON_VOLT; pe.Coulomb /= ELECTRON_VOLT; pe.exclusion /= ELECTRON_VOLT; double K = kineticEnergy() / ELECTRON_VOLT; double T = getKineticTemperature(); double E = K + pe.bond + pe.angle + pe.dihedral + pe.stack + pe.basePair + pe.Coulomb + pe.exclusion; printf("Vb = %le, Va = %le, Vd = %le, Vs = %le, Vbp = %le, Vpp = %le, Ve = %le", pe.bond, pe.angle, pe.dihedral, pe.stack, pe.basePair, pe.Coulomb, pe.exclusion); /* Extra interactions */ ExtraIntNode *node = extraIntList; while (node != NULL) { double V = node->i.potential(node->i.data) / ELECTRON_VOLT; printf(", V%s = %le\n", node->i.symbol, V); E += V; node = node->next; } printf(", E = %le, K = %le, T = %lf\n", E, K, T); }
/// Advance the simulation time to t+dt using a leap frog method /// (equivalent to velocity verlet). /// /// Forces must be computed before calling the integrator the first time. /// /// - Advance velocities half time step using forces /// - Advance positions full time step using velocities /// - Update link cells and exchange remote particles /// - Compute forces /// - Update velocities half time step using forces /// /// This leaves positions, velocities, and forces at t+dt, with the /// forces ready to perform the half step velocity update at the top of /// the next call. /// /// After nSteps the kinetic energy is computed for diagnostic output. double timestep(SimFlat* s, int nSteps, real_t dt) { for (int ii=0; ii<nSteps; ++ii) { startTimer(velocityTimer); advanceVelocity(s, s->boxes->nLocalBoxes, 0.5*dt); stopTimer(velocityTimer); startTimer(positionTimer); advancePosition(s, s->boxes->nLocalBoxes, dt); stopTimer(positionTimer); startTimer(redistributeTimer); redistributeAtoms(s); stopTimer(redistributeTimer); startTimer(computeForceTimer); computeForce(s); stopTimer(computeForceTimer); startTimer(velocityTimer); advanceVelocity(s, s->boxes->nLocalBoxes, 0.5*dt); stopTimer(velocityTimer); } kineticEnergy(s); return s->ePotential; }
static double kineticEnergy_proxy(const ModelHandler & model, DataHandler & data, const VectorXd_fx & q, const VectorXd_fx & v, const bool update_kinematics = true) { return kineticEnergy(*model,*data,q,v,update_kinematics); }
//http://klas-physics.googlecode.com/svn/trunk/src/general/Integrator.cpp (reference) void CVX_Voxel::timeStep(float dt) { previousDt = dt; if (dt == 0.0f) return; if (dofIsAllSet(dofFixed)){ //if this voxel is fixed, no need to change its location haltMotion(); return; } //Translation Vec3D<> curForce = force(); linMom += curForce*dt; if (dofIsSet(dofFixed, X_TRANSLATE)){linMom.x=0;} if (dofIsSet(dofFixed, Y_TRANSLATE)){linMom.y=0;} if (dofIsSet(dofFixed, Z_TRANSLATE)){linMom.z=0;} Vec3D<double> translate(linMom*(dt*mat->_massInverse)); //movement of the voxel this timestep if (isFloorEnabled() && floorPenetration() > 0){ //we must catch a slowing voxel here since it all boils down to needing access to the dt of this timestep. vfloat work = curForce.x*translate.x + curForce.y*translate.y; //F dot disp if(kineticEnergy() + work < 0) setFloorStaticFriction(true); //this checks for a change of direction according to the work-energy principle if (isFloorStaticFriction()){ //if we're in a state of static friction, zero out all horizontal motion linMom.x = linMom.y = 0; translate.x = translate.y = 0; } } pos += translate; //Rotation Vec3D<> curMoment = moment(); angMom += curMoment*dt; if (dofIsSet(dofFixed, X_ROTATE)){angMom.x=0;} if (dofIsSet(dofFixed, Y_ROTATE)){angMom.y=0;} if (dofIsSet(dofFixed, Z_ROTATE)){angMom.z=0;} orient = CQuat<>(angularVelocity()*dt)*orient; //update the orientation // if(pSim->StatToCalc & CALCSTAT_KINE) KineticEnergy = 0.5*Mass*Vel.Length2() + 0.5*Inertia*AngVel.Length2(); //1/2 m v^2 // if(pSim->StatToCalc & CALCSTAT_PRESSURE) { //// vfloat VolumetricStrain = GetVoxelStrain(AXIS_X) + GetVoxelStrain(AXIS_Y) + GetVoxelStrain(AXIS_Z); // vfloat VolumetricStrain = strain(false).x+strain(false).y+strain(false).z; // Pressure = - _pMat->GetElasticMod()*VolumetricStrain/(3*(1-2*_pMat->GetPoissonsRatio())); //http://www.colorado.edu/engineering/CAS/courses.d/Structures.d/IAST.Lect05.d/IAST.Lect05.pdf // } // // updatePoissonsstrain(); // // }
/// Initialized the main CoMD data stucture, SimFlat, based on command /// line input from the user. Also performs certain sanity checks on /// the input to screen out certain non-sensical inputs. /// /// Simple data members such as the time step dt are initialized /// directly, substructures such as the potential, the link cells, the /// atoms, etc., are initialized by calling additional initialization /// functions (initPotential(), initLinkCells(), initAtoms(), etc.). /// Initialization order is set by the natural dependencies of the /// substructure such as the atoms need the link cells so the link cells /// must be initialized before the atoms. SimFlat* initSimulation(Command cmd) { SimFlat* sim = comdMalloc(sizeof(SimFlat)); sim->nSteps = cmd.nSteps; sim->printRate = cmd.printRate; sim->dt = cmd.dt; sim->domain = NULL; sim->boxes = NULL; sim->atoms = NULL; sim->ePotential = 0.0; sim->eKinetic = 0.0; sim->atomExchange = NULL; sim->pot = initPotential(cmd.doeam, cmd.potDir, cmd.potName, cmd.potType); real_t latticeConstant = cmd.lat; if (cmd.lat < 0.0) latticeConstant = sim->pot->lat; // ensure input parameters make sense. sanityChecks(cmd, sim->pot->cutoff, latticeConstant, sim->pot->latticeType); sim->species = initSpecies(sim->pot); real3 globalExtent; globalExtent[0] = cmd.nx * latticeConstant; globalExtent[1] = cmd.ny * latticeConstant; globalExtent[2] = cmd.nz * latticeConstant; sim->domain = initDecomposition( cmd.xproc, cmd.yproc, cmd.zproc, globalExtent); sim->boxes = initLinkCells(sim->domain, sim->pot->cutoff); sim->atoms = initAtoms(sim->boxes); // create lattice with desired temperature and displacement. createFccLattice(cmd.nx, cmd.ny, cmd.nz, latticeConstant, sim); setTemperature(sim, cmd.temperature); randomDisplacements(sim, cmd.initialDelta); sim->atomExchange = initAtomHaloExchange(sim->domain, sim->boxes); // Forces must be computed before we call the time stepper. startTimer(redistributeTimer); redistributeAtoms(sim); stopTimer(redistributeTimer); startTimer(computeForceTimer); computeForce(sim); stopTimer(computeForceTimer); kineticEnergy(sim); return sim; }
void StatisticsSampler::saveToFile(System &system, ofstream &file) { // Convert all energy per atom, use eV file << setw(15) << UnitConverter::timeToSI(system.steps()) << " " << setw(15) << UnitConverter::timeToSI(system.time()) << " " << setw(15) << UnitConverter::temperatureToSI(temperature()) << " " << setw(15) << UnitConverter::energyToEv(kineticEnergy()/system.atoms().size()) << " " << setw(15) << UnitConverter::energyToEv(potentialEnergy()/system.atoms().size()) << " " << setw(15) << UnitConverter::energyToEv(totalEnergy()/system.atoms().size()) << " " << setw(15) << diffusionConstant() << " " << setw(15) << m_rSquared << std::endl; }
int testEnergy(){ int failed = 0; int n = 3; particle * particles = malloc(n * sizeof(particle)); initialize_linearx(particles, n); double kinetic = kineticEnergy(particles, n); if(kinetic != 0){ failed ++; printf("nonzero kinetic energy %lf found\n", kinetic); } double potential = potentialEnergy(particles, n); if(potential != -0.25){ failed ++; printf("unexpected potential energy %lf found. expected -0.25\n", potential); } //double distances, expect force ~2^-9 particles[0]. x = 0; particles[1].x = 2; particles[2].x = 4; potential = potentialEnergy(particles, n); if(potential != -0.00048828125){ failed ++; printf("unexpected potential energy %lf found. expected -0.00048828125\n", potential); } //equilateral triangle initialize_equilateral(particles, n); potential = potentialEnergy(particles, n); if(potential != 1.375){ failed ++; printf("unexpected potential energy %g found. expected 1.375\n", potential - 1.375); } free(particles); if(failed == 0){ printf("energy test passed\n"); } return !failed; }
double getKineticTemperature(void) { return 2.0 / (3.0 * BOLTZMANN_CONSTANT) * kineticEnergy() / numParticles(); }
SimFlat* initSimulation(Command cmd) { SimFlat* sim = comdMalloc(sizeof(SimFlat)); sim->nSteps = cmd.nSteps; sim->printRate = cmd.printRate; sim->dt = cmd.dt; sim->domain = NULL; sim->boxes = NULL; sim->atoms = NULL; sim->ePotential = 0.0; sim->eKinetic = 0.0; sim->atomExchange = NULL; sim->pot = initPotential(cmd.doeam, cmd.potDir, cmd.potName, cmd.potType); real_t latticeConstant = cmd.lat; if (cmd.lat < 0.0) latticeConstant = sim->pot->lat; // ensure input parameters make sense. sanityChecks(cmd, sim->pot->cutoff, latticeConstant, sim->pot->latticeType); sim->species = initSpecies(sim->pot); real3 globalExtent; globalExtent[0] = cmd.nx * latticeConstant; globalExtent[1] = cmd.ny * latticeConstant; globalExtent[2] = cmd.nz * latticeConstant; sim->domain = initDecomposition(cmd.xproc, cmd.yproc, cmd.zproc, globalExtent); sim->boxes = initLinkCells(sim->domain, sim->pot->cutoff); sim->atoms = initAtoms(sim->boxes); sim->defInfo = initDeformation(sim, cmd.defGrad); //printf("Got to here\n"); // create lattice with desired temperature and displacement. createFccLattice(cmd.nx, cmd.ny, cmd.nz, latticeConstant, sim); setTemperature(sim,0.0); randomDisplacements(sim, cmd.initialDelta); sim->atomExchange = initAtomHaloExchange(sim->domain, sim->boxes); forwardDeformation(sim); //eamForce(sim); // Procedure for energy density passing from the macrosolver to CoMD //setTemperature(sim,((cmd.energy*latticeVolume*cmd.nx*cmd.ny*cmd.nz-sim->ePotential)/sim->atoms->nGlobal)/(kB_eV * 1.5)); //randomDisplacements(sim, cmd.initialDelta); // Forces must be computed before we call the time stepper. startTimer(redistributeTimer); redistributeAtoms(sim); stopTimer(redistributeTimer); startTimer(computeForceTimer); computeForce(sim); stopTimer(computeForceTimer); double cohmmEnergy=cmd.energy*sim->defInfo->globalVolume; double temperatureFromEnergyDensity=((cohmmEnergy-sim->ePotential)/sim->atoms->nGlobal)/(kB_eV*1.5); setTemperature(sim,temperatureFromEnergyDensity); //uncomment to set temperature according to hmm energy density //setTemperature(sim,cmd.temperature); //uncomment to directly input temperature kineticEnergy(sim); return sim; }