Пример #1
0
/** \brief Lê o arquivo de parametrização dos custos de instrução
    
    O arquivo possui o formato de uma dupla de CODIGO_DE_OPERACAO e VALOR por linha e separados por espaços em branco.
 
    \param filename O caminho e nome para o arquivo de custos
*/
void read_costs (std::string filename) {
    std::ifstream myfile (filename);
    if (myfile.is_open()) {
        int latency, line_count=0;
        std::string opcode, line;
        while ( getline (myfile,line) ) {
            line_count++;
            std::stringstream stream(line);
            try {
                stream >> opcode >> latency;
                Operation::set_latency(Operation::string_to_opcode(opcode), latency);
            } catch (const std::out_of_range& oor) {
                std::stringstream ss;
                ss << "Erro lendo arquivo " << filename << " na linha " << line_count << ": " << line << std::endl;
                throw SimulationError(ss.str());
            }
        }
        myfile.close();
    } else {
Пример #2
0
void Simulation::addParticle(double x, double y, double vx, double vy,
                             double radius, int mass, int r, int g, int b)
{
    Particle *new_p = new Particle(x, y, vx, vy, radius, mass,
                                   width, height, r, g, b);

    // ensure that new particle does not overlap
    // with existing ones before adding it to the
    // simulation.
    for (Particle *p : particles) {
        if (new_p->overlaps(*p)) {
            std::ostringstream oss;

            oss << "Particle " << *new_p << " overlaps with "
                << "existing particle " << *p;
            throw SimulationError(oss.str());
        }
    }

    particles.push_back(new_p);
}
Пример #3
0
Simulation::Simulation(int width, int height, int fps)
{
    this->width = width;
    this->height = height;
    this->fps = fps;
    is_paused = false;
    speed = SPEED_MIN;
    now = 0.0;
    delay_ms = 1000 / fps;
    window = nullptr;
    renderer = nullptr;

    if (SDL_CreateWindowAndRenderer(width, height, 0,
            &window, &renderer) != 0) {
        std::ostringstream oss;

        oss << "Failed to create window (SDL: "
            << SDL_GetError() << ")";
        throw SimulationError(oss.str());
    }

    resetBackgroundColor();
}
Пример #4
0
void Simulation::tick()
{
    // The idea behind event driven simulation is quite
    // ingenious: we determine the time of all collisions
    // happening between all particles and walls assuming
    // that particles move by straight lines at constant
    // speed without any resistance.
    //
    // We keep the collision events arranged by time in priority
    // queue, so that we always know when and what collisions
    // are going to happen.
    //
    // The expensive calculations have to be done only
    // once when the priority queue is initialised. By the expensive
    // calculations I mean the calculation of all collisions between
    // all available particles O(n^2). Then the event driven model
    // requires to recalculate new events only after some event (collision)
    // happens, which requires no more than O(N). That's why this
    // model is so swift.
    //
    // Of course some of the events in the queue have to be cancelled after
    // the collision event happens (since particle's trajectories change),
    // that's why the system allows to detect whether the event
    // is stale/cancelled.

    if (events.empty()) {
        if (particles.size() == 0) {
            throw SimulationError("Simulation can not be launched "
                                  "with 0 particles");
        }

        initializeEvents();
    }
    if (is_paused) {
        SDL_Delay(delay_ms);
        return;
    }

    bool enough = false;
    while (!enough) {
        Event *ev = events.top();

        events.pop();
        if (ev->isStale()) {
            delete ev;
            continue;
        }

        // simulation system does time related calculations
        // in relative time, not absolute. So we have to
        // translate relative time time to absolute one
        // and vice versa.
        moveParticles(ev->getTime() - now);
        SDL_Delay(simulationTimeToMS(ev->getTime() - now));
        now = ev->getTime();

        switch (ev->getType()) {
        case EventType::WallCollision:
        {
            // Particle collides a wall. This requires to calculate
            // the collisions of this particle with all other particles
            // and walls.
            WallCollisionEvent *wc_ev = dynamic_cast<WallCollisionEvent*>(ev);
            wc_ev->getParticle().bounceWall(wc_ev->getWallType());
            predictCollisions(wc_ev->getParticle());
            break;
        }

        case EventType::ParticleCollision:
        {
            // Two particles collide each other. This requires to calculate
            // the collisions of these two particles with all other particles
            // and walls.
            ParticleCollisionEvent *pc_ev = dynamic_cast<ParticleCollisionEvent*>(ev);
            pc_ev->getFirstParticle().bounceParticle(pc_ev->getSecondParticle());
            predictCollisions(pc_ev->getFirstParticle());
            predictCollisions(pc_ev->getSecondParticle());
            break;
        }

        case EventType::Refresh:
            refresh();
            enough = true;
            events.push(new RefreshEvent(now + MSToSimulationTime(delay_ms)));
            break;
        }

        delete ev;
    }
}
void
nest::SimulationManager::resume_( size_t num_active_nodes )
{
    assert( kernel().is_initialized() );

    std::ostringstream os;
    double_t t_sim = to_do_ * Time::get_resolution().get_ms();

    os << "Number of local nodes: " << num_active_nodes << std::endl;
    os << "Simulaton time (ms): " << t_sim;

#ifdef _OPENMP
    os << std::endl
       << "Number of OpenMP threads: " << kernel().vp_manager.get_num_threads();
#else
    os << std::endl
       << "Not using OpenMP";
#endif

#ifdef HAVE_MPI
    os << std::endl
       << "Number of MPI processes: " << kernel().mpi_manager.get_num_processes();
#else
    os << std::endl
       << "Not using MPI";
#endif

    LOG( M_INFO, "SimulationManager::resume", os.str() );


    terminate_ = false;

    if ( to_do_ == 0 )
        return;

    if ( print_time_ )
    {
        // TODO: Remove direct output
        std::cout << std::endl;
        print_progress_();
    }

    simulating_ = true;
    simulated_ = true;

    update_();

    simulating_ = false;

    if ( print_time_ )
        std::cout << std::endl;

    kernel().mpi_manager.synchronize();

    if ( terminate_ )
    {
        LOG( M_ERROR,
             "SimulationManager::resume",
             "Exiting on error or user signal." );
        LOG( M_ERROR,
             "SimulationManager::resume",
             "SimulationManager: Use 'ResumeSimulation' to resume." );

        if ( SLIsignalflag != 0 )
        {
            SystemSignal signal( SLIsignalflag );
            SLIsignalflag = 0;
            throw signal;
        }
        else
            throw SimulationError();
    }

    LOG( M_INFO, "SimulationManager::resume", "Simulation finished." );
}