public override void CalculateEnergyTerms(ParticleEnsemble ensemble) { ParticleStaticObjects.AtomPropertiesDefinition.CalculateEnergyTerms(); /* for (int i = 0; i < ensemble.MaxNumberOfParticles; ++i) { for (int j = (i + 1); j < ensemble.MaxNumberOfParticles; ++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]; } } */ }
// constructor public SoftSpheres(ParticleEnsemble pParticleSet) { //epsilon=10.0; // allocate vectors holding positions & forces LJxforces = new double[pParticleSet.MaxNumberOfParticles]; LJyforces = new double[pParticleSet.MaxNumberOfParticles]; // allocate vector holding cutoff distance for calculating Wall-Particle interactions WallDistance = new double[pParticleSet.MaxNumberOfParticles]; // allocate vector holding cutoff distance for calculating particle-particle interaction //Mat_DP tmp(0.0,pParticleSet->MaxNumberOfParticles,pParticleSet->MaxNumberOfParticles); //MinimumDistance = new DPMatrix(0, pParticleSet.MaxNumberOfParticles,pParticleSet.MaxNumberOfParticles); // allocate vectors holding particle-particle LJ energy terms //LJenergyTermA = new DPMatrix(0, pParticleSet.MaxNumberOfParticles,pParticleSet.MaxNumberOfParticles); // =tmp; //LJenergyTermB = new DPMatrix(0, pParticleSet.MaxNumberOfParticles, pParticleSet.MaxNumberOfParticles); // =tmp; //LJgradientTermA = new DPMatrix(0, pParticleSet.MaxNumberOfParticles, pParticleSet.MaxNumberOfParticles); // =tmp; //LJgradientTermB = new DPMatrix(0, pParticleSet.MaxNumberOfParticles, pParticleSet.MaxNumberOfParticles); // =tmp; CalculateEnergyTerms(pParticleSet); // calculate initial forcefield CalculateForceField(pParticleSet); }
public ExternalField(ParticleEnsemble ensemble) { GrabberCalls = 0; CalibrationCalls = 1; consecutiveZeroThreshold = 3; BoxWidth = ensemble.BoxWidth; BoxHeight = ensemble.BoxHeight; Calibrating = false; // initialize background pixels BackgroundPixels = new double[BoxHeight * BoxWidth]; // initialize the calibration count vector calibrationCountVector = new double[BoxHeight * BoxWidth]; // initialize timeTpixels timeTpixels = new double[BoxHeight * BoxWidth]; // initialize consecutiveZerosCount consecutiveZerosCount = new double[BoxHeight * BoxWidth]; // allocate vectors holding positions & forces xforces = new double[ensemble.MaxNumberOfParticles]; yforces = new double[ensemble.MaxNumberOfParticles]; // set up the gaussian array with the desired smoothing width parameter sigma = 10; nGaussPoints = 2 * (3 * sigma) + 1; RangeEitherSide = 3 * sigma; gaussian = new double[nGaussPoints]; double point = -1.0 * (3.0 * (double)sigma); for (int i = 0; i < nGaussPoints; ++i) { #if !UsePOW gaussian[i] = Math.Exp(-0.5 * (Math.Pow(point / (double)sigma, 2.0))) / ((double)sigma * Math.Sqrt(2.0 * Math.PI)); #else gaussian[i] = Math.Exp(-0.5 * (MathHelper.Pow2(point / (double)sigma))) / ((double)sigma * Math.Sqrt(2.0 * Math.PI)); #endif // cout << point << " " << gaussian[i] << endl; ++point; } }
public override void UpdateEnergyTerms(ParticleEnsemble ensemble) { throw new NotImplementedException(); }
/// <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 BoxWidth = ensemble.BoxWidth; int BoxHeight = ensemble.BoxHeight; // #pragma omp parallel for for (i = 0; i < ensemble.NumberOfParticles; ++i) { // initialize vectors holding forces xforces[i] = 0.0; // HERE'S THE PROBLEM - THE INDEX WILL OVERRUN THE VECTOR SIZE!!! yforces[i] = 0.0; } //#pragma omp parallel for for (i = 0; i < ensemble.NumberOfParticles; ++i) { posXi = ensemble.GetXParticlePosition(i); posYi = ensemble.GetYParticlePosition(i); 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; //List<double> SubsetOfPixelsAlongX = GetSubsetOfPixelsAlongX(posYi, posXi, RangeEitherSide + 1); GetSubsetOfPixelsAlongX(posXi, posYi, 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;} //xforces[i] = ensemble.GetGradientScaleFactor() * GaussianSmoothedSlope(posXi, SubsetOfPixelsAlongX); xforces[i] = ensemble.GradientScaleFactor * 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); //List<double> SubsetOfPixelsAlongY = GetSubsetOfPixelsAlongY(posXi, posYi, RangeEitherSide + 1); GetSubsetOfPixelsAlongY(posXi, posYi, RangeEitherSide + 1, ref m_CalculateForceField_TempArray, out count); // cout << "Yposition " << endl; //yforces[i] = ensemble.GetGradientScaleFactor() * GaussianSmoothedSlope(posYi, SubsetOfPixelsAlongY); yforces[i] = ensemble.GradientScaleFactor * 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 AtomicInfo typeInfo = ParticleStaticObjects.AtomPropertiesDefinition.Lookup[(ensemble.Particles[i]).TypeID]; double attractiveOrRepulsiveFactor = typeInfo.AttractiveOrRepulsive; xforces[i] *= attractiveOrRepulsiveFactor; yforces[i] *= attractiveOrRepulsiveFactor; } ensemble.AddXForces(xforces); // set the forces in the Particle Ensemble Object ensemble.AddYForces(yforces); // set the potential energy ensemble.AddPotentialEnergy(PotentialEnergy); // add in the potential energy }
public void ResizeForceArrays(ParticleEnsemble ensemble) { // clear out the forces vectors //xforces.Clear(); //yforces.Clear(); // allocate vectors holding positions & forces xforces = new double[ensemble.NumberOfParticles]; yforces = new double[ensemble.NumberOfParticles]; }
public static void LoadConfig(string filename) { #region Load the actual config if (File.Exists(filename)) { RC.WriteLine(ConsoleThemeColor.TitleText1, "Loading config '" + filename + "'"); XmlDocument doc = new XmlDocument(); doc.Load(filename); m_Options.Load(doc.DocumentElement); } #endregion #region Setup The Field Image m_CompositeFieldImage.Bounds = m_Options.Kinect.Bounds; int i = 0; foreach (DS.Simulation.CompositeFieldImage.KinectFieldImage field in m_CompositeFieldImage.Images) { field.X = m_Options.Kinect.Cameras[i].X; field.Y = m_Options.Kinect.Cameras[i++].Y; } #endregion #region Setup The Particle Simulation double gradScaleFactor = 1000.0; double MinRad = 10.0; double MaxRad = 30.0; List<string> FFtype = new List<string>(new string[] { "SoftSpheres", "ExternalField" }); ParticleStaticObjects.AtomPropertiesDefinition.Clear(); ParticleStaticObjects.AtomPropertiesDefinition.AddParticleDefinition("A", 1, new Color3(0.0390625f, 0.1953125f, 0.99609375f), 0, 20); // neon blue 0xc00A32FF ParticleStaticObjects.AtomPropertiesDefinition.AddParticleDefinition("B", 4, new Color3(1f, 0.03921569f, 0.1960784f), 1, 49); // red 0xc0FF0A32 ParticleStaticObjects.AtomPropertiesDefinition.AddParticleDefinition("C", 6, new Color3(0.1960784f, 0.03921569f, 1f), 2, 45); // purple 0xc0320AFF ParticleStaticObjects.AtomPropertiesDefinition.AddParticleDefinition("D", 9.2, new Color3(0.1490196f, 0.8470589f, 1f), 3, 43); // sky blue 0xc026D8FF // 0xc032FF0A, 3, 43); // green ParticleStaticObjects.AtomPropertiesDefinition.AddParticleDefinition("E", 12.6, new Color3(1f, 0.1960784f, 0.03921569f), 4, 38); // orange 0xc0FF320A ParticleStaticObjects.ReSeedRandom(42); m_Ensemble = new ParticleEnsemble(1, MinRad, MaxRad, FFtype, ArtworkStaticObjects.CompositeFieldImage.Height, ArtworkStaticObjects.CompositeFieldImage.Width, gradScaleFactor); m_ExternalField = new ExternalField(m_Ensemble, ArtworkStaticObjects.CompositeFieldImage); for (int j = 0; j < ParticleStaticObjects.AtomPropertiesDefinition.Count; j++) { ParticleStaticObjects.AtomPropertiesDefinition.SetAttractiveOrRepulsive(j, Options.Simulation.ParticleTypes[j].AttractiveOrRepulsive); ParticleStaticObjects.AtomPropertiesDefinition.SetEnabled(j, Options.Simulation.ParticleTypes[j].IsEnabled); ParticleStaticObjects.AtomPropertiesDefinition.SetSound(j, Options.Simulation.ParticleTypes[j].IsSoundOn); } m_Ensemble.BerendsenThermostatCoupling = Options.Simulation.BerendsenThermostatCoupling; m_Ensemble.EquilibriumTemperature = Options.Simulation.EquilibriumTemperature; m_Ensemble.GradientScaleFactor = Options.Simulation.GradientScaleFactor; int newNumber = Options.Simulation.NumberOfParticles; while (ArtworkStaticObjects.Ensemble.NumberOfParticles < newNumber) { ArtworkStaticObjects.Ensemble.InitializeOneNewParticle(); } while (ArtworkStaticObjects.Ensemble.NumberOfParticles > newNumber) { ArtworkStaticObjects.Ensemble.Particles.Pop(); } m_Ensemble.ParticleScale = Options.Simulation.ParticleScale; m_Ensemble.PotentialEnergy = Options.Simulation.PotentialEnergy; //ParticleStaticObjects.AtomPropertiesDefinition.ToggleAttractiveOrRepulsive(0); #endregion }
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 BoxWidth = ensemble.BoxWidth; int BoxHeight = ensemble.BoxHeight; double MaxForce = ensemble.MaxForceThreshold; double MinForce = -1.0 * (ensemble.MaxForceThreshold); // initialize vectors holding forces for (int i = 0; i < ensemble.NumberOfParticles; ++i) { LJxforces[i]=0.0; LJyforces[i]=0.0; } ensemble.ResetAllParticlesNotWithinRange(); for (int i = 0; i < ensemble.NumberOfParticles; ++i) { Particle particlei = ensemble.GetParticle(i); for (j = (i + 1); j < ensemble.NumberOfParticles; ++j) { Particle particlej = ensemble.GetParticle(j); if (particlei.GridSector.IsInJoiningSectors(particlej.GridSector) == false) { continue; } // get the interparticle separation distances ijSeparation = ensemble.GetInterParticleSeparation(i, j); // update the radial distribution function // pParticleSet->UpdateRadialDistributionFunction((int)(ijSeparation)); double cutoffDistance = particlei.ParticleType.MinimumDistance[particlej.TypeID]; // MinimumDistance[i, j]; //double cutoffDistance = MinimumDistance[i, j]; if (ijSeparation < cutoffDistance) { // SQRT MOD ijSeparation = Math.Sqrt(ijSeparation); double LJgradientTermA = particlei.ParticleType.LJgradientTermA[particlej.TypeID]; double LJgradientTermB = particlei.ParticleType.LJgradientTermB[particlej.TypeID]; // 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; LJforce = (posXj - posXi) * (LJgradientTermA / Math.Pow(ijSeparation, 13.0) + LJgradientTermB / 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; LJforce = (posYj - posYi) * (LJgradientTermA / Math.Pow(ijSeparation, 13.0) + LJgradientTermB / 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); } } } // set the forces in the Particle Ensemble Object ensemble.AddXForces(LJxforces); ensemble.AddYForces(LJyforces); // set the potential energy ensemble.AddPotentialEnergy(PotentialEnergy); }