Exemplo n.º 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(2, unchecked((int)0xc00A32FF), 0, 50); // neon blue
			ParticleStaticObjects.AtomPropertiesDefinition.addParticleDefinition(4, unchecked((int)0xc0FF0A32), 1, 49); // red
			ParticleStaticObjects.AtomPropertiesDefinition.addParticleDefinition(6, unchecked((int)0xc0320AFF), 2, 45); // purple
			ParticleStaticObjects.AtomPropertiesDefinition.addParticleDefinition(9.2, unchecked((int)0xc026D8FF), 3, 43); // sky blue // 0xc032FF0A, 3,  43); // green 
			ParticleStaticObjects.AtomPropertiesDefinition.addParticleDefinition(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);
		}
Exemplo n.º 2
0
		/* 
		//  function to propagate the particle ensemble
		public void VelocityVerletPropagation(int, int, ExternalField) 
		{
  

		}
	*/

		// velocity verlet routine to propagate the particle ensemble
		public void VelocityVerletPropagation(int Height, int Width, ExternalField pExternalField)
		{
			int i, kk;
			double V = 0.0, T = 0.0, dt, pxnew, pynew, factor;
			DPVector pnew;
			DPVector vnew; 

			AllPositionsUnchangedFromLastStep = true;

			BoxWidth = Width;
			BoxHeight = Height;

			if (NumberOfParticlesChangedFlag)
			{
				NumberOfParticlesChangedFlag = false;
				if (NumberOfParticlesIsGreaterFlag)
				{
					for (kk = 0; kk < GetNumberOfForceFieldObjects(); ++kk)
					{				// calculate the ij energy terms for particle set including the new ones
						GetForceFieldObject(kk).UpdateEnergyTerms(this);
					}
				}
			}
			else
			{

				//  Timestep = 1.0/(double)ofGetFrameRate();
				Timestep = 0.005;

				dt = Timestep;
				++step;                                 // increment ParticleEnsemble Private data member step

				if (BerendsenThermostat)
				{                //  Berendsen Thermostat
					BerendsenVelocityRescaling();
				}

				//  T=GetKineticEnergy();
				//  V=GetPotentialEnergy();                // get the potential energy - pretty useless when the external field is time dependent - but useful for 
				//  TotalEnergy=T+V;                       // testing that new interparticle forceFields conserve energy

				//this loop uses verlet scheme (VV) to propagate the positions forward one step
				for (i = 0; i < GetNumberOfParticles(); ++i)
				{
					Particle particle = pParticleVector[i];

					//SetLastXParticlePosition(i, GetXParticlePosition(i));
					//SetLastYParticlePosition(i, GetYParticlePosition(i));

					particle.PositionLast = particle.Position; 

					//factor = 0.5 * dt * dt / GetParticleMass(i);
					factor = 0.5 * dt * dt / particle.Mass; // GetParticleMass(i);

					//pxnew = GetXParticlePosition(i) + GetXParticleVelocity(i) * dt + GetXParticleForce(i) * factor;
					//pynew = GetYParticlePosition(i) + GetYParticleVelocity(i) * dt + GetYParticleForce(i) * factor;

					//pxnew = particle.Position.X + GetXParticleVelocity(i) * dt + GetXParticleForce(i) * factor;
					//pynew = GetYParticlePosition(i) + GetYParticleVelocity(i) * dt + GetYParticleForce(i) * factor;
					pnew = particle.Position + particle.Velocity * dt + particle.Force * factor;
					vnew = particle.Velocity; 

					//		cout << "x " << pxnew << " y " << pynew << endl;
					//if (pxnew > GetParticleRadius(i) && pxnew < (BoxWidth - GetParticleRadius(i)))
					if (pnew.X <= particle.Radius || pnew.X >= (BoxWidth - particle.Radius))
					{  
						// this is to reflect off the walls; added by DRG in lieu of soft walls to improve real time stability... not part of a standard VV scheme      
						//SetXParticlePosition(i, GetLastXParticlePosition(i));
						//SetXParticleVelocity(i, -1.0 * GetXParticleVelocity(i));
						
						pnew.X = particle.PositionLast.X;
						vnew.X *= -1;

						particle.WasReflectedByWall = true; 

						//SetWasReflectedByWall(i, true);
						calculateParticleVelocitiesInXWallFrame(i);
						//			cout << "X Wall Reflection, Particle " << i << endl;
					}

					//if (pynew > GetParticleRadius(i) && pynew < (BoxHeight - GetParticleRadius(i)))
					if (pnew.Y <= particle.Radius && pnew.Y >= (BoxHeight - particle.Radius))					
					{  // this is to reflect off the walls; added by DRG in lieu of soft walls to improve real time stability... not part of a standard VV scheme
						//SetYParticlePosition(i, GetLastYParticlePosition(i));
						//SetYParticleVelocity(i, -1.0 * GetYParticleVelocity(i));

						pnew.Y = particle.PositionLast.Y;
						vnew.Y *= -1;

						particle.WasReflectedByWall = true; 
						// SetWasReflectedByWall(i, true);

						calculateParticleVelocitiesInYWallFrame(i);
						//			cout << "Y Wall Reflection, Particle " << i << endl;
					}

					particle.Position = pnew;
					particle.Velocity = vnew;

					//check whether all the positions are changed from the last step
					if (particle.Position != particle.PositionLast)
					{
						AllPositionsUnchangedFromLastStep = false;
					}
				}

				if (AllPositionsUnchangedFromLastStep)
				{    
					// this is a stability measure; if the frame is frozen wrt to the previous frame,
					//cout << "Positions unchanged" << endl;

					EliminateParticleOverlap(BoxHeight, BoxWidth);    // adjust particle positions to eliminate overlap - this can cause the sim to freeze

					for (i = 0; i < GetNumberOfParticles(); ++i)
					{           //  then we zero out the forces and velocities & repropagate the positions
						//      cout << px[i] << " " << py[i] << " " << vx[i] << " " << vy[i] << " " << fx[i] << " " << fy[i] << " " << fxLast[i] << " " << fyLast[i] << endl; 
						Particle particle = pParticleVector[i];

						particle.Force = new DPVector(0, 0);
						//SetXParticleForce(i, 0.0);
						//SetYParticleForce(i, 0.0);
						particle.PositionLast = particle.Position;
						//SetLastXParticlePosition(i, GetXParticlePosition(i));
						//SetLastYParticlePosition(i, GetYParticlePosition(i));
						particle.Position = particle.Position + particle.Velocity * dt + (particle.Force / particle.Mass) * dt * dt * 0.5;
						//SetXParticlePosition(i, GetXParticlePosition(i) + GetXParticleVelocity(i) * dt + (GetXParticleForce(i) / GetParticleMass(i)) * dt * dt * 0.5);
						//SetYParticlePosition(i, GetYParticlePosition(i) + GetYParticleVelocity(i) * dt + (GetYParticleForce(i) / GetParticleMass(i)) * dt * dt * 0.5);
					}

					AllPositionsUnchangedFromLastStep = false;
				}

				UpdateInterParticleSeparations();

				if (pExternalField != null)
				{
					pExternalField.CalculateForceField(this);
				}

				if (GetForceFieldObject(0).ForceFieldType == "HardSphereForceField")
				{
					GetForceFieldObject(0).CalculateForceField(this);
				}
				else
				{
					for (i = 0; i < GetNumberOfParticles(); ++i)
					{
						Particle particle = pParticleVector[i];

						// save the present forces to t-1 vectors
						//SetLastXParticleForce(i, GetXParticleForce(i));
						//SetLastYParticleForce(i, GetYParticleForce(i));
						particle.ForceLast = particle.Force; 
					}


					ZeroForces();			// zero out the force vectors & potential energy
					SetPotentialEnergy(0.0);

					for (kk = 0; kk < GetNumberOfForceFieldObjects(); ++kk)
					{				
						// calculate & set the forces at the new positions
						GetForceFieldObject(kk).CalculateForceField(this);
					}

					for (i = 0; i < GetNumberOfParticles(); ++i)
					{                  
						// use VV scheme to propagate the velocities forward
						Particle particle = pParticleVector[i];

						//factor = dt * 0.5 / GetParticleMass(i);
						factor = dt * 0.5 / particle.Mass;
						
						//SetXParticleVelocity(i, GetXParticleVelocity(i) + (GetXParticleForce(i) + GetLastXParticleForce(i)) * factor);
						//SetYParticleVelocity(i, GetYParticleVelocity(i) + (GetYParticleForce(i) + GetLastYParticleForce(i)) * factor);
						particle.Velocity = particle.Velocity + (particle.Force + particle.ForceLast) * factor;
					}

					// see whether any collisions occurred
					DetermineIfCollisionsOccurred();
				}
			}
		}