Пример #1
0
void graphics_show_cairo_surface(void *data, Environment *environment) {
    if (environment -> fast_run) {return;}
    cairo_surface_t *surface = (cairo_surface_t *) data;
    cairo_set_source_surface(environment -> cairo, surface, 0, 0);
    profiler_start(profile_cairo);
    cairo_paint(environment -> cairo);
    profiler_end(profile_cairo);
}
Пример #2
0
// ---------------------------------------------------------------------------
/// Performs time step for the particles and starts parallel exchange.
// ---------------------------------------------------------------------------
void
plasma_move (meshVec_RO_p E, meshVec_RO_p H, meshVec_p J)
{
   profiler_begin (mc_prof_plasma_cleanJ);
   plasma_J = J;
   mf_mesh_clean (plasma_J);
   plasmaWx = plasmaWy = plasmaWz = 0;

#if defined(ACTIVATE_TRACER) && ACTIVATE_TRACER
   fwrite (&Time, sizeof(Time), 1, tracer);
#endif

   // Remembers initial core size and makes shell timestep.
   long int unprocessedCore = countCore;
   plasma_timestep (DOING_SHELL, countShell, E, H, J);

   // Applies local boundary conditions.
   profiler_endBegin (mc_prof_plasma_pbcPop);
   for (int b = 0 ; b < 6 ; ++b)
      BC[b][cpu_bc_min[b]] ();

   // Sends outgoing particles.
   comm_plasma_send ();

   // Parallel exchange (particles and currents).
   profiler_endBegin (mc_prof_plasma_jbc);
   jbc_start (mcast_meshVec (plasma_J));

   // Final timestep (unprocessed core particles).
   plasma_timestep (DOING_CORE, countAll - unprocessedCore, E, H, J);

#if defined(ACTIVATE_TRACER) && ACTIVATE_TRACER
   marker_t p = {.id = 0};
   fwrite (&p, sizeof(p), 1, tracer);
#endif

   profiler_end ();
}

// ---------------------------------------------------------------------------
/// Reports thermal energy of plasma.
// ---------------------------------------------------------------------------
void
plasma_temperature (double *WTx, double *WTy, double *WTz)
{
   *WTx = plasmaWx;
   *WTy = plasmaWy;
   *WTz = plasmaWz;
}
Пример #3
0
void graphics_present(Environment *environment) {
    if (environment -> fast_run) {return;}
    profiler_start(profile_present);
    void *pixels;
    int pitch;
    SDL_Rect rect;
    rect.x = 0;
    rect.y = 0;
    rect.w = environment -> width;
    rect.h = environment -> height;

    cairo_surface_flush(environment -> cairo_surface);
    SDL_UnlockTexture(environment -> base_texture);
    SDL_RenderCopy(environment -> renderer, environment -> base_texture, &rect, &rect);
    SDL_RenderPresent(environment -> renderer);
    SDL_LockTexture(environment -> base_texture, NULL, &pixels, &pitch);
    profiler_end(profile_present);
}
Пример #4
0
/**
  * Signals to profiler that simulation loop is finished.
  */
void profiler_finishLoop(void)
{
    profiler_end();		// Closes main profiler interval.

    char empty1[60], empty2[60];	// Empty strings for output formatting.
    double invBlockTime[mc_maxLevel] = { 1 };	// Coefficients for percentage evaluation.

    memset(empty1, ' ', sizeof(char) * 60);	// Prepares empty string to print indents.
    memset(empty2, ' ', sizeof(char) * 60);
    fprintf(profFile, "--------------- %d intervals ---------------\n", (int) (profEvent - profEvents));
    sample_t *event = profEvents;
    for(; event < profEvent; ++event) {
        const int level = event->level;
        const nameBind_t *const name = profBinds + event->id;

        empty1[level * 2] = 0;	// Sets length of the offset.
        empty2[profLongestName - name->nameLenght + 8 - 2 * level] = 0;	// Sets span between to reach the next column.

        const double dt = event->accumulated;	// Alias for time interval.
        invBlockTime[level] = 100.0 / (dt + 1e-10);	// 100 to turn everything into percents.
        const int levelDn = (level > 0) ? level - 1 : 0;
        fprintf(profFile, "%s%s: %s%8.4f%% %.4e sec %8.4f%%\n", empty1, name->name, empty2, dt * invBlockTime[levelDn], dt, dt * invBlockTime[0]);

        empty1[level * 2] = ' ';	// Restores prepared line for offset.
        empty2[profLongestName - name->nameLenght + 8 - 2 * level] = ' ';	// Restores prepared line for column shift.
        event->accumulated = 0;	// Prepares for next session.
    }

#if defined (mc_debugChecks) && mc_debugChecks == 1
    if(profLevel != -1)
        error("profiler_finishLoop: there are %d open blocks which are not closed properly.", profLevel + 1);
#endif

    profEvent = profEvents;
    profLevel = -1;
    profAccumEvent = 0;
}
Пример #5
0
// ---------------------------------------------------------------------------
/// Mandor2 core.
// ---------------------------------------------------------------------------
int
main (int argc, char **argv)
{
   time_get (&stopFlag_startTime);
   cl_import ("./source/import.pl", argc, argv, 0);

   parameter_enterMPI (argc, argv, 1);
   parameter_load ();

   // Initializes profiler.
   profiler_init (_("output/prof_core_%03d.txt", cpu_here));

   units_load ();

   // Configures all modules.
   main_startUp ();
   em_init      (&E, &H);
   plasma_init  ();

   for (int tmp = 0; tmp < 100; tmp++) tmp_gamma[tmp] = 0.0; // TEMP

   say ("System is initialized successfully.");

   // Total time of the work stage - starts here.
   int    stopFlag   = 0;
   double computTime = MPI_Wtime (),
          oldTime    = -1;
   for (int t = 1 ; t <= totalSteps && !stopFlag ; t++) {
      double W_E, W_M, WTx = 0, WTy = 0, WTz = 0;
      profiler_startLoop ();

      // XXX Add it to the timing counter.
      comm_plasma_start ();

      // Reads data from external file (works as mailbox)..
      profiler_begin (mc_prof_throwStopFlag);
      if (chPoint_stopRequest > 0 && t%chPoint_stopRequest == 0)
         main_throwStopFlag ();

      // H^(n-1/2) -> H^n.
      profiler_endBegin (mc_prof_emh1);
      em_HHalfStep (mcast_meshVec_RO (&E), &H);

      // Energy density of the field at t = n*tau.
      profiler_endBegin (mc_prof_EMenergy);
      em_energy (mcast_meshVec_RO(&E), mcast_meshVec_RO(&H), &W_E, &W_M);
      profiler_endBegin (mc_prof_probes);
      probe_postData (Time, mcast_meshVec_RO(&E), mcast_meshVec_RO(&H));

      // Gauss law test beginning (profiler call is inside).
      gauss_before ();

      profiler_endBegin (mc_prof_plasma_move);
      plasma_move (mcast_meshVec_RO(&E), mcast_meshVec_RO(&H), &J);

      // Energy density: gets plasma termal energy.
      profiler_endBegin (mc_prof_plasma_Txyz);
      plasma_temperature (&WTx, &WTy, &WTz);

      // Tecplot's diagnostic check-pointing.
      if (chPoint_tecplot > 0 && t%chPoint_tecplot == 0) {
         say_doing ("writing tecplot mesh...");
         profiler_endBegin (mc_prof_tecRho);
         plasma_rho (&rho);
         profiler_endBegin (mc_prof_tecEH);
         tecIO_saveFields (Time, mcast_meshVec_RO(&E), mcast_meshVec_RO(&H));
      }

      // Spectral energy density diagnostic.
      if (chPoint_spectr > 0 && t%chPoint_spectr == 0) {
         say_doing ("writing spectral energy density dump...");
         profiler_endBegin (mc_prof_spectr);
         reg_t reg = {{cpu_min[0], cpu_min[1], cpu_min[2]},
                      {cpu_max[0] - mc_have_x, cpu_max[1] - mc_have_y, cpu_max[2] - mc_have_z}};
         reg_t map = {{E.imin, E.jmin, E.kmin},
                      {E.imax, E.jmax, E.kmax}};
         spectr_dump (Time, cpu_here, cpu_total, &reg, &map, E.storage, H.storage);
      }

      // Saves local energies to the buffer.
      profiler_endBegin (mc_prof_wDensity);
      wDensity_addPoint (W_E, W_M, WTx, WTy, WTz);

      // H^n -> H^(n+1/2).
      profiler_endBegin (mc_prof_emh2);
      em_HStep (mcast_meshVec_RO(&E), &H);

      // E^n -> E^(n+1).
      profiler_endBegin (mc_prof_eme);
      em_EStep_start (&E, mcast_meshVec_RO(&H));

      // Gets full picture of the currents.
      profiler_endBegin (mc_prof_jbcFinish);
      jbc_finish (&J);

      profiler_endBegin (mc_prof_plasma_pbcRecv);
      comm_plasma_complete (1000);

      profiler_endBegin (mc_prof_EFinish);
      em_EStep_finish (&E, &H, mcast_meshVec_RO(&J));

      // Gauss law test ending.
      gauss_after (mcast_meshVec_RO(&J), mcast_meshVec_RO(&E));

      // Tecplot's diagnostic check-pointing.
      if (chPoint_tecplot > 0 && t%chPoint_tecplot == 0) {
         say_doing ("writing tecplot mesh...");
         profiler_endBegin (mc_prof_tecRhoJ);
         tecIO_saveCurrents (mcast_meshVec_RO(&J), mcast_meshDouble_RO(&rho));
      }

      // Updates time after successful time step.
      parameter_setTime (Time + tau);

      tmp_update_gamma(countCore, countAll); // TEMP
      tmp_update_gamma(0, countShell); // TEMP

      // System check-point.
      if (t && t%chPoint_full == 0) {
        tmp_save_gamma(sysNum, cpu_here); // TEMP

         timeTick_t startWrite;
         time_get (&startWrite);
         say_doing ("writing check-point...");

         profiler_endBegin (mc_prof_sysSave);
         plasma_save (sysNum, cpu_here);
         sysIO_save  (Time, mcast_meshVec_RO(&E), mcast_meshVec_RO(&H));

         profiler_endBegin (mc_prof_wDensityFlush);
         // WARNING: barrier-type calls inside.
         wDensity_flushData ();
         oldTime = Time;

         // Updates estimate of saving time.
         timeTick_t endWrite;
         time_get (&endWrite);
         stopFlag_saveTime = time_elapsed (&startWrite, &endWrite);
      }

      profiler_endBegin (mc_prof_catchStop);

      // Gets data sent earlier.
      if (chPoint_stopRequest > 0 &&  t % chPoint_stopRequest == 0) {
         stopFlag = main_catchStopFlag ();
      }
      profiler_end ();

      say_doing ("time=%.4f (%.2f %%)   ", Time, 100.0*t/(double) totalSteps);
//       say ("step %d: time=%.4f (%.2f %%)", t, Time
//                                               , 100.0*t/(double) totalSteps);
      profiler_finishLoop ();
   }
   computTime = MPI_Wtime () - computTime;
   say ("main: main loop have taken %f sec.", computTime);

   // System check-point.
   if (oldTime != Time)	{
      say ("Addional check-point to save the final state.");
      plasma_save (sysNum, cpu_here);
      sysIO_save  (Time, mcast_meshVec_RO(&E), mcast_meshVec_RO(&H));
   }

   say ("Final barrier.");
   MPI_Barrier (MPI_COMM_WORLD);

   // Removes tmp file to signal the end of run.
   if (!cpu_here)
      remove ("tmp/stop.flag");

   return EXIT_SUCCESS;
}
Пример #6
0
/**
 * position must be a list
 * If the list consists of two numbers (x y) the surface will be rendered at location x,y
 * the same is true for (plain x y)
 * (x y)
 * (plain x y) x,y = numbers, rendered with top left corner at x,y with scale=1
 * (full) fullscreen
 * (centered)
 * (scaled)
 * (sized)
 * (rotated)

 * (windowed)
 */
Bool graphics_render_at_position(Renderable *renderable, Value position, Environment *environment) {
    if (environment -> fast_run) {return false;}
    profiler_start(profile_render);

    Double width = renderable -> width;
    Double height = renderable -> height;
    Double screen_width = environment -> width;
    Double screen_height = environment -> height;

    cairo_save(environment -> cairo);

    if (position.type == NIL) {
        cairo_scale(environment -> cairo, screen_width/width, screen_height/height);
        goto RENDER;
    }
    if (!IS_LIST(position)) {
        log_error_in;
        goto ERROR;
    }
    if (position.type != CONS) {
        log_error_in;
        goto ERROR;
    }
    Value length_val = list_length(position);
    if (length_val.type != INTEGER) {
        log_error_in;
        goto ERROR;
    }
    Unt length = NUM_VAL(length_val);
    Value first = NEXT(position);


    if (first.type == SYMBOL) {
        if (equal(first, symbols_plain)) {
            /**** plain ****/
            /* Render at coords, unscaled */
            if (length == 3) {
                Value x = NEXT(position);
                Value y = NEXT(position);
                if (IS_NUMERIC(x) && IS_NUMERIC(y)) {
                    cairo_translate(environment -> cairo, NUM_VAL(x), NUM_VAL(y));
                    goto RENDER;
                } /* Return a specific error? */
            }
        } else if (equal(first, symbols_full)) {
            /**** full ****/
            /* Stretch image to fill entire screen */
            if (length == 1) {
                cairo_scale(environment -> cairo, screen_width/width, screen_height/height);
                goto RENDER;
            }
        } else if (equal(first, symbols_centered)) {
            /**** centered ****/
            if (length == 3) {
                Value x = NEXT(position);
                Value y = NEXT(position);
                if (x.type == INTEGER && y.type == INTEGER) {
                    /* Render offset from center */
                    Double dx = (screen_width - width) / 2 + NUM_VAL(x);
                    Double dy = (screen_height - height) / 2 + NUM_VAL(y);
                    cairo_translate(environment -> cairo, dx, dy);
                    goto RENDER;
                }
                if (x.type == FLOAT && y.type == FLOAT) {
                    /* As in sized */
                    Double dx = (screen_width - width) / 2 + ((screen_width - width)/2 * NUM_VAL(x));
                    Double dy = (screen_height - height) / 2 + ((screen_height - height)/2 * NUM_VAL(y));
                    cairo_translate(environment -> cairo, dx, dy);
                    goto RENDER;
                }
            } else if (length == 1) {
                Double dx = (screen_width - width) / 2;
                Double dy = (screen_height - height) / 2;
                cairo_translate(environment -> cairo, dx, dy);
            }
        } else if (equal(first, symbols_scaled)) {
            /**** scaled ****/
            /* ('scaled x y scale) */
            /* ('scaled x y scalex scaley) */
            /* TODO: make it work with relative float positions */
            if (length < 4 || length > 5) {
                log_error_in;
                goto ERROR;
            }

            Value x_val = NEXT(position);
            Value y_val = NEXT(position);
            Value scale_x = NEXT(position);
            Value scale_y = scale_x;
            if (length == 5) {
                scale_y = NEXT(position);
            }

            Double new_width;
            Double new_height;
            if (scale_x.type == INTEGER) {
                new_width = NUM_VAL(scale_x);
            } else if (scale_x.type == FLOAT) {
                new_width = width * NUM_VAL(scale_x);
            } else {
                log_error_in;
                goto ERROR;
            }
            if (scale_y.type == INTEGER) {
                new_height = NUM_VAL(scale_y);
            } else if (scale_y.type == FLOAT) {
                new_height = height * NUM_VAL(scale_y);
            } else {
                log_error_in;
                goto ERROR;
            }

            Double x = 0;
            Double y = 0;
            if (x_val.type == INTEGER) {
                x = NUM_VAL(x_val);
            } else if (x_val.type == FLOAT) {
                x = (screen_width - new_width) / 2 + ((screen_width - new_width)/2 * NUM_VAL(x_val));
            } else {
                log_error_in;
                goto ERROR;
            }
            if (y_val.type == INTEGER) {
                y = NUM_VAL(y_val);
            } else if (y_val.type == FLOAT) {
                y = (screen_height - new_height) / 2 + ((screen_height - new_height)/2 * NUM_VAL(y_val));
            } else {
                log_error_in;
                goto ERROR;
            }
            cairo_translate(environment -> cairo, x, y);
            cairo_scale(environment -> cairo, new_width/width, new_height/height);
            goto RENDER;

        } else if (equal(first, symbols_sized)) {
            /**** sized ****/
            /* ('sized x y sizex/boundx sizey/boundy) */
            /* Render scaled but keep aspect ratio */
            if (length < 4 || length > 5) {
                log_error_in;
                goto ERROR;
            }
            Value x_val = NEXT(position);
            Value y_val = NEXT(position);
            Value size_x = NEXT(position);
            Value size_y = size_x;
            if (length == 5) {
                size_y = NEXT(position);
            }

            Double desired_width;
            Double desired_height;
            if (size_x.type == INTEGER) {
                desired_width = NUM_VAL(size_x);
            } else if (size_x.type == FLOAT) {
                desired_width = screen_width * NUM_VAL(size_x);
            } else {
                log_error_in;
                goto ERROR;
            }
            if (size_y.type == INTEGER) {
                desired_height = NUM_VAL(size_y);
            } else if (size_y.type == FLOAT) {
                desired_height = screen_height * NUM_VAL(size_y);
            } else {
                log_error_in;
                goto ERROR;
            }

            Double new_width;
            Double new_height;
            Double ratio_w = desired_width / width;
            Double ratio_h = desired_height / height;
            if (ratio_w <= ratio_h) {
                new_height = desired_width * ((Double) height / (Double) width);
                new_width = desired_width;
            } else {
                new_width = desired_height * ((Double) width / (Double) height);
                new_height = desired_height;
            }

            Double x = 0;
            Double y = 0;
            if (x_val.type == INTEGER) {
                x = NUM_VAL(x_val);
            } else if (x_val.type == FLOAT) {
                x = (screen_width - new_width) / 2 + ((screen_width - new_width)/2 * NUM_VAL(x_val));
            } else {
                log_error_in;
                goto ERROR;
            }
            if (y_val.type == INTEGER) {
                y = NUM_VAL(y_val);
            } else if (y_val.type == FLOAT) {
                y = (screen_height - new_height) / 2 + ((screen_height - new_height)/2 * NUM_VAL(y_val));
            } else {
                log_error_in;
                goto ERROR;
            }
            cairo_translate(environment -> cairo, x, y);
            cairo_scale(environment -> cairo, new_width/width, new_height/height);
            goto RENDER;
        } else if (equal(first, symbols_rotated)) {
            /**** Rotated ****/
            if (length < 4) {
                log_error_in;
                goto ERROR;
            }

            Value angle_v = NEXT(position);
            if (!IS_NUMERIC(angle_v)) {
                log_error_in;
                goto ERROR;
            }
            Double angle = NUM_VAL(angle_v);

            Value x = NEXT(position);
            Value y = NEXT(position);
            if (!IS_NUMERIC(x) || !IS_NUMERIC(y)) {
                log_error_in;
                goto ERROR;
            }
            Double dx = NUM_VAL(x);
            Double dy = NUM_VAL(y);

            Value scale_x;
            Value scale_y;
            if (length == 5) {
                scale_x = NEXT(position);
                scale_y = scale_x;
            } else if (length == 6) {
                scale_x = NEXT(position);
                scale_y = NEXT(position);
            } else {
                log_error_in;
                goto ERROR;
            }

            Double sx;
            Double sy;
            if (scale_x.type == INTEGER && scale_y.type == INTEGER) {
                sx = NUM_VAL(scale_x)/width;
                sy = NUM_VAL(scale_y)/height;
            } else if (scale_x.type == FLOAT && scale_y.type == FLOAT) {
                sx = NUM_VAL(scale_x);
                sy = NUM_VAL(scale_y);
            } else {
                log_error_in;
                goto ERROR;
            }
            if (sx == 0.0 || sy == 0.0) {
                /* Scaled to 0, thus is not shown. Cairo freezes if given scales of 0 */
                return true;
            }
            cairo_translate(environment -> cairo, dx, dy);
            cairo_translate(environment -> cairo, sx*width/2, sx*height/2);
            cairo_rotate(environment -> cairo, angle);
            cairo_scale(environment -> cairo, sx, sy);
            cairo_translate(environment -> cairo, -width/2, -height/2);
            goto RENDER;
        }

    } else if (IS_NUMERIC(first) && length == 2) {/* (x y) */
        Value second = NEXT(position);
        if (IS_NUMERIC(second)) {
            Double x = NUM_VAL(first);
            Double y = NUM_VAL(second);
            cairo_translate(environment -> cairo, x, y);
            goto RENDER;
        }
    }
 ERROR:
    cairo_restore(environment -> cairo);
    profiler_end(profile_render);
    return false;
 RENDER:
    renderable -> render(renderable -> data, environment);
    /* cairo_set_source_surface(environment -> cairo, surface, 0, 0); */
    /* cairo_paint(environment -> cairo); */
    cairo_restore(environment -> cairo);
    profiler_end(profile_render);
    return true;
}