Commit 29d0e5fe authored by Pedro Gonnet's avatar Pedro Gonnet
Browse files

Merge branch 'master' into gpart_ids

Conflicts:
	src/common_io.c
	src/gravity/Default/gravity_io.h
	src/tools.c
parents 23f09dde 1ebd9336
......@@ -25,15 +25,23 @@ examples/swift_mindt
examples/swift_mindt_mpi
examples/swift_mpi
tests/testVectorize
tests/brute_force.dat
tests/swift_dopair.dat
tests/testPair
tests/brute_force_standard.dat
tests/swift_dopair_standard.dat
tests/brute_force_perturbed.dat
tests/swift_dopair_perturbed.dat
tests/test27cells
tests/brute_force_27_standard.dat
tests/swift_dopair_27_standard.dat
tests/brute_force_27_perturbed.dat
tests/swift_dopair_27_perturbed.dat
tests/testGreetings
tests/testReading
tests/input.hdf5
tests/testSingle
tests/testTimeIntegration
tests/testSPHStep
tests/testParser
theory/latex/swift.pdf
......
......@@ -55,7 +55,6 @@
* @brief Main routine that loads a few particles and generates some output.
*
*/
int main(int argc, char *argv[]) {
int c, icount, periodic = 1;
......@@ -79,7 +78,10 @@ int main(int argc, char *argv[]) {
int nr_nodes = 1, myrank = 0;
FILE *file_thread;
int with_outputs = 1;
int verbose = 0, talking;
int with_external_gravity = 0;
int with_self_gravity = 0;
int engine_policies = 0;
int verbose = 0, talking = 0;
unsigned long long cpufreq = 0;
#ifdef WITH_MPI
......@@ -97,12 +99,15 @@ int main(int argc, char *argv[]) {
#endif
#endif
/* Choke on FP-exceptions. */
// feenableexcept( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
/* Choke on FP-exceptions. */
// feenableexcept( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
/* Initialize CPU frequency, this also starts time. */
clocks_set_cpufreq(cpufreq);
#ifdef WITH_MPI
/* Start by initializing MPI. */
int res, prov;
int res = 0, prov = 0;
if ((res = MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &prov)) !=
MPI_SUCCESS)
error("Call to MPI_Init failed with error %i.", res);
......@@ -128,9 +133,6 @@ int main(int argc, char *argv[]) {
&initial_partition.grid[1], &initial_partition.grid[0]);
#endif
/* Initialize CPU frequency, this also starts time. */
clocks_set_cpufreq(cpufreq);
/* Greeting message */
if (myrank == 0) greetings();
......@@ -156,7 +158,7 @@ int main(int argc, char *argv[]) {
bzero(&s, sizeof(struct space));
/* Parse the options */
while ((c = getopt(argc, argv, "a:c:d:e:f:h:m:oP:q:R:s:t:v:w:y:z:")) != -1)
while ((c = getopt(argc, argv, "a:c:d:e:f:gGh:m:oP:q:R:s:t:v:w:y:z:")) != -1)
switch (c) {
case 'a':
if (sscanf(optarg, "%lf", &scaling) != 1)
......@@ -185,6 +187,12 @@ int main(int argc, char *argv[]) {
case 'f':
if (!strcpy(ICfileName, optarg)) error("Error parsing IC file name.");
break;
case 'g':
with_external_gravity = 1;
break;
case 'G':
with_self_gravity = 1;
break;
case 'h':
if (sscanf(optarg, "%llu", &cpufreq) != 1)
error("Error parsing CPU frequency.");
......@@ -343,10 +351,6 @@ int main(int argc, char *argv[]) {
message("CPU frequency used for tick conversion: %llu Hz", cpufreq);
}
/* Check we have sensible time step bounds */
if (dt_min > dt_max)
error("Minimal time step size must be large than maximal time step size ");
/* Check whether an IC file has been provided */
if (strcmp(ICfileName, "") == 0)
error("An IC file name must be provided via the option -f");
......@@ -356,11 +360,11 @@ int main(int argc, char *argv[]) {
if (myrank == 0) clocks_gettime(&tic);
#if defined(WITH_MPI)
#if defined(HAVE_PARALLEL_HDF5)
read_ic_parallel(ICfileName, dim, &parts, &Ngas, &periodic, myrank, nr_nodes,
MPI_COMM_WORLD, MPI_INFO_NULL);
read_ic_parallel(ICfileName, dim, &parts, &gparts, &Ngas, &Ngpart, &periodic,
myrank, nr_nodes, MPI_COMM_WORLD, MPI_INFO_NULL);
#else
read_ic_serial(ICfileName, dim, &parts, &Ngas, &periodic, myrank, nr_nodes,
MPI_COMM_WORLD, MPI_INFO_NULL);
read_ic_serial(ICfileName, dim, &parts, &gparts, &Ngas, &Ngpart, &periodic,
myrank, nr_nodes, MPI_COMM_WORLD, MPI_INFO_NULL);
#endif
#else
read_ic_single(ICfileName, dim, &parts, &gparts, &Ngas, &Ngpart, &periodic);
......@@ -376,6 +380,7 @@ int main(int argc, char *argv[]) {
#if defined(WITH_MPI)
long long N_long[2] = {Ngas, Ngpart};
MPI_Reduce(&N_long, &N_total, 2, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
N_total[1] -= N_total[0];
if (myrank == 0)
message("Read %lld gas particles and %lld DM particles from the ICs",
N_total[0], N_total[1]);
......@@ -383,8 +388,33 @@ int main(int argc, char *argv[]) {
N_total[0] = Ngas;
N_total[1] = Ngpart - Ngas;
message("Read %lld gas particles and %lld DM particles from the ICs",
N_total[0], N_total[1]);
N_total[0], N_total[1]);
#endif
/* MATTHIEU: Temporary fix to preserve master */
if (!with_external_gravity && !with_self_gravity) {
free(gparts);
gparts = NULL;
for (size_t k = 0; k < Ngas; ++k) parts[k].gpart = NULL;
Ngpart = 0;
#if defined(WITH_MPI)
N_long[0] = Ngas;
N_long[1] = Ngpart;
MPI_Reduce(&N_long, &N_total, 2, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
if (myrank == 0)
message(
"AFTER FIX: Read %lld gas particles and %lld DM particles from the "
"ICs",
N_total[0], N_total[1]);
#else
N_total[0] = Ngas;
N_total[1] = Ngpart;
message(
"AFTER FIX: Read %lld gas particles and %lld DM particles from the ICs",
N_total[0], N_total[1]);
#endif
}
/* MATTHIEU: End temporary fix */
/* Apply h scaling */
if (scaling != 1.0)
......@@ -448,12 +478,16 @@ int main(int argc, char *argv[]) {
message("nr of cells at depth %i is %i.", data[0], data[1]);
}
/* Construct the engine policy */
engine_policies = ENGINE_POLICY | engine_policy_steal | engine_policy_hydro;
if (with_external_gravity) engine_policies |= engine_policy_external_gravity;
if (with_self_gravity) engine_policies |= engine_policy_self_gravity;
/* Initialize the engine with this space. */
if (myrank == 0) clocks_gettime(&tic);
if (myrank == 0) message("nr_nodes is %i.", nr_nodes);
engine_init(&e, &s, dt_max, nr_threads, nr_queues, nr_nodes, myrank,
ENGINE_POLICY | engine_policy_steal | engine_policy_hydro, 0,
time_end, dt_min, dt_max, talking);
engine_policies, 0, time_end, dt_min, dt_max, talking);
if (myrank == 0 && verbose) {
clocks_gettime(&toc);
message("engine_init took %.3f %s.", clocks_diff(&tic, &toc),
......@@ -510,8 +544,8 @@ int main(int argc, char *argv[]) {
/* Legend */
if (myrank == 0)
printf(
"# Step Time time-step Number of updates CPU Wall-clock time "
"[%s]\n",
"# Step Time time-step Number of updates Number of updates "
"CPU Wall-clock time [%s]\n",
clocks_getunit());
/* Let loose a runner on the space. */
......
......@@ -35,13 +35,13 @@ endif
# List required headers
include_HEADERS = space.h runner.h queue.h task.h lock.h cell.h part.h const.h \
engine.h swift.h serial_io.h timers.h debug.h scheduler.h proxy.h parallel_io.h \
common_io.h single_io.h multipole.h map.h tools.h partition.h clocks.h
common_io.h single_io.h multipole.h map.h tools.h partition.h clocks.h parser.h
# Common source files
AM_SOURCES = space.c runner.c queue.c task.c cell.c engine.c \
serial_io.c timers.c debug.c scheduler.c proxy.c parallel_io.c \
units.c common_io.c single_io.c multipole.c version.c map.c \
kernel.c tools.c part.c partition.c clocks.c
kernel.c tools.c part.c partition.c clocks.c parser.c
# Include files for distribution, not installation.
nobase_noinst_HEADERS = approx_math.h atomic.h cycle.h error.h inline.h kernel.h vector.h \
......
......@@ -45,6 +45,7 @@
/* Local headers. */
#include "atomic.h"
#include "error.h"
#include "gravity.h"
#include "hydro.h"
#include "space.h"
#include "timers.h"
......@@ -89,14 +90,18 @@ int cell_unpack(struct pcell *pc, struct cell *c, struct space *s) {
c->ti_end_min = pc->ti_end_min;
c->ti_end_max = pc->ti_end_max;
c->count = pc->count;
c->gcount = pc->gcount;
c->tag = pc->tag;
/* Fill the progeny recursively, depth-first. */
/* Number of new cells created. */
int count = 1;
/* Fill the progeny recursively, depth-first. */
for (int k = 0; k < 8; k++)
if (pc->progeny[k] >= 0) {
struct cell *temp = space_getcell(s);
temp->count = 0;
temp->gcount = 0;
temp->loc[0] = c->loc[0];
temp->loc[1] = c->loc[1];
temp->loc[2] = c->loc[2];
......@@ -122,7 +127,7 @@ int cell_unpack(struct pcell *pc, struct cell *c, struct space *s) {
}
/**
* @brief Link the cells recursively to the given part array.
* @brief Link the cells recursively to the given #part array.
*
* @param c The #cell.
* @param parts The #part array.
......@@ -130,7 +135,7 @@ int cell_unpack(struct pcell *pc, struct cell *c, struct space *s) {
* @return The number of particles linked.
*/
int cell_link(struct cell *c, struct part *parts) {
int cell_link_parts(struct cell *c, struct part *parts) {
c->parts = parts;
......@@ -139,14 +144,40 @@ int cell_link(struct cell *c, struct part *parts) {
int offset = 0;
for (int k = 0; k < 8; k++) {
if (c->progeny[k] != NULL)
offset += cell_link(c->progeny[k], &parts[offset]);
offset += cell_link_parts(c->progeny[k], &parts[offset]);
}
}
/* Return the total number of unpacked cells. */
/* Return the total number of linked particles. */
return c->count;
}
/**
* @brief Link the cells recursively to the given #gpart array.
*
* @param c The #cell.
* @param gparts The #gpart array.
*
* @return The number of particles linked.
*/
int cell_link_gparts(struct cell *c, struct gpart *gparts) {
c->gparts = gparts;
/* Fill the progeny recursively, depth-first. */
if (c->split) {
int offset = 0;
for (int k = 0; k < 8; k++) {
if (c->progeny[k] != NULL)
offset += cell_link_gparts(c->progeny[k], &gparts[offset]);
}
}
/* Return the total number of linked particles. */
return c->gcount;
}
/**
* @brief Pack the data of the given cell and all it's sub-cells.
*
......@@ -164,6 +195,7 @@ int cell_pack(struct cell *c, struct pcell *pc) {
pc->ti_end_min = c->ti_end_min;
pc->ti_end_max = c->ti_end_max;
pc->count = c->count;
pc->gcount = c->gcount;
c->tag = pc->tag = atomic_inc(&cell_next_tag) % cell_max_tag;
/* Fill in the progeny, depth-first recursion. */
......@@ -574,6 +606,27 @@ void cell_init_parts(struct cell *c, void *data) {
c->ti_end_max = 0;
}
/**
* @brief Initialises all g-particles to a valid state even if the ICs were
*stupid
*
* @param c Cell to act upon
* @param data Unused parameter
*/
void cell_init_gparts(struct cell *c, void *data) {
struct gpart *gp = c->gparts;
const int gcount = c->gcount;
for (int i = 0; i < gcount; ++i) {
gp[i].ti_begin = 0;
gp[i].ti_end = 0;
gravity_first_init_gpart(&gp[i]);
}
c->ti_end_min = 0;
c->ti_end_max = 0;
}
/**
* @brief Converts hydro quantities to a valid state after the initial density
*calculation
......
......@@ -47,7 +47,7 @@ struct pcell {
int ti_end_min, ti_end_max;
/* Number of particles in this cell. */
int count;
int count, gcount;
/* tag used for MPI communication. */
int tag;
......@@ -144,7 +144,7 @@ struct cell {
double mass, e_pot, e_int, e_kin;
/* Number of particles updated in this cell. */
int updated;
int updated, g_updated;
/* Linking pointer for "memory management". */
struct cell *next;
......@@ -178,8 +178,10 @@ void cell_gunlocktree(struct cell *c);
int cell_pack(struct cell *c, struct pcell *pc);
int cell_unpack(struct pcell *pc, struct cell *c, struct space *s);
int cell_getsize(struct cell *c);
int cell_link(struct cell *c, struct part *parts);
int cell_link_parts(struct cell *c, struct part *parts);
int cell_link_gparts(struct cell *c, struct gpart *gparts);
void cell_init_parts(struct cell *c, void *data);
void cell_init_gparts(struct cell *c, void *data);
void cell_convert_hydro(struct cell *c, void *data);
void cell_clean_links(struct cell *c, void *data);
......
......@@ -45,6 +45,9 @@
#include "kernel.h"
#include "version.h"
const char* particle_type_names[NUM_PARTICLE_TYPES] = {
"Gas", "DM", "Boundary", "Dummy", "Star", "BH"};
/**
* @brief Converts a C data type to the HDF5 equivalent.
*
......@@ -402,52 +405,68 @@ void createXMFfile() {
*snapshot
*
* @param xmfFile The file to write in.
* @param Nparts The number of particles.
* @param hdfFileName The name of the HDF5 file corresponding to this output.
* @param time The current simulation time.
*/
void writeXMFheader(FILE* xmfFile, long long Nparts, char* hdfFileName,
float time) {
void writeXMFoutputheader(FILE* xmfFile, char* hdfFileName, float time) {
/* Write end of file */
fprintf(xmfFile, "<!-- XMF description for file: %s -->\n", hdfFileName);
fprintf(xmfFile,
"<Grid GridType=\"Collection\" CollectionType=\"Spatial\">\n");
fprintf(xmfFile, "<Time Type=\"Single\" Value=\"%f\"/>\n", time);
fprintf(xmfFile, "<Grid Name=\"Gas\" GridType=\"Uniform\">\n");
fprintf(xmfFile,
"<Topology TopologyType=\"Polyvertex\" Dimensions=\"%lld\"/>\n",
Nparts);
fprintf(xmfFile, "<Geometry GeometryType=\"XYZ\">\n");
fprintf(xmfFile,
"<DataItem Dimensions=\"%lld 3\" NumberType=\"Double\" "
"Precision=\"8\" "
"Format=\"HDF\">%s:/PartType0/Coordinates</DataItem>\n",
Nparts, hdfFileName);
fprintf(xmfFile, "</Geometry>");
}
/**
* @brief Writes the end of the XMF file (closes all open markups)
*
* @param xmfFile The file to write in.
* @param output The number of this output.
* @param time The current simulation time.
*/
void writeXMFfooter(FILE* xmfFile) {
void writeXMFoutputfooter(FILE* xmfFile, int output, float time) {
/* Write end of the section of this time step */
fprintf(xmfFile, "\n</Grid>\n");
fprintf(xmfFile, "</Grid>\n");
fprintf(xmfFile, "\n</Grid>\n");
fprintf(xmfFile,
"\n</Grid> <!-- End of meta-data for output=%03i, time=%f -->\n",
output, time);
fprintf(xmfFile, "\n</Grid> <!-- timeSeries -->\n");
fprintf(xmfFile, "</Domain>\n");
fprintf(xmfFile, "</Xdmf>\n");
fclose(xmfFile);
}
void writeXMFgroupheader(FILE* xmfFile, char* hdfFileName, size_t N,
enum PARTICLE_TYPE ptype) {
fprintf(xmfFile, "\n<Grid Name=\"%s\" GridType=\"Uniform\">\n",
particle_type_names[ptype]);
fprintf(xmfFile,
"<Topology TopologyType=\"Polyvertex\" Dimensions=\"%zi\"/>\n", N);
fprintf(xmfFile, "<Geometry GeometryType=\"XYZ\">\n");
fprintf(xmfFile,
"<DataItem Dimensions=\"%zi 3\" NumberType=\"Double\" "
"Precision=\"8\" "
"Format=\"HDF\">%s:/PartType%d/Coordinates</DataItem>\n",
N, hdfFileName, ptype);
fprintf(xmfFile,
"</Geometry>\n <!-- Done geometry for %s, start of particle fields "
"list -->\n",
particle_type_names[ptype]);
}
void writeXMFgroupfooter(FILE* xmfFile, enum PARTICLE_TYPE ptype) {
fprintf(xmfFile, "</Grid> <!-- End of meta-data for parttype=%s -->\n",
particle_type_names[ptype]);
}
/**
* @brief Writes the lines corresponding to an array of the HDF5 output
*
* @param xmfFile The file in which to write
* @param fileName The name of the HDF5 file associated to this XMF descriptor.
* @param partTypeGroupName The name of the group containing the particles in
*the HDF5 file.
* @param name The name of the array in the HDF5 file.
* @param N The number of particles.
* @param dim The dimension of the quantity (1 for scalars, 3 for vectors).
......@@ -455,21 +474,21 @@ void writeXMFfooter(FILE* xmfFile) {
*
* @todo Treat the types in a better way.
*/
void writeXMFline(FILE* xmfFile, char* fileName, char* name, long long N,
int dim, enum DATA_TYPE type) {
void writeXMFline(FILE* xmfFile, char* fileName, char* partTypeGroupName,
char* name, size_t N, int dim, enum DATA_TYPE type) {
fprintf(xmfFile,
"<Attribute Name=\"%s\" AttributeType=\"%s\" Center=\"Node\">\n",
name, dim == 1 ? "Scalar" : "Vector");
if (dim == 1)
fprintf(xmfFile,
"<DataItem Dimensions=\"%lld\" NumberType=\"Double\" "
"Precision=\"%d\" Format=\"HDF\">%s:/PartType0/%s</DataItem>\n",
N, type == FLOAT ? 4 : 8, fileName, name);
"<DataItem Dimensions=\"%zi\" NumberType=\"Double\" "
"Precision=\"%d\" Format=\"HDF\">%s:%s/%s</DataItem>\n",
N, type == FLOAT ? 4 : 8, fileName, partTypeGroupName, name);
else
fprintf(xmfFile,
"<DataItem Dimensions=\"%lld %d\" NumberType=\"Double\" "
"Precision=\"%d\" Format=\"HDF\">%s:/PartType0/%s</DataItem>\n",
N, dim, type == FLOAT ? 4 : 8, fileName, name);
"<DataItem Dimensions=\"%zi %d\" NumberType=\"Double\" "
"Precision=\"%d\" Format=\"HDF\">%s:%s/%s</DataItem>\n",
N, dim, type == FLOAT ? 4 : 8, fileName, partTypeGroupName, name);
fprintf(xmfFile, "</Attribute>\n");
}
......@@ -483,14 +502,13 @@ void writeXMFline(FILE* xmfFile, char* fileName, char* name, long long N,
* @param gparts The array of #gpart freshly read in.
* @param Ndm The number of DM particles read in.
*/
void prepare_dm_gparts(struct gpart* gparts, size_t Ndm) {
void prepare_dm_gparts(struct gpart* const gparts, size_t Ndm) {
/* Let's give all these gparts a negative id */
for (size_t i = 0; i < Ndm; ++i) {
/* 0 or negative ids are not allowed */
if (gparts[i].id_or_neg_offset <= 0)
error("0 or negative ID for DM particle");
error("0 or negative ID for DM particle %zd: ID=%lld", i, gparts[i].id_or_neg_offset);
}
}
......@@ -506,8 +524,9 @@ void prepare_dm_gparts(struct gpart* gparts, size_t Ndm) {
* @param Ngas The number of gas particles read in.
* @param Ndm The number of DM particles read in.
*/
void duplicate_hydro_gparts(struct part* parts, struct gpart* gparts,
size_t Ngas, size_t Ndm) {
void duplicate_hydro_gparts(struct part* const parts,
struct gpart* const gparts, size_t Ngas,
size_t Ndm) {
for (size_t i = 0; i < Ngas; ++i) {
......@@ -536,14 +555,17 @@ void duplicate_hydro_gparts(struct part* parts, struct gpart* gparts,
* @param dmparts The array of #gpart containg DM particles to be filled.
* @param Ndm The number of DM particles.
*/
void collect_dm_gparts(struct gpart* gparts, size_t Ntot, struct gpart* dmparts,
size_t Ndm) {
void collect_dm_gparts(const struct gpart* const gparts, size_t Ntot,
struct gpart* const dmparts, size_t Ndm) {
size_t count = 0;
/* Loop over all gparts */
for (size_t i = 0; i < Ntot; ++i) {
/* message("i=%zd count=%zd id=%lld part=%p", i, count, gparts[i].id,
* gparts[i].part); */
/* And collect the DM ones */
if (gparts[i].id_or_neg_offset > 0) {
dmparts[count] = gparts[i];
......
......@@ -70,14 +70,20 @@ enum PARTICLE_TYPE {
NUM_PARTICLE_TYPES
};
extern const char* particle_type_names[];
#define FILENAME_BUFFER_SIZE 150
#define PARTICLE_GROUP_BUFFER_SIZE 20
hid_t hdf5Type(enum DATA_TYPE type);
size_t sizeOfType(enum DATA_TYPE type);
void collect_dm_gparts(struct gpart* gparts, size_t Ntot, struct gpart* dmparts,
size_t Ndm);
void prepare_dm_gparts(struct gpart* gparts, size_t Ndm);
void duplicate_hydro_gparts(struct part* parts, struct gpart* gparts,
size_t Ngas, size_t Ndm);
void collect_dm_gparts(const struct gpart* const gparts, size_t Ntot,
struct gpart* const dmparts, size_t Ndm);
void prepare_dm_gparts(struct gpart* const gparts, size_t Ndm);
void duplicate_hydro_gparts(struct part* const parts,
struct gpart* const gparts, size_t Ngas,
size_t Ndm);
void readAttribute(hid_t grp, char* name, enum DATA_TYPE type, void* data);
......@@ -92,10 +98,13 @@ void writeAttribute_s(hid_t grp, char* name, const char* str);
void createXMFfile();
FILE* prepareXMFfile();
void writeXMFfooter(FILE* xmfFile);
void writeXMFheader(FILE* xmfFile, long long N, char* hdfFileName, float time);
void writeXMFline(FILE* xmfFile, char* fileName, char* name, long long N,
int dim, enum DATA_TYPE type);
void writeXMFoutputheader(FILE* xmfFile, char* hdfFileName, float time);
void writeXMFoutputfooter(FILE* xmfFile, int outputCount, float time);
void writeXMFgroupheader(FILE* xmfFile, char* hdfFileName, size_t N,
enum PARTICLE_TYPE ptype);
void writeXMFgroupfooter(FILE* xmfFile, enum PARTICLE_TYPE ptype);
void writeXMFline(FILE* xmfFile, char* fileName, char* partTypeGroupName,
char* name, size_t N, int dim, enum DATA_TYPE type);
void writeCodeDescription(hid_t h_file);
void writeSPHflavour(hid_t h_file);
......
This diff is collapsed.
......@@ -62,6 +62,8 @@ extern const char *engine_policy_names[];
#define engine_maxtaskspercell 96
#define engine_maxproxies 64
#define engine_tasksreweight 10
#define engine_parts_size_grow 1.05
#define engine_redistribute_alloc_margin 1.2
/* The rank of the engine as a global variable (for messages). */
extern int engine_rank;
......@@ -160,12 +162,6 @@ struct engine {
/* Are we talkative ? */
int verbose;
#ifdef WITH_MPI
/* MPI data type for the particle transfers */
MPI_Datatype part_mpi_type;
MPI_Datatype xpart_mpi_type;
#endif
};
/* Function prototypes. */
......@@ -182,7 +178,9 @@ void engine_init_particles(struct engine *e);
void engine_step(struct engine *e);
void engine_maketasks(struct engine *e);
void engine_split(struct engine *e, struct partition *initial_partition);
int engine_exchange_strays(struct engine *e, int offset, size_t *ind, size_t N);
void engine_exchange_strays(struct engine *e, size_t offset_parts,
int *ind_part, size_t *Npart, size_t offset_gparts,
int *ind_gpart, size_t *Ngpart);
void engine_rebuild(struct engine *e);
void engine_repartition(struct engine *e);
void engine_makeproxies(struct engine *e);
......
......@@ -22,14 +22,61 @@
/**
* @brief Computes the gravity time-step of a given particle
*
* @param p Pointer to the particle data
* @param xp Pointer to the extended particle data
* @param gp Pointer to the g-particle data