Пример #1
0
		private void SetupForTesting(int Nparticles)
		{
			double gradScaleFactor = 3000.0;
			double MinRad = 40.0;
			double MaxRad = 50.0;

			List<string> FFtype = new List<string>(new string[] { "SoftSpheres", "ExternalField" }); 
			
			ParticleStaticObjects.AtomPropertiesDefinition.Clear(); 
			ParticleStaticObjects.AtomPropertiesDefinition.AddParticleDefinition("Hydrogen", 2, unchecked((int)0xc00A32FF), 0, 50); // neon blue
			ParticleStaticObjects.AtomPropertiesDefinition.AddParticleDefinition("Oxygen", 4, unchecked((int)0xc0FF0A32), 1, 49); // red
			ParticleStaticObjects.AtomPropertiesDefinition.AddParticleDefinition("Neon", 6, unchecked((int)0xc0320AFF), 2, 45); // purple
			ParticleStaticObjects.AtomPropertiesDefinition.AddParticleDefinition("Zinc", 9.2, unchecked((int)0xc026D8FF), 3, 43); // sky blue // 0xc032FF0A, 3,  43); // green 
			ParticleStaticObjects.AtomPropertiesDefinition.AddParticleDefinition("Iron", 12.6, unchecked((int)0xc0FF320A), 4, 38); // orange

			ParticleStaticObjects.ReSeedRandom(42); 

			Ensemble1 = new ParticleEnsemble(Nparticles, MinRad, MaxRad, FFtype, m_SizeY, m_SizeX, gradScaleFactor);
			Field = new ExternalField(Ensemble1);

			double[] background = new double[m_NumberOfPixels]; 

			for (int i = 0; i < m_NumberOfPixels; i++)
			{
				background[i] = 512; 
			}

			Field.IncrementGrabberCalls();                         // increment the number of grabber calls			
			Field.BackgroundCalibration(m_NumberOfPixels, background);  // in order to simply set the background to zero 
			Field.SetCalibrating(false);
		}
Пример #2
0
		public override void CalculateEnergyTerms(ParticleEnsemble ensemble)
		{
			ParticleStaticObjects.AtomPropertiesDefinition.CalculateEnergyTerms(); 

			/*for (int i = 0; i < ensemble.MaxNumberOfParticles; ++i)
			{
				double radiusi = ensemble.GetParticle(i).Radius; 

				for (int j = (i + 1); j < ensemble.MaxNumberOfParticles; ++j)
				{
					double radiusj = ensemble.GetParticle(j).Radius;

					double MinDist = 2.0 * (radiusi + radiusj);

					MinimumDistance[i, j] = MinDist * MinDist;
					MinimumDistance[j, i] = MinimumDistance[i, j];
					LJenergyTermA[i, j] = epsilon * Math.Pow(MinDist, 12.0);
					LJenergyTermA[j, i] = LJenergyTermA[i, j];
					LJenergyTermB[i, j] = -2.0 * epsilon * Math.Pow(MinDist, 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];
				}
			} */ 
		}
Пример #3
0
		public void ResizeForceArrays(ParticleEnsemble ensemble)
		{			
			DPVector zero = new DPVector(0, 0); 

			for (int i = 0; i < ensemble.NumberOfParticles; i++)
			{
				forces[i] = zero;				
			}
		}
Пример #4
0
		public ExternalField(ParticleEnsemble ensemble)
		{
			GrabberCalls = 0;
			CalibrationCalls = 1;
			consecutiveZeroThreshold = 3;
			BoxHeight = ensemble.BoxHeight;
			BoxWidth = ensemble.BoxWidth;
			Calibrating = false;

			// initialize background pixels
			BackgroundPixels = new List<double>(new double[BoxHeight * BoxWidth]);

			// initialize the calibration count vector
			calibrationCountVector = new List<double>(new double[BoxHeight * BoxWidth]);

			// initialize timeTpixels
			timeTpixels = new List<double>(new double[BoxHeight * BoxWidth]);

			// initialize consecutiveZerosCount
			consecutiveZerosCount = new List<double>(new double[BoxHeight * BoxWidth]);

			// allocate vectors holding positions & forces
			forces = new DPVector[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)
			{
				gaussian[i] = Math.Exp(-0.5 * (Math.Pow(point / (double)sigma, 2.0))) / ((double)sigma * Math.Sqrt(2.0 * Math.PI));				
				++point;
			}

		}
Пример #5
0
		public SoftSpheres(ParticleEnsemble pParticleSet)
		{  
			epsilon = 10.0;
	
			// allocate vectors holding positions & forces
			LJforces = new DPVector[pParticleSet.MaxNumberOfParticles];			
  
			// allocate vector holding cutoff distance for calculating Wall-Particle interactions
			WallDistance = new List<double>(new double[pParticleSet.MaxNumberOfParticles]);
  		
			// allocate vector holding cutoff distance for calculating particle-particle interaction
			//MinimumDistance = new DPMatrix(0, pParticleSet.MaxNumberOfParticles,pParticleSet.MaxNumberOfParticles);
	
			// allocate vectors holding particle-particle LJ energy terms
			//LJenergyTermA = new DPMatrix(0, pParticleSet.MaxNumberOfParticles,pParticleSet.MaxNumberOfParticles); 
			//LJenergyTermB = new DPMatrix(0, pParticleSet.MaxNumberOfParticles, pParticleSet.MaxNumberOfParticles);
			//LJgradientTermA = new DPMatrix(0, pParticleSet.MaxNumberOfParticles, pParticleSet.MaxNumberOfParticles);
			//LJgradientTermB = new DPMatrix(0, pParticleSet.MaxNumberOfParticles, pParticleSet.MaxNumberOfParticles);
  
			CalculateEnergyTerms(pParticleSet);
	
			// calculate initial forcefield
			CalculateForceField(pParticleSet);  
		}
Пример #6
0
		public override void CalculateForceField(ParticleEnsemble ensemble)
		{
			// variable declarations
			double posXi, posYi;
			double posXj, posYj;
			double ijSeparation = 0.0, LJforce = 0.0, PotentialEnergy = 0.0;
  
			// variable initializations
			int BoxHeight = ensemble.BoxHeight;
			int BoxWidth = ensemble.BoxWidth;
			double MaxForce = ensemble.MaxForceThreshold;
			double MinForce = -1.0 * (ensemble.MaxForceThreshold);

			DPVector zero = new DPVector(0, 0);

			// initialize vectors holding forces
			for (int i = 0; i < ensemble.NumberOfParticles; ++i)
			{
				LJforces[i] = zero;				
			}

			ensemble.ResetAllParticlesNotWithinRange(); 

			for (int i = 0; i < ensemble.NumberOfParticles; ++i)
			{
				Particle particlei = ensemble.GetParticle(i); 

				for (int j = (i + 1); j < ensemble.NumberOfParticles; ++j)
				{				
					Particle particlej = ensemble.GetParticle(j); 

					// get the interparticle separation distances
					ijSeparation = ensemble.GetInterParticleSeparation(i, j);

					double LJgradientTermA = particlei.ParticleType.LJgradientTermA[particlej.TypeID];
					double LJgradientTermB = particlei.ParticleType.LJgradientTermB[particlej.TypeID]; 
						
					// update the radial distribution function
					double cutoffDistance = particlei.ParticleType.MinimumDistance[particlej.TypeID]; // MinimumDistance[i, j];
			
					if (ijSeparation < cutoffDistance) 
					{						
						// for each particle, change the appropriate element of the setWithinRangeOfAnotherParticle vector to true
						posXi = particlei.Position.X; 
						posYi = particlei.Position.Y; 

						posXj = particlej.Position.X; 
						posYj = particlej.Position.Y; 
												
						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)
						{
							// error check for real-time stability...
							LJforce = 0.0; 
						}    
						else if(double.IsNaN(LJforce) || double.IsInfinity(LJforce))
						{
							// error check for real-time stability...
							LJforce = 0.0;
						}

						LJforces[i].X += LJforce;
						LJforces[j].X += -1.0 * LJforce;
						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) 
						{
							// error check for real-time stability...
							LJforce = 0.0; 
						}    
						else if (double.IsNaN(LJforce) || double.IsInfinity(LJforce)) 
						{
							// error check for real-time stability...
							LJforce = 0.0; 
						} 

						LJforces[i].Y += LJforce;
						LJforces[j].Y += -1.0 * LJforce;

						ensemble.SetParticlesWithinRange(i, j);
						ensemble.SetParticlesWithinRange(j, i);					
					}
					//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);
		}
Пример #7
0
		public abstract void CalculateForceField(ParticleEnsemble ensemble);
Пример #8
0
		public abstract void UpdateEnergyTerms(ParticleEnsemble ensemble);
Пример #9
0
		public abstract void CalculateEnergyTerms(ParticleEnsemble ensemble);
Пример #10
0
		public override void UpdateEnergyTerms(ParticleEnsemble ensemble)
		{
			throw new NotImplementedException();
		}
Пример #11
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 BoxHeight = ensemble.BoxHeight;
			int BoxWidth = ensemble.BoxWidth;

			DPVector zero = new DPVector(0, 0); 

			// #pragma omp parallel for
			for (i = 0; i < ensemble.NumberOfParticles; ++i)
			{
				// initialize vectors holding forces
				forces[i] = zero;																							
			}

			//#pragma omp parallel for
			for (i = 0; i < ensemble.NumberOfParticles; ++i)
			{
				Particle particlei = ensemble.GetParticle(i);

				posXi = particlei.Position.X; 
				posYi = particlei.Position.Y; 
				radius = particlei.Radius; 

				// 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

				if (m_CalculateForceField_TempArray.Length < RangeEitherSide + 1)
				{
					m_CalculateForceField_TempArray = new double[RangeEitherSide + 1]; 
				}

				int count; 

				GetSubsetOfPixelsAlongX(posYi, posXi, RangeEitherSide + 1, ref m_CalculateForceField_TempArray, out count);
				forces[i].X = ensemble.GradientScaleFactor * GaussianSmoothedSlope(posXi, m_CalculateForceField_TempArray, count);

				GetSubsetOfPixelsAlongY(posXi, posYi, RangeEitherSide + 1, ref m_CalculateForceField_TempArray, out count);
				forces[i].Y = ensemble.GradientScaleFactor * GaussianSmoothedSlope(posYi, m_CalculateForceField_TempArray, count);

				// get the gradient scale factor, depending on whether the particle is attractive or repulsive
				ParticleInfo typeInfo = ParticleStaticObjects.AtomPropertiesDefinition.Lookup[(ensemble.Particles[i]).TypeID];
				
				double attractiveOrRepulsiveFactor = typeInfo.AttractiveOrRepulsive;
				forces[i].X *= attractiveOrRepulsiveFactor;
				forces[i].Y *= attractiveOrRepulsiveFactor;

			}

			// set the forces in the Particle Ensemble Object
			ensemble.AddForces(forces);
			// add in the potential energy    
			ensemble.AddPotentialEnergy(PotentialEnergy);		
		}