public override void UpdateEnergyTerms(ParticleEnsemble ensemble) { for (int i = 0; i < ensemble.GetNumberOfParticles(); ++i) { for (int j = (i + 1); j < ensemble.GetNumberOfParticles(); ++j) { double MinDistance = 2.0 * (ensemble.GetParticleRadius(i) + ensemble.GetParticleRadius(j)); MinimumDistance[i, j] = MinDistance; MinimumDistance[j, i] = MinDistance; LJenergyTermA[i, j] = epsilon * Math.Pow(MinDistance, 12.0); LJenergyTermA[j, i] = LJenergyTermA[i, j]; LJenergyTermB[i, j] = -2.0 * epsilon * Math.Pow(MinDistance, 6.0); LJenergyTermB[j, i] = LJenergyTermB[i, j]; LJgradientTermA[i, j] = -12.0 * LJenergyTermA[i, j]; LJgradientTermA[j, i] = LJgradientTermA[i, j]; LJgradientTermB[i, j] = -6.0 * LJenergyTermB[i, j]; LJgradientTermB[j, i] = LJgradientTermB[i, j]; } } }
public override void CalculateForceField(ParticleEnsemble ensemble) { //variable declarations double posXi, posYi; double posXj, posYj; double LJxf, LJyf; double ijSeparation = 0.0, LJforce = 0.0, PotentialEnergy = 0.0; int j, kk, ctr, dimensions = 2; //variable initializations int BoxHeight = ensemble.GetBoxHeight(); int BoxWidth = ensemble.GetBoxWidth(); double MaxForce = ensemble.GetMaxForceThreshold(); double MinForce = -1.0 * (ensemble.GetMaxForceThreshold()); // initialize vectors holding forces for (int i = 0; i < ensemble.GetNumberOfParticles(); ++i) { LJxforces[i]=0.0; LJyforces[i]=0.0; } ensemble.ResetAllParticlesNotWithinRange(); for (int i = 0; i < ensemble.GetNumberOfParticles(); ++i) { for (j = (i + 1); j < ensemble.GetNumberOfParticles(); ++j) { // get the interparticle separation distances ijSeparation = ensemble.GetInterParticleSeparation(i, j); // update the radial distribution function // pParticleSet->UpdateRadialDistributionFunction((int)(ijSeparation)); double cutoffDistance = MinimumDistance[i, j]; if (ijSeparation < cutoffDistance) { // for each particle, change the appropriate element of the setWithinRangeOfAnotherParticle vector to true posXi = ensemble.GetXParticlePosition(i); posYi = ensemble.GetYParticlePosition(i); posXj = ensemble.GetXParticlePosition(j); posYj = ensemble.GetYParticlePosition(j); // PotentialEnergy += LJenergyTermA[i][j]/(pow(ijSeparation,12.0))+LJenergyTermB[i][j]/pow(ijSeparation,6.0)+epsilon; LJforce = (posXj - posXi) * (LJgradientTermA[i, j] / Math.Pow(ijSeparation, 13.0) + LJgradientTermB[i, j] / Math.Pow(ijSeparation, 7.0)) / ijSeparation; if (Math.Abs(LJforce) > MaxForce || Math.Abs(LJforce) < MinForce) { LJforce = 0.0; } // error check for real-time stability... else if(double.IsNaN(LJforce) || double.IsInfinity(LJforce)){LJforce = 0.0;} // error check for real-time stability... LJxforces[i] += LJforce; LJxforces[j] += -1.0*LJforce; // cout << "x "<< i << " " << j << " " << LJforce << endl; // cout << "i " << i << " LJxforces[i] " << LJxforces[i] << " j " << j << " LJxforces[j] " << LJxforces[j] << endl; // cout << "xi:=" << posXi << ";" << "xj:=" << posXj << ";" << "yi:=" << posYi << ";" << "yj:=" << posYj << ";" << LJxforces[i] << endl; LJforce = (posYj - posYi) * (LJgradientTermA[i, j] / Math.Pow(ijSeparation, 13.0) + LJgradientTermB[i, j] / Math.Pow(ijSeparation, 7.0)) / ijSeparation; if (Math.Abs(LJforce) > MaxForce || Math.Abs(LJforce) < MinForce) { LJforce = 0.0; } // error check for real-time stability... else if (double.IsNaN(LJforce) || double.IsInfinity(LJforce)) { LJforce = 0.0; } // error check for real-time stability... LJyforces[i] += LJforce; LJyforces[j] += -1.0*LJforce; ensemble.SetParticlesWithinRange(i, j); ensemble.SetParticlesWithinRange(j, i); // cout << i << " " << j << endl; } //else{ //ensemble.SetParticlesNotWithinRange(i, j); //ensemble.SetParticlesNotWithinRange(j, i); //} } } // set the forces in the Particle Ensemble Object ensemble.AddXForces(LJxforces); ensemble.AddYForces(LJyforces); // set the potential energy ensemble.AddPotentialEnergy(PotentialEnergy); }