Example #1
0
		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];
				}
			}
			*/ 
		}
Example #2
0
		// 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);
  
		}
Example #3
0
		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;
			}
		}
Example #4
0
		public override void UpdateEnergyTerms(ParticleEnsemble ensemble)
		{
			throw new NotImplementedException();
		}
Example #5
0
		/// <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    

		}
Example #6
0
		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];
		}
Example #7
0
		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
		}
Example #8
0
		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);
		}