#ifndef SIMULATION_H
#define SIMULATION_H

#include <mpi.h>

#include "configuration.h"
#include "particles.h"

typedef struct
{
   const conf_t* configuration;
   MPI_Comm communicator;

   int receive_count;
   MPI_Win rma_window;

   part_t local_particles;
   part_t leaving_particles;
} sim_t;

typedef struct
{
   long n_particles_total;
   int min_particles_per_cell;
   int max_particles_per_cell;

   double max_velocity;
} sim_info_t;

// Meta-information for MPI-Datatype creation
#define SIM_INFO_T_N_LONG_MEMBERS 1
#define SIM_INFO_T_FIRST_LONG_MEMBER n_particles_total
#define SIM_INFO_T_N_INT_MEMBERS 2
#define SIM_INFO_T_FIRST_INT_MEMBER min_particles_per_cell
#define SIM_INFO_T_N_DOUBLE_MEMBERS 1
#define SIM_INFO_T_FIRST_DOUBLE_MEMBER max_velocity

void sim_init(sim_t *s, const conf_t* configuration, MPI_Comm communicator);

void sim_free(sim_t *s);

void sim_info(const sim_t *s, sim_info_t *info);

void sim_calc_forces(sim_t *s);

void sim_move_particles(sim_t *s);

void sim_communicate_particles(sim_t *s);

#endif

