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) { LJforces[i] = new DPVector(0, 0); } for (int i = 0; i < ensemble.GetNumberOfParticles(); ++i) { Particle particleI = ensemble.GetParticle(i); for (j = (i + 1); j < ensemble.GetNumberOfParticles(); ++j) { Particle particleJ = ensemble.GetParticle(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 = particleI.Position.X; //ensemble.GetXParticlePosition(i); posYi = particleI.Position.Y; //ensemble.GetYParticlePosition(i); posXj = particleJ.Position.X; //ensemble.GetXParticlePosition(j); posYj = particleJ.Position.Y; //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... DPVector newIForce = LJforces[i]; DPVector newJForce = LJforces[j]; newIForce.X += LJforce; newJForce.X += -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... newIForce.Y += LJforce; newJForce.Y += -1.0 * LJforce; ensemble.SetParticlesWithinRange(i, j); ensemble.SetParticlesWithinRange(j, i); LJforces[i] = newIForce; LJforces[j] = newJForce; // cout << i << " " << j << endl; } else{ ensemble.SetParticlesNotWithinRange(i, j); ensemble.SetParticlesNotWithinRange(j, i); } } } // set the forces in the Particle Ensemble Object ensemble.AddForces(LJforces); // set the potential energy ensemble.AddPotentialEnergy(PotentialEnergy); }
/// <summary> /// function to calculate Soft Spheres forcefield /// </summary> /// <param name="ensemble"></param> public override void CalculateForceField(ParticleEnsemble ensemble) { // variable declarations int i; double posXi, posYi, radius; double PotentialEnergy = 0.0; // variable initializations int BoxHeight = ensemble.GetBoxHeight(); int BoxWidth = ensemble.GetBoxWidth(); // #pragma omp parallel for for (i = 0; i < ensemble.GetNumberOfParticles(); ++i) { // initialize vectors holding forces forces[i] = new DPVector(0, 0); // HERE'S THE PROBLEM - THE INDEX WILL OVERRUN THE VECTOR SIZE!!! } //#pragma omp parallel for for (i = 0; i < ensemble.GetNumberOfParticles(); ++i) { Particle particle = ensemble.GetParticle(i); posXi = particle.Position.X; //ensemble.GetXParticlePosition(i); posYi = particle.Position.Y; //ensemble.GetYParticlePosition(i); radius = particle.Radius; //ensemble.GetParticleRadius(i); // get pixel vectors along the particle's X & Y axes for getting gradient of image field // there are 2 steps to this process: // (1) do some gaussian smoothing with a user defined width parameter (this determines how // many pixels we need // (2) determine the gradient from linear regression of the 3 surrounding points... // cout << "particle " << i << " Xpos " << posXi << " Ypos " << posYi << endl; // first get the vectors that we need - the length of the vectors depend on the width of the gaussian // if the pixels are near the edge, the pixels beyond them (which arent in the image) are simply returned as zeros // vector < double > AllThePixelsAlongX = pParticleSet->GetAllThePixelsAlongX(posYi,posXi,RangeEitherSide); // xforces[i] = pParticleSet->GetGradientScaleFactor()*GaussianSmoothedSlope(posXi,AllThePixelsAlongX); // cout << "Xposition " << posXi << endl; if (m_CalculateForceField_TempArray.Length < RangeEitherSide + 1) { m_CalculateForceField_TempArray = new double[RangeEitherSide + 1]; } int count; DPVector newForce = new DPVector(); GetSubsetOfPixelsAlongX(posYi, posXi, RangeEitherSide + 1, ref m_CalculateForceField_TempArray, out count); // for(int kk=0; kk<SubsetOfPixelsAlongX.size(); ++kk){ // cout << kk << " " << SubsetOfPixelsAlongX[kk] << endl; // } // cout << "Xposition " << posXi << endl; // for(int kk=1;kk<SubsetOfPixelsAlongX.size();++kk){cout << kk << " " << SubsetOfPixelsAlongX[kk] << endl;} newForce.X = ensemble.GetGradientScaleFactor() * GaussianSmoothedSlope(posXi, m_CalculateForceField_TempArray, count); // vector < double > AllThePixelsAlongY = pParticleSet->GetAllThePixelsAlongY(posXi,posYi,RangeEitherSide); // cout << "Yposition " << posYi << endl; // for(int kk=0;kk<AllThePixelsAlongY.size();++kk){cout << kk << " " << AllThePixelsAlongY[kk] << endl;} // yforces[i] = pParticleSet->GetGradientScaleFactor()*GaussianSmoothedSlope(posYi,AllThePixelsAlongY); GetSubsetOfPixelsAlongY(posXi, posYi, RangeEitherSide + 1, ref m_CalculateForceField_TempArray, out count); //List<double> SubsetOfPixelsAlongY = GetSubsetOfPixelsAlongY(posXi, posYi, RangeEitherSide + 1); // cout << "Yposition " << endl; newForce.Y = ensemble.GetGradientScaleFactor() * GaussianSmoothedSlope(posYi, m_CalculateForceField_TempArray, count); // cout << "yforces[i] " << i << " " << yforces[i] << endl; // get the gradient scale factor, depending on whether the particle is attractive or repulsive ParticleInfo typeInfo = ParticleStaticObjects.AtomPropertiesDefinition.Lookup[particle.TypeID]; double attractiveOrRepulsiveFactor = typeInfo.AttractiveOrRepulsive; newForce.X *= attractiveOrRepulsiveFactor; newForce.Y *= attractiveOrRepulsiveFactor; forces[i] = newForce; } ensemble.AddForces(forces); // set the forces in the Particle Ensemble Object ensemble.AddPotentialEnergy(PotentialEnergy); // add in the potential energy }