Esempio n. 1
0
void System<DataType,Integrator,Potential,Communicator>::simulate(int numIters, std::ostream & output) {
	// MPI Comms. //
	clearBuffers() ;
	appendTransitionsToBuffers() ;
	appendInteractionsToBuffers() ;
	communicateInteractionsTransitions() ;
	// Initialise the forces. //
	updateForces() ;
	// Prime the velocity based on the integration policy. //
	for (unsigned int i = 0 ; i < positions.size() ; i+=2) {
		Integrator::initialise(&positions[i], &velocities[i], &forces[i]) ;
	}
	// Update velocities and positions based on the integration policy. //
	for (int i = 0; i < numIters ; ++i) {
		updateVelocities() ;
		updatePositions() ;
		// MPI Comms. 
		clearBuffers() ;
		appendTransitionsToBuffers() ;
		appendInteractionsToBuffers() ;
		communicateInteractionsTransitions() ;
		updateForces() ;
		printSystem(output,i) ;
		output << std::endl << std::endl ;
	}
}		/* -----  end of member function simulate  ----- */
Esempio n. 2
0
static void updateForces(int firstStar, int secondStar, struct star* star_array)
{
  if (firstStar > 0){
    if (secondStar > 1){
    addForce(&star_array[firstStar],&star_array[secondStar]);
    updateForces(firstStar, secondStar - 1, star_array);
    }else{
      updateForces(firstStar - 1, firstStar - 2, star_array);
    }
  }
}
Esempio n. 3
0
// Update is called every frame or as specified in the max desired updates per
// second GUI slider
void FluidSimulation3D::update()
{
    SCOPE_CYCLE_COUNTER(STAT_AtmosphericsUpdate)
    updateDiffusion();
    updateForces();
    updateAdvection();
}
Esempio n. 4
0
void particleSystem::advance(float timestep){
   
    dt = timestep;
	// For each particles i ...
	#pragma omp parallel for
	for(int i=0; i < particles.size(); ++i)
	{
		// Normal verlet stuff
		particles[i].pos_old = particles[i].pos;
		particles[i].pos += particles[i].vel * dt;

		// Apply the currently accumulated forces
		particles[i].pos += particles[i].force * dt * dt;

		// Restart the forces with gravity only. We'll add the rest later.
		particles[i].force = globalForce;

		// Calculate the velocity for later.
		particles[i].vel = (particles[i].pos - particles[i].pos_old)/dt;

		// If the velocity is really high, we're going to cheat and cap it.
		// This will not damp all motion. It's not physically-based at all. Just
		// a little bit of a hack.
		float max_vel = 2.f;
		float vel_mag = particles[i].vel.len2();
		// If the velocity is greater than the max velocity, then cut it in half.
		if(vel_mag > max_vel*max_vel)
			particles[i].vel = particles[i].vel * .5f;

		// If the particle is outside the bounds of the world, then
		// Make a little spring force to push it back in.
		if(particles[i].pos.x < -simW) particles[i].force.x -= (particles[i].pos.x - -simW) / 8;
		if(particles[i].pos.x >  simW) particles[i].force.x -= (particles[i].pos.x - simW) / 8;
		if(particles[i].pos.y < bottom) particles[i].force.y -= (particles[i].pos.y - bottom) / 8;
		if(particles[i].pos.y > simW*2) particles[i].force.y -= (particles[i].pos.y - simW*2) / 8;

		// Handle the mouse attractor. 
		// It's a simple spring based attraction to where the mouse is.
       // float attr_dist2 = (particles[i].pos - attractor).len2();
       //const float attr_l = simW/4;
       //if( attracting )
       //      if( attr_dist2 < attr_l*attr_l )
       //        particles[i].force -= (particles[i].pos - attractor) / 256;
	
		// Reset the nessecary items.
		particles[i].rho = particles[i].rho_near = 0;
		particles[i].neighbors.clear();
	}

    updateForces();

    if (kill) {
       for (int i = particles.size()-1; i >= 0; i--)
        {
           particles[i].lifetime -= dt;
           if (particles[i].lifetime < 0.0) eraseParticle(i);
       }
    }
}
Esempio n. 5
0
int MainWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QMainWindow::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        switch (_id) {
        case 0: setIso(); break;
        case 1: launchApp(); break;
        case 2: updateForces(); break;
        case 3: deleteCells(); break;
        case 4: clearQGview(); break;
        case 5: redrawQGview(); break;
        case 6: selectContainer((*reinterpret_cast< int(*)>(_a[1]))); break;
        default: ;
        }
        _id -= 7;
    }
    return _id;
}
Esempio n. 6
0
void SPH::timestep(float dt) {

	if(_nActive < _nParticles && _tStep%5 == 0) {
		++_nActive;
	}

	// Update Time counters
	_dt = dt;
	_T += _dt;
	++_tStep;

	// Update Parameters
	updateDensityPressure();
	updateForces();

	_vmax = 0;

	for(unsigned i=0; i<_nActive; ++i) {

		// Update Velocities
		_v1[i] += _dt*_a1[i];
		_v2[i] += _dt*_a2[i];
		_v3[i] += _dt*_a3[i];

		_vmax = std::max(std::max(_vmax,std::abs(_v1[i])),std::max(std::abs(_v2[i]),std::abs(_v3[i])));

		// Update Positions
		_x1[i] += _dt*_v1[i];
		_x2[i] += _dt*_v2[i];
		_x3[i] += _dt*_v3[i];

	}

	/*
	unsigned microseconds = 20000;
	usleep(microseconds); 
	*/

}
Esempio n. 7
0
void ParticleField::Update() {
  updateForces();
  updateParticles();
  killParticles();
  spawnParticles();
}
Esempio n. 8
0
// Runge Kutta 4th Order simulation step - WORK IN PROGRESS, fails on multiple collisions
void Sim::rungeKuttaStep(float dt)
{
    vec3 x,v, dx1, dx2, dx3, dx4, dv1, dv2, dv3, dv4;
    int i,j;

    // Step 1
    updateForces(0);
    for(i=0; i<myFlag->particlesHigh; i++)
    {
        for(j=0; j<myFlag->particlesWide; j++)
        {
            // pin the corners and detect collisions
            if(myFlag->particles[i][j]->pinned
                    || myPerson->collidesWith(myFlag->particles[i][j]) || myGround->collidesWith(myFlag->particles[i][j]))
            {
                // set velocity to zero
                myFlag->particles[i][j]->velocity=vec3(0.0f,0.0f,0.0f);
                myFlag->particles[i][j]->velocity1=vec3(0.0f,0.0f,0.0f);
                myFlag->particles[i][j]->velocity2=vec3(0.0f,0.0f,0.0f);
                myFlag->particles[i][j]->velocity3=vec3(0.0f,0.0f,0.0f);

                continue;   // skip euler for this particle
            }

            // update all other particles
            else
            {
                // capture current position and velocity
                x = myFlag->particles[i][j]->position;
                v = myFlag->particles[i][j]->velocity;

                // calculate RK4 values
                dx1 = dt * v;
                dv1 = dt * myFlag->particles[i][j]->force;  //acceleration(x,T);

                // store intermediate values
                myFlag->particles[i][j]->position1 = x + dx1/2.0f;
                myFlag->particles[i][j]->velocity1 = v + dv1/2.0f;
            }
        }
    }

    // Step 2
    updateForces(1);
    for(i=0; i<myFlag->particlesHigh; i++)
    {
        for(j=0; j<myFlag->particlesWide; j++)
        {
            // pin the corners and check for collisions
            if(myFlag->particles[i][j]->pinned
                    || myPerson->collidesWith(myFlag->particles[i][j]) || myGround->collidesWith(myFlag->particles[i][j]))
            {
                // set velocity to zero
                myFlag->particles[i][j]->velocity=vec3(0.0f,0.0f,0.0f);
                myFlag->particles[i][j]->velocity1=vec3(0.0f,0.0f,0.0f);
                myFlag->particles[i][j]->velocity2=vec3(0.0f,0.0f,0.0f);
                myFlag->particles[i][j]->velocity3=vec3(0.0f,0.0f,0.0f);

                continue;   // skip euler for this particle
            }

            // update all other particles
            else
            {
                // capture current position and velocity
                x = myFlag->particles[i][j]->position;
                v = myFlag->particles[i][j]->velocity;

                // calculate RK4 values
                dx2 = dt * (v + dv1/2.0f);
                dv2 = dt * myFlag->particles[i][j]->force;  //acceleration(x + dx1/2.0f, T + dt/2.0f);

                // store intermediate values
                myFlag->particles[i][j]->position2 = x + dx2/2.0f;
                myFlag->particles[i][j]->velocity2 = v + dv2/2.0f;
            }
        }
    }

    // Step 3
    updateForces(2);
    for(i=0; i<myFlag->particlesHigh; i++)
    {
        for(j=0; j<myFlag->particlesWide; j++)
        {
            // pin the corners and check for collisions
            if(myFlag->particles[i][j]->pinned
                    || myPerson->collidesWith(myFlag->particles[i][j]) || myGround->collidesWith(myFlag->particles[i][j]))
            {
                // set velocity to zero
                myFlag->particles[i][j]->velocity=vec3(0.0f,0.0f,0.0f);
                myFlag->particles[i][j]->velocity1=vec3(0.0f,0.0f,0.0f);
                myFlag->particles[i][j]->velocity2=vec3(0.0f,0.0f,0.0f);
                myFlag->particles[i][j]->velocity3=vec3(0.0f,0.0f,0.0f);

                continue;   // skip euler for this particle
            }

            // update all other particles
            else
            {
                // capture current position and velocity
                x = myFlag->particles[i][j]->position;
                v = myFlag->particles[i][j]->velocity;

                // calculate RK4 values
                dx3 = dt * (v + dv2/2.0f);
                dv3 = dt *  myFlag->particles[i][j]->force;    //acceleration(x + dx2/2.0f, T + dt/2.0f);

                // store intermediate values
                myFlag->particles[i][j]->position3 = x + dx3;
                myFlag->particles[i][j]->velocity3 = v + dv3;
            }
        }
    }

    // Step 4
    updateForces(3);
    for(i=0; i<myFlag->particlesHigh; i++)
    {
        for(j=0; j<myFlag->particlesWide; j++)
        {
            // pin the corners and check for collisions
            if(myFlag->particles[i][j]->pinned
                    || myPerson->collidesWith(myFlag->particles[i][j]) || myGround->collidesWith(myFlag->particles[i][j]))
            {
                // set velocity to zero
                myFlag->particles[i][j]->velocity=vec3(0.0f,0.0f,0.0f);
                myFlag->particles[i][j]->velocity1=vec3(0.0f,0.0f,0.0f);
                myFlag->particles[i][j]->velocity2=vec3(0.0f,0.0f,0.0f);
                myFlag->particles[i][j]->velocity3=vec3(0.0f,0.0f,0.0f);

                continue;   // skip euler for this particle
            }

            // update all other particles
            else
            {
                // capture current position and velocity
                x = myFlag->particles[i][j]->position;
                v = myFlag->particles[i][j]->velocity;

                // calculate RK4 values
                dx4 = dt * (v + dv3);
                dv4 = dt * myFlag->particles[i][j]->force;    // acceleration(x + dx3, T + dt);

                // update final positions and velocities
                myFlag->particles[i][j]->position = x + dx1/6.0f + dx2/3.0f + dx3/3.0f + dx4/6.0f;
                myFlag->particles[i][j]->velocity = v + dv1/6.0f + dv2/3.0f + dv3/3.0f + dv4/6.0f;
            }
        }
    }
}
Esempio n. 9
0
// Semi-Implicit Euler simulation step
void Sim::semiImplicitEuler(float dt)
{
    int i,j;
    vec3 x,v,a,x_prime,v_prime,a_prime;
    Particle *p;

    // Check if user moved character
    if(personMoved)
    {
        for( i=0; i<myFlag->particlesHigh; i++ )
        {
            for( j=0; j<myFlag->particlesWide; j++ )
            {
                if(myPerson->collidesWith(myFlag->particles[i][j]))
                {
                    myFlag->particles[i][j]->position += (directionMoved * stepSize);

                }
            }
        }

        // reset flag
        personMoved = false;
    }


    // get values for current x,v,a
    updateForces(0);
    for(i=0; i<myFlag->particlesHigh; i++)
    {
        for(j=0; j<myFlag->particlesWide; j++)
        {
            p = myFlag->particles[i][j];

            // for the particle secured to the top of the penguin's body
            if(p->pinned)
            {
                p->position = myPerson->body->origin - vec3(0.0f,myPerson->body->radius,0.0f);

                continue;
            }

            else if(myPerson->collidesWith(p))
            {
                // move particle to outside the person
                if(p->position.y >= myPerson->head->origin.y + myPerson->head->radius)
                {
                    // bump to outside the body
                    p->position = myPerson->body->origin
                            + (normalize(p->position - myPerson->body->origin)
                            * myPerson->body->radius * 1.1f);

                } else
                {
                    // bump to outside head
                    p->position = myPerson->head->origin
                            + (normalize(p->position - myPerson->head->origin)
                            * myPerson->head->radius * 1.1f);
                }

                continue;

            // adjust for collision with ground
            } else if(myGround->collidesWith(myFlag->particles[i][j])){

                continue;

            // update all other particles
            }
            else
            {
                // values at current time
                x = p->position_old;
                v = p->velocity_old;
                a = p->acceleration_old;

                // euler to approximate future values
                v_prime = v + dt * a;
                x_prime = x + dt * v_prime;
                a_prime = p->acceleration;

                // use approx future values to find s.e.i. result
                v = v + dt * a_prime;
                p->velocity = v;
                p->position += v*dt;
                p->acceleration = a_prime;

                p->position1 = x_prime;
                p->velocity1 = v_prime;

            }

        }

    }

}
Esempio n. 10
0
// Euler simulation step
void Sim::eulerStep(float dt)
{
    int i,j;
    vec3 x, v, a;

    if(personMoved)
    {
        for( i=0; i<myFlag->particlesHigh; i++ )
        {
            for( j=0; j<myFlag->particlesWide; j++ )
            {
                if(myPerson->collidesWith(myFlag->particles[i][j]))
                {
                    myFlag->particles[i][j]->position += (directionMoved * stepSize);
                    myFlag->particles[i][j]->pinned = true;
                }
                else
                {
                    myFlag->particles[i][j]->pinned = false;
                }
            }
        }

        // reset flag
        personMoved = false;
    }


    // update forces on particles
    updateForces(0);

    // update velocities and positions of particles
    for( i=0; i<myFlag->particlesHigh; i++ )
    {
        for( j=0; j<myFlag->particlesWide; j++ )
        {
            if(myPerson->collidesWith(myFlag->particles[i][j])){

                // move particle to outside the person
                if(myFlag->particles[i][j]->position.y >= myPerson->head->origin.y + myPerson->head->radius)
                {
                    // bump to outside the body
                    myFlag->particles[i][j]->position = myPerson->body->origin
                            + (normalize(myFlag->particles[i][j]->position - myPerson->body->origin)
                            * myPerson->body->radius * 1.1f);
                } else {
                    // bump to outside head
                    myFlag->particles[i][j]->position = myPerson->head->origin
                            + (normalize(myFlag->particles[i][j]->position - myPerson->head->origin)
                            * myPerson->head->radius * 1.1f);
                }

                continue;

            // adjust for collision with ground
            } else if(myGround->collidesWith(myFlag->particles[i][j])){

                continue;

            // update all other particles
            }
            else
            {
                // calculate acceleration: a = F/m where m=1
                a = myFlag->particles[i][j]->force;

                // get velocity of spring
                v = myFlag->particles[i][j]->velocity;

                // update velocity
                v = v + dt*a;
                myFlag->particles[i][j]->velocity = v;

                // get position of spring
                x = myFlag->particles[i][j]->position;

                // update position
                x = x + v*dt;// + 0.5f * a * dt * dt;

                myFlag->particles[i][j]->position = x;

                // ignore very small velocities
                if(length(v) <= EPSILON)
                {
                    myFlag->particles[i][j]->velocity = vec3(0.0f,0.0f,0.0f);
                }

            }

        }

    }

}
Esempio n. 11
0
// ------- update
void wave::update(vector<inputManager::Target> &targets){
    updateForces(targets);
    updatePolyline();
}
Esempio n. 12
0
SPH::SPH(unsigned N)
	:	_nParticles(N),
		_nGhostObject(_uicSize),
		_x1BoxDim(0), // keep it 2d
		_x2BoxDim(280),
		_x3BoxDim(100),
		_nGhostWall(2*(_x2BoxDim+1+_x3BoxDim+1)*_ghostDepth), // keep it 2d
		_nTotal(_nParticles+_nGhostObject+_nGhostWall),
		_nActive(0),
		_x1(new float[_nTotal]),
		_x2(new float[_nTotal]),
		_x3(new float[_nTotal]),
		_v1(new float[_nTotal]),
		_v2(new float[_nTotal]),
		_v3(new float[_nTotal]),
		_a1(new float[_nTotal]),
		_a2(new float[_nTotal]),
		_a3(new float[_nTotal]),
		_m(new float[_nTotal]),
		_rho(new float[_nTotal]),
		_p(new float[_nTotal]),
		_r(new float[_nTotal]),
		_vmax(1e-10),
		_g(0),
		_damping(.8),
		_support(10),
		_h(.5*_support),
		_kPressure(1),
		_rho0(1),
		_mu(0),
		_T(0.0),
		_tStep(0),
		_dt(0),
		_boxMoved(false)
{

	if(_x1BoxDim%2 || _x2BoxDim%2 || _x3BoxDim%2) {
		std::cout << "Error: please select even dimension for box";
		throw -1;
	}

	std::cout << "\nInitializing Model...";

	initObjectCoords();
	
	// Seeding random number generator and set parameters for normal distribution
	// std::random_device rd; // Uncomment to make it even more random ;)
	// std::mt19937 e2(rd());
	std::mt19937 e2(42);
	float mean = 50; // mean velocity
	float stddev = 10; // standard deviation of velocity
	std::normal_distribution<> dist(mean,stddev);

	// Initialize Fluid Particles
	for(unsigned i=0; i<_nParticles; ++i) {
		
		// Position (Locate at source)
		_x1[i] = 0; // keep it 2d
		_x2[i] = -.45*_x2BoxDim; // fmod(rand(),_x2BoxDim)-.5*_x2BoxDim;
		_x3[i] = .45*_x3BoxDim; // fmod(rand(),_x3BoxDim)-.5*_x3BoxDim;
		
		// Masses (assume two groups of particle masses)
		_m[i] = .5*(1+i%2);
		_rho[i] = 1;
		_p[i] = 1;

		// Radius / Support of particles
		_r[i] = 1; // 1+i%3;

		// Compute Forces acting on particles based on positions
		updateForces();

		// Velocities (sampled from random normal distribution)
		_v1[i] = 0; // keep it 2d
		_v2[i] = dist(e2);
		_v3[i] = 0; // dist(e2);

	}

	// Initialize Ghost Particles in Object
	for(unsigned i=_nParticles; i<(_nParticles+_nGhostObject); ++i) {

		unsigned objectIndex = i - _nParticles;

		_x1[i] = _uic[0][objectIndex];
		_x2[i] = _uic[1][objectIndex];
		_x3[i] = _uic[2][objectIndex];

		_v1[i] = 0;
		_v2[i] = 0;
		_v3[i] = 0;
	
		_r[i] = 1;
		_m[i] = 1;
		_p[i] = 1;

	}
	
	// Initialize Ghost Particles in Wall

	// temporary indices for loop
	unsigned zeroIndex; 

	for(unsigned d=0; d<_ghostDepth; ++d) {
		
		zeroIndex = _nParticles + _nGhostObject + 2*d*(_x2BoxDim+1+_x3BoxDim+1);

		for(unsigned i=0; i<(2*_x3BoxDim+1); ++i) {
			_x1[zeroIndex+i] = 0; // keep it 2d
			_x2[zeroIndex+i] = (i%2 ? 1 : -1) * (.5*_x2BoxDim + d); // place on alternating sides
			_x3[zeroIndex+i] = -.5*_x3BoxDim + i/2; // place at distance 1 apart
			
			// v=0 for wall particles
			_v1[zeroIndex+i] = 0;
			_v2[zeroIndex+i] = 0;
			_v3[zeroIndex+i] = 0;

			_m[zeroIndex+i] = 1e3;
			_p[zeroIndex+i] = 1;
			_r[zeroIndex+i] = .4;
		}

		zeroIndex += 2*_x3BoxDim;
		
		for(unsigned i=0; i<(2*_x2BoxDim+1); ++i) {
			_x1[zeroIndex+i] = 0; // keep it 2d
			_x2[zeroIndex+i] = -.5*_x2BoxDim + i/2; // place at distance 1 apart
			_x3[zeroIndex+i] = (i%2 ? 1 : -1) * (.5*_x3BoxDim + d); // place on alternating sides
			
			// v=0 for wall particles
			_v1[zeroIndex+i] = 0;
			_v2[zeroIndex+i] = 0;
			_v3[zeroIndex+i] = 0;

			_m[zeroIndex+i] = 1;
			_p[zeroIndex+i] = 1;
			_r[zeroIndex+i] = .4;
		}
	
	}
}
Esempio n. 13
0
int main(int argc, char* argv[]) {

  int number_of_stars = 200;
  int iterations = 1000;
  prec time_unit = gdt;

  if(argc == 3)
    {
      number_of_stars = atoi(argv[1]);
      iterations = atoi(argv[2]);
    }
  struct star* star_array = malloc(sizeof(struct star) * number_of_stars);
  generate_init_values(number_of_stars, star_array);
  
  
  
  
  
#ifdef ANIMATE
  XPoint* points = malloc(sizeof(XPoint)*number_of_stars);
  Display* disp;
  Window window, rootwin;
  int screen;

  disp = XOpenDisplay(NULL);
  screen = DefaultScreen(disp);
  rootwin = RootWindow(disp,screen);
  window = XCreateSimpleWindow(disp,rootwin,
                               0,0,X_SIZE,Y_SIZE,1,0,0);
  GC gc = XCreateGC(disp, window, 0, 0);
  XSetForeground(disp, gc, WhitePixel(disp, screen));
  XSetBackground(disp, gc, BlackPixel(disp, screen));
  XMapWindow(disp,window);

  XClearWindow(disp,window);	
	
  copyToXBuffer(star_array, points, number_of_stars);
  XDrawPoints(disp, window, gc, points, number_of_stars, 0);

  XFlush(disp);

#endif

  clock_t start = clock();
  for(int i = 0; i < iterations; i++)
    {

#ifndef ANIMATE
      
      resetForces(number_of_stars, star_array);
      updateForces(number_of_stars, number_of_stars - 1, star_array);
      for(int j = 0; j < number_of_stars; ++j){
        update_position(&star_array[j], time_unit);
      }

#endif
     
#ifdef ANIMATE

      resetForces(number_of_stars, star_array);
      updateForces(number_of_stars, number_of_stars - 1, star_array);
      for(int j = 0; j < number_of_stars; ++j){
        update_position(&star_array[j], time_unit);


        copyToXBuffer(star_array, points,number_of_stars );
        XDrawPoints(disp, window, gc, points, number_of_stars, CoordModeOrigin);
	

      }
      XClearWindow(disp,window);

    
#endif
 
    }
  clock_t stop = clock();
  float diff = (float)(stop - start)/CLOCKS_PER_SEC;
  printf("Total: %lf seconds\n",diff);
  printf("Bodies: %d\n",number_of_stars);
  printf("Iterations: %d\n", iterations);

#ifdef ANIMATE
  free(points);
  XCloseDisplay(disp);
#endif
  free(star_array);
  return 0;
}