void TimeStepFluidModel::step(FluidModel &model) { TimeManager *tm = TimeManager::getCurrent (); const float h = tm->getTimeStepSize(); ParticleData &pd = model.getParticles(); clearAccelerations(model); // Compute viscosity forces if (TimeManager::getCurrent()->getTime() > 0.0) // in the first step we do not know the neighbors { computeDensities(model); computeViscosityAccels(model); } // Update time step size by CFL condition updateTimeStepSizeCFL(model, 0.0001f, 0.005f); // Time integration for (unsigned int i = 0; i < pd.size(); i++) { model.getDeltaX(i).setZero(); pd.getLastPosition(i) = pd.getOldPosition(i); pd.getOldPosition(i) = pd.getPosition(i); TimeIntegration::semiImplicitEuler(h, pd.getMass(i), pd.getPosition(i), pd.getVelocity(i), pd.getAcceleration(i)); } // Perform neighborhood search model.getNeighborhoodSearch()->neighborhoodSearch(&model.getParticles().getPosition(0), model.numBoundaryParticles(), &model.getBoundaryX(0)); // Solve density constraint constraintProjection(model); // Update velocities for (unsigned int i = 0; i < pd.size(); i++) { if (m_velocityUpdateMethod == 0) TimeIntegration::velocityUpdateFirstOrder(h, pd.getMass(i), pd.getPosition(i), pd.getOldPosition(i), pd.getVelocity(i)); else TimeIntegration::velocityUpdateSecondOrder(h, pd.getMass(i), pd.getPosition(i), pd.getOldPosition(i), pd.getLastPosition(i), pd.getVelocity(i)); } // Compute new time tm->setTime (tm->getTime () + h); model.getNeighborhoodSearch()->update(); }
void TimeStepController::step(SimulationModel &model) { TimeManager *tm = TimeManager::getCurrent (); const float h = tm->getTimeStepSize(); ////////////////////////////////////////////////////////////////////////// // rigid body model ////////////////////////////////////////////////////////////////////////// clearAccelerations(model); SimulationModel::RigidBodyVector &rb = model.getRigidBodies(); ParticleData &pd = model.getParticles(); ParticleData &pg = model.getGhostParticles(); #pragma omp parallel default(shared) { #pragma omp for schedule(static) nowait for (int i = 0; i < (int) rb.size(); i++) { rb[i]->getLastPosition() = rb[i]->getOldPosition(); rb[i]->getOldPosition() = rb[i]->getPosition(); TimeIntegration::semiImplicitEuler(h, rb[i]->getMass(), rb[i]->getPosition(), rb[i]->getVelocity(), rb[i]->getAcceleration()); rb[i]->getLastRotation() = rb[i]->getOldRotation(); rb[i]->getOldRotation() = rb[i]->getRotation(); TimeIntegration::semiImplicitEulerRotation(h, rb[i]->getMass(), rb[i]->getInertiaTensorInverseW(), rb[i]->getRotation(), rb[i]->getAngularVelocity(), rb[i]->getTorque()); rb[i]->rotationUpdated(); } ////////////////////////////////////////////////////////////////////////// // particle model ////////////////////////////////////////////////////////////////////////// #pragma omp for schedule(static) for (int i = 0; i < (int) pd.size(); i++) { pd.getLastPosition(i) = pd.getOldPosition(i); pd.getOldPosition(i) = pd.getPosition(i); pd.getVelocity(i) *= (1.0f - m_damping); TimeIntegration::semiImplicitEuler(h, pd.getMass(i), pd.getPosition(i), pd.getVelocity(i), pd.getAcceleration(i)); } for (int i = 0; i < (int)pg.size(); i++) { pg.getLastPosition(i) = pg.getOldPosition(i); pg.getOldPosition(i) = pg.getPosition(i); pg.getVelocity(i) *= (1.0f - m_damping); TimeIntegration::semiImplicitEuler(h, pg.getMass(i), pg.getPosition(i), pg.getVelocity(i), pg.getAcceleration(i)); } } positionConstraintProjection(model); #pragma omp parallel default(shared) { // Update velocities #pragma omp for schedule(static) nowait for (int i = 0; i < (int) rb.size(); i++) { if (m_velocityUpdateMethod == 0) { TimeIntegration::velocityUpdateFirstOrder(h, rb[i]->getMass(), rb[i]->getPosition(), rb[i]->getOldPosition(), rb[i]->getVelocity()); TimeIntegration::angularVelocityUpdateFirstOrder(h, rb[i]->getMass(), rb[i]->getRotation(), rb[i]->getOldRotation(), rb[i]->getAngularVelocity()); } else { TimeIntegration::velocityUpdateSecondOrder(h, rb[i]->getMass(), rb[i]->getPosition(), rb[i]->getOldPosition(), rb[i]->getLastPosition(), rb[i]->getVelocity()); TimeIntegration::angularVelocityUpdateSecondOrder(h, rb[i]->getMass(), rb[i]->getRotation(), rb[i]->getOldRotation(), rb[i]->getLastRotation(), rb[i]->getAngularVelocity()); } } // Update velocities #pragma omp for schedule(static) for (int i = 0; i < (int) pd.size(); i++) { if (m_velocityUpdateMethod == 0) TimeIntegration::velocityUpdateFirstOrder(h, pd.getMass(i), pd.getPosition(i), pd.getOldPosition(i), pd.getVelocity(i)); else TimeIntegration::velocityUpdateSecondOrder(h, pd.getMass(i), pd.getPosition(i), pd.getOldPosition(i), pd.getLastPosition(i), pd.getVelocity(i)); } #pragma omp for schedule(static) for (int i = 0; i < (int)pg.size(); i++) { if (m_velocityUpdateMethod == 0) TimeIntegration::velocityUpdateFirstOrder(h, pg.getMass(i), pg.getPosition(i), pg.getOldPosition(i), pg.getVelocity(i)); else TimeIntegration::velocityUpdateSecondOrder(h, pg.getMass(i), pg.getPosition(i), pg.getOldPosition(i), pg.getLastPosition(i), pg.getVelocity(i)); } } velocityConstraintProjection(model); // compute new time tm->setTime (tm->getTime () + h); }