From ec8c1de5c9d15f0c65d63f104cedb5c592868c1d Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 16 May 2016 15:38:30 +0100 Subject: [PATCH 01/72] Removed all the gravity tasks apart from the 'up' ones. --- src/engine.c | 50 +- src/runner.c | 28 +- src/runner_doiact_grav.h | 1018 +++++++++++++++++++------------------- src/scheduler.c | 256 +++++----- src/space.c | 7 +- src/task.c | 38 +- src/task.h | 6 +- 7 files changed, 707 insertions(+), 696 deletions(-) diff --git a/src/engine.c b/src/engine.c index 05b0739c5..d5fe48bf1 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1340,28 +1340,31 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { void engine_make_gravityinteraction_tasks(struct engine *e) { struct space *s = e->s; - struct scheduler *sched = &e->sched; + /* struct scheduler *sched = &e->sched; */ const int nr_cells = s->nr_cells; - struct cell *cells = s->cells; + /* struct cell *cells = s->cells; */ /* Loop over all cells. */ for (int i = 0; i < nr_cells; i++) { - /* If it has gravity particles, add a self-task */ - if (cells[i].gcount > 0) { - scheduler_addtask(sched, task_type_grav_mm, task_subtype_none, -1, 0, - &cells[i], NULL, 0); - - /* Loop over all remainding cells */ - for (int j = i + 1; j < nr_cells; j++) { - - /* If that other cell has gravity parts, add a pair interaction */ - if (cells[j].gcount > 0) { - scheduler_addtask(sched, task_type_grav_mm, task_subtype_none, -1, 0, - &cells[i], &cells[j], 0); - } - } - } + /* /\* If it has gravity particles, add a self-task *\/ */ + /* if (cells[i].gcount > 0) { */ + /* scheduler_addtask(sched, task_type_grav_mm, task_subtype_none, -1, 0, + */ + /* &cells[i], NULL, 0); */ + + /* /\* Loop over all remainding cells *\/ */ + /* for (int j = i + 1; j < nr_cells; j++) { */ + + /* /\* If that other cell has gravity parts, add a pair interaction *\/ + */ + /* if (cells[j].gcount > 0) { */ + /* scheduler_addtask(sched, task_type_grav_mm, task_subtype_none, -1, + * 0, */ + /* &cells[i], &cells[j], 0); */ + /* } */ + /* } */ + /* } */ } } @@ -1390,9 +1393,12 @@ void engine_make_gravityrecursive_tasks(struct engine *e) { struct task *up = scheduler_addtask(sched, task_type_grav_up, task_subtype_none, 0, 0, &cells[k], NULL, 0); - struct task *down = - scheduler_addtask(sched, task_type_grav_down, task_subtype_none, 0, 0, - &cells[k], NULL, 0); + + struct task *down = NULL; + /* struct task *down = */ + /* scheduler_addtask(sched, task_type_grav_down, task_subtype_none, 0, + * 0, */ + /* &cells[k], NULL, 0); */ /* Push tasks down the cell hierarchy. */ engine_addtasks_grav(e, &cells[k], up, down); @@ -1428,8 +1434,8 @@ void engine_maketasks(struct engine *e) { engine_make_hydroloop_tasks(e); /* Add the gravity mm tasks. */ - if (e->policy & engine_policy_self_gravity) - engine_make_gravityinteraction_tasks(e); + /* if (e->policy & engine_policy_self_gravity) */ + /* engine_make_gravityinteraction_tasks(e); */ /* Split the tasks. */ scheduler_splittasks(sched); diff --git a/src/runner.c b/src/runner.c index 77153d060..c096d2e48 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1340,8 +1340,8 @@ void *runner_main(void *data) { runner_dosub1_density(r, ci, cj, t->flags, 1); else if (t->subtype == task_subtype_force) runner_dosub2_force(r, ci, cj, t->flags, 1); - else if (t->subtype == task_subtype_grav) - runner_dosub_grav(r, ci, cj, 1); + /* else if (t->subtype == task_subtype_grav) */ + /* runner_dosub_grav(r, ci, cj, 1); */ else error("Unknown task subtype."); break; @@ -1362,21 +1362,21 @@ void *runner_main(void *data) { case task_type_recv: runner_dorecv_cell(r, ci, 1); break; - case task_type_grav_pp: - if (t->cj == NULL) - runner_doself_grav(r, t->ci); - else - runner_dopair_grav(r, t->ci, t->cj); - break; - case task_type_grav_mm: - runner_dograv_mm(r, t->ci, t->cj); - break; + /* case task_type_grav_pp: */ + /* if (t->cj == NULL) */ + /* runner_doself_grav(r, t->ci); */ + /* else */ + /* runner_dopair_grav(r, t->ci, t->cj); */ + /* break; */ + /* case task_type_grav_mm: */ + /* runner_dograv_mm(r, t->ci, t->cj); */ + /* break; */ case task_type_grav_up: runner_dograv_up(r, t->ci); break; - case task_type_grav_down: - runner_dograv_down(r, t->ci); - break; + /* case task_type_grav_down: */ + /* runner_dograv_down(r, t->ci); */ + /* break; */ case task_type_grav_external: runner_dograv_external(r, t->ci, 1); break; diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 02626295a..19e778795 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -24,177 +24,177 @@ #include "clocks.h" #include "part.h" -/** - * @brief Compute the sorted gravity interactions between a cell pair. - * - * @param r The #runner. - * @param ci The first #cell. - * @param cj The second #cell. - */ - -void runner_dopair_grav_new(struct runner *r, struct cell *ci, - struct cell *cj) { - - struct engine *restrict e = r->e; - int pid, pjd, k, sid; - double rshift, shift[3] = {0.0, 0.0, 0.0}, nshift[3]; - struct entry *restrict sort_i, *restrict sort_j; - struct gpart *restrict pi, *restrict pj, *restrict parts_i, *restrict parts_j; - double pix[3]; - float dx[3], r2, h_max, di, dj; - int count_i, count_j, cnj, cnj_new; - const int ti_current = e->ti_current; - struct multipole m; -#ifdef VECTORIZE - int icount = 0; - float r2q[VEC_SIZE] __attribute__((aligned(16))); - float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); - struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; -#endif - TIMER_TIC - - /* Anything to do here? */ - if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; - - /* Get the sort ID. */ - sid = space_getsid(e->s, &ci, &cj, shift); - - /* Make sure the cells are sorted. */ - runner_dogsort(r, ci, (1 << sid), 0); - runner_dogsort(r, cj, (1 << sid), 0); - - /* Have the cells been sorted? */ - if (!(ci->gsorted & (1 << sid)) || !(cj->gsorted & (1 << sid))) - error("Trying to interact unsorted cells."); - - /* Get the cutoff shift. */ - for (rshift = 0.0, k = 0; k < 3; k++) - rshift += shift[k] * runner_shift[3 * sid + k]; - - /* Pick-out the sorted lists. */ - sort_i = &ci->gsort[sid * (ci->count + 1)]; - sort_j = &cj->gsort[sid * (cj->count + 1)]; - - /* Get some other useful values. */ - h_max = - sqrtf(ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]) * - const_theta_max; - count_i = ci->gcount; - count_j = cj->gcount; - parts_i = ci->gparts; - parts_j = cj->gparts; - cnj = count_j; - multipole_reset(&m); - nshift[0] = -shift[0]; - nshift[1] = -shift[1]; - nshift[2] = -shift[2]; - - /* Loop over the parts in ci. */ - for (pid = count_i - 1; pid >= 0; pid--) { - - /* Get a hold of the ith part in ci. */ - pi = &parts_i[sort_i[pid].i]; - if (pi->ti_end > ti_current) continue; - di = sort_i[pid].d + h_max - rshift; - - for (k = 0; k < 3; k++) pix[k] = pi->x[k] - shift[k]; - - /* Loop over the parts in cj. */ - for (pjd = 0; pjd < cnj && sort_j[pjd].d < di; pjd++) { - - /* Get a pointer to the jth particle. */ - pj = &parts_j[sort_j[pjd].i]; - - /* Compute the pairwise distance. */ - r2 = 0.0f; - for (k = 0; k < 3; k++) { - dx[k] = pix[k] - pj->x[k]; - r2 += dx[k] * dx[k]; - } - -#ifndef VECTORIZE - - // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) - // message( "interacting particles pi=%lli and pj=%lli with r=%.3e in - // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long - // long int)ci) / sizeof(struct cell) , ((long long int)cj) / - // sizeof(struct cell) ); +/* /\** */ +/* * @brief Compute the sorted gravity interactions between a cell pair. */ +/* * */ +/* * @param r The #runner. */ +/* * @param ci The first #cell. */ +/* * @param cj The second #cell. */ +/* *\/ */ + +/* void runner_dopair_grav_new(struct runner *r, struct cell *ci, */ +/* struct cell *cj) { */ + +/* struct engine *restrict e = r->e; */ +/* int pid, pjd, k, sid; */ +/* double rshift, shift[3] = {0.0, 0.0, 0.0}, nshift[3]; */ +/* struct entry *restrict sort_i, *restrict sort_j; */ +/* struct gpart *restrict pi, *restrict pj, *restrict parts_i, *restrict parts_j; */ +/* double pix[3]; */ +/* float dx[3], r2, h_max, di, dj; */ +/* int count_i, count_j, cnj, cnj_new; */ +/* const int ti_current = e->ti_current; */ +/* struct multipole m; */ +/* #ifdef VECTORIZE */ +/* int icount = 0; */ +/* float r2q[VEC_SIZE] __attribute__((aligned(16))); */ +/* float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); */ +/* struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; */ +/* #endif */ +/* TIMER_TIC */ + +/* /\* Anything to do here? *\/ */ +/* if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; */ + +/* /\* Get the sort ID. *\/ */ +/* sid = space_getsid(e->s, &ci, &cj, shift); */ + +/* /\* Make sure the cells are sorted. *\/ */ +/* runner_dogsort(r, ci, (1 << sid), 0); */ +/* runner_dogsort(r, cj, (1 << sid), 0); */ + +/* /\* Have the cells been sorted? *\/ */ +/* if (!(ci->gsorted & (1 << sid)) || !(cj->gsorted & (1 << sid))) */ +/* error("Trying to interact unsorted cells."); */ + +/* /\* Get the cutoff shift. *\/ */ +/* for (rshift = 0.0, k = 0; k < 3; k++) */ +/* rshift += shift[k] * runner_shift[3 * sid + k]; */ + +/* /\* Pick-out the sorted lists. *\/ */ +/* sort_i = &ci->gsort[sid * (ci->count + 1)]; */ +/* sort_j = &cj->gsort[sid * (cj->count + 1)]; */ + +/* /\* Get some other useful values. *\/ */ +/* h_max = */ +/* sqrtf(ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]) * */ +/* const_theta_max; */ +/* count_i = ci->gcount; */ +/* count_j = cj->gcount; */ +/* parts_i = ci->gparts; */ +/* parts_j = cj->gparts; */ +/* cnj = count_j; */ +/* multipole_reset(&m); */ +/* nshift[0] = -shift[0]; */ +/* nshift[1] = -shift[1]; */ +/* nshift[2] = -shift[2]; */ + +/* /\* Loop over the parts in ci. *\/ */ +/* for (pid = count_i - 1; pid >= 0; pid--) { */ + +/* /\* Get a hold of the ith part in ci. *\/ */ +/* pi = &parts_i[sort_i[pid].i]; */ +/* if (pi->ti_end > ti_current) continue; */ +/* di = sort_i[pid].d + h_max - rshift; */ + +/* for (k = 0; k < 3; k++) pix[k] = pi->x[k] - shift[k]; */ + +/* /\* Loop over the parts in cj. *\/ */ +/* for (pjd = 0; pjd < cnj && sort_j[pjd].d < di; pjd++) { */ + +/* /\* Get a pointer to the jth particle. *\/ */ +/* pj = &parts_j[sort_j[pjd].i]; */ + +/* /\* Compute the pairwise distance. *\/ */ +/* r2 = 0.0f; */ +/* for (k = 0; k < 3; k++) { */ +/* dx[k] = pix[k] - pj->x[k]; */ +/* r2 += dx[k] * dx[k]; */ +/* } */ + +/* #ifndef VECTORIZE */ + +/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */ +/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e in */ +/* // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long */ +/* // long int)ci) / sizeof(struct cell) , ((long long int)cj) / */ +/* // sizeof(struct cell) ); */ + +/* runner_iact_grav(r2, dx, pi, pj); */ + +/* #else */ + +/* /\* Add this interaction to the queue. *\/ */ +/* r2q[icount] = r2; */ +/* dxq[3 * icount + 0] = dx[0]; */ +/* dxq[3 * icount + 1] = dx[1]; */ +/* dxq[3 * icount + 2] = dx[2]; */ +/* piq[icount] = pi; */ +/* pjq[icount] = pj; */ +/* icount += 1; */ + +/* /\* Flush? *\/ */ +/* if (icount == VEC_SIZE) { */ +/* runner_iact_vec_grav(r2q, dxq, piq, pjq); */ +/* icount = 0; */ +/* } */ - runner_iact_grav(r2, dx, pi, pj); +/* #endif */ -#else +/* } /\* loop over the parts in cj. *\/ */ - /* Add this interaction to the queue. */ - r2q[icount] = r2; - dxq[3 * icount + 0] = dx[0]; - dxq[3 * icount + 1] = dx[1]; - dxq[3 * icount + 2] = dx[2]; - piq[icount] = pi; - pjq[icount] = pj; - icount += 1; - - /* Flush? */ - if (icount == VEC_SIZE) { - runner_iact_vec_grav(r2q, dxq, piq, pjq); - icount = 0; - } - -#endif +/* /\* Set the new limit. *\/ */ +/* cnj_new = pjd; */ - } /* loop over the parts in cj. */ +/* /\* Add trailing parts to the multipole. *\/ */ +/* for (pjd = cnj_new; pjd < cnj; pjd++) { */ - /* Set the new limit. */ - cnj_new = pjd; +/* /\* Add the part to the multipole. *\/ */ +/* multipole_addpart(&m, &parts_j[sort_j[pjd].i]); */ - /* Add trailing parts to the multipole. */ - for (pjd = cnj_new; pjd < cnj; pjd++) { +/* } /\* add trailing parts to the multipole. *\/ */ - /* Add the part to the multipole. */ - multipole_addpart(&m, &parts_j[sort_j[pjd].i]); +/* /\* Set the new cnj. *\/ */ +/* cnj = cnj_new; */ - } /* add trailing parts to the multipole. */ +/* /\* Interact the ith particle with the multipole. *\/ */ +/* multipole_iact_mp(&m, pi, nshift); */ - /* Set the new cnj. */ - cnj = cnj_new; +/* } /\* loop over the parts in ci. *\/ */ - /* Interact the ith particle with the multipole. */ - multipole_iact_mp(&m, pi, nshift); +/* #ifdef VECTORIZE */ +/* /\* Pick up any leftovers. *\/ */ +/* if (icount > 0) */ +/* for (k = 0; k < icount; k++) */ +/* runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); */ +/* #endif */ - } /* loop over the parts in ci. */ +/* /\* Re-set the multipole. *\/ */ +/* multipole_reset(&m); */ -#ifdef VECTORIZE - /* Pick up any leftovers. */ - if (icount > 0) - for (k = 0; k < icount; k++) - runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); -#endif +/* /\* Loop over the parts in cj and interact with the multipole in ci. *\/ */ +/* for (pid = count_i - 1, pjd = 0; pjd < count_j; pjd++) { */ - /* Re-set the multipole. */ - multipole_reset(&m); +/* /\* Get the position of pj along the axis. *\/ */ +/* dj = sort_j[pjd].d - h_max + rshift; */ - /* Loop over the parts in cj and interact with the multipole in ci. */ - for (pid = count_i - 1, pjd = 0; pjd < count_j; pjd++) { +/* /\* Add any left-over parts in cell_i to the multipole. *\/ */ +/* while (pid >= 0 && sort_i[pid].d < dj) { */ - /* Get the position of pj along the axis. */ - dj = sort_j[pjd].d - h_max + rshift; +/* /\* Add this particle to the multipole. *\/ */ +/* multipole_addpart(&m, &parts_i[sort_i[pid].i]); */ - /* Add any left-over parts in cell_i to the multipole. */ - while (pid >= 0 && sort_i[pid].d < dj) { +/* /\* Decrease pid. *\/ */ +/* pid -= 1; */ +/* } */ - /* Add this particle to the multipole. */ - multipole_addpart(&m, &parts_i[sort_i[pid].i]); +/* /\* Interact pj with the multipole. *\/ */ +/* multipole_iact_mp(&m, &parts_j[sort_j[pjd].i], shift); */ - /* Decrease pid. */ - pid -= 1; - } +/* } /\* loop over the parts in cj and interact with the multipole. *\/ */ - /* Interact pj with the multipole. */ - multipole_iact_mp(&m, &parts_j[sort_j[pjd].i], shift); - - } /* loop over the parts in cj and interact with the multipole. */ - - TIMER_TOC(TIMER_DOPAIR); -} +/* TIMER_TOC(TIMER_DOPAIR); */ +/* } */ /** * @brief Compute the recursive upward sweep, i.e. construct the @@ -231,367 +231,367 @@ void runner_dograv_up(struct runner *r, struct cell *c) { multipole_init(&c->multipole, c->gparts, c->gcount); } -/** - * @brief Compute the recursive downward sweep, i.e. apply the multipole - * acceleration on all the particles. - * - * @param r The #runner. - * @param c The top-level #cell. - */ - -void runner_dograv_down(struct runner *r, struct cell *c) { - - struct multipole *m = &c->multipole; +/* /\** */ +/* * @brief Compute the recursive downward sweep, i.e. apply the multipole */ +/* * acceleration on all the particles. */ +/* * */ +/* * @param r The #runner. */ +/* * @param c The top-level #cell. */ +/* *\/ */ + +/* void runner_dograv_down(struct runner *r, struct cell *c) { */ + +/* struct multipole *m = &c->multipole; */ + +/* /\* Split? *\/ */ +/* if (c->split) { */ + +/* /\* Apply this cell's acceleration on the multipoles below. *\/ */ +/* for (int k = 0; k < 8; k++) */ +/* if (c->progeny[k] != NULL) { */ +/* struct multipole *mp = &c->progeny[k]->multipole; */ +/* mp->a[0] += m->a[0]; */ +/* mp->a[1] += m->a[1]; */ +/* mp->a[2] += m->a[2]; */ +/* } */ + +/* /\* Recurse. *\/ */ +/* for (int k = 0; k < 8; k++) */ +/* if (c->progeny[k] != NULL) runner_dograv_down(r, c->progeny[k]); */ + +/* } */ + +/* /\* No, leaf node. *\/ */ +/* else { */ + +/* /\* Apply the multipole acceleration to all gparts. *\/ */ +/* for (int k = 0; k < c->gcount; k++) { */ +/* struct gpart *p = &c->gparts[k]; */ +/* p->a_grav[0] += m->a[0]; */ +/* p->a_grav[1] += m->a[1]; */ +/* p->a_grav[2] += m->a[2]; */ +/* } */ +/* } */ +/* } */ + +/* /\** */ +/* * @brief Compute the multipole-multipole interaction between two cells. */ +/* * */ +/* * @param r The #runner. */ +/* * @param ci The first #cell. */ +/* * @param cj The second #cell. */ +/* *\/ */ + +/* void runner_dograv_mm(struct runner *r, struct cell *restrict ci, */ +/* struct cell *restrict cj) { */ + +/* struct engine *e = r->e; */ +/* int k; */ +/* double shift[3] = {0.0, 0.0, 0.0}; */ +/* float dx[3], theta; */ + +/* /\* Compute the shift between the cells. *\/ */ +/* for (k = 0; k < 3; k++) { */ +/* dx[k] = cj->loc[k] - ci->loc[k]; */ +/* if (r->e->s->periodic) { */ +/* if (dx[k] < -e->s->dim[k] / 2) */ +/* shift[k] = e->s->dim[k]; */ +/* else if (dx[k] > e->s->dim[k] / 2) */ +/* shift[k] = -e->s->dim[k]; */ +/* dx[k] += shift[k]; */ +/* } */ +/* } */ +/* theta = */ +/* sqrt((dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */ +/* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2])); */ + +/* /\* Do an MM or an MP/PM? *\/ */ +/* if (theta > const_theta_max * 4) { */ + +/* /\* Update the multipoles. *\/ */ +/* multipole_iact_mm(&ci->multipole, &cj->multipole, shift); */ + +/* } else { */ + +/* /\* Interact the multipoles via their parts. *\/ */ +/* for (k = 0; k < ci->gcount; k++) */ +/* multipole_iact_mp(&cj->multipole, &ci->gparts[k], shift); */ +/* for (k = 0; k < cj->gcount; k++) */ +/* multipole_iact_mp(&ci->multipole, &cj->gparts[k], shift); */ +/* } */ +/* } */ + +/* /\** */ +/* * @brief Compute the interactions between a cell pair. */ +/* * */ +/* * @param r The #runner. */ +/* * @param ci The first #cell. */ +/* * @param cj The second #cell. */ +/* *\/ */ + +/* void runner_dopair_grav(struct runner *r, struct cell *restrict ci, */ +/* struct cell *restrict cj) { */ + +/* struct engine *e = r->e; */ +/* int pid, pjd, k, count_i = ci->gcount, count_j = cj->gcount; */ +/* double shift[3] = {0.0, 0.0, 0.0}; */ +/* struct gpart *restrict parts_i = ci->gparts, *restrict parts_j = cj->gparts; */ +/* struct gpart *restrict pi, *restrict pj; */ +/* double pix[3]; */ +/* float dx[3], r2; */ +/* const int ti_current = r->e->ti_current; */ +/* #ifdef VECTORIZE */ +/* int icount = 0; */ +/* float r2q[VEC_SIZE] __attribute__((aligned(16))); */ +/* float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); */ +/* struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; */ +/* #endif */ +/* TIMER_TIC */ + +/* /\* Anything to do here? *\/ */ +/* if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; */ + +/* /\* Get the relative distance between the pairs, wrapping. *\/ */ +/* if (e->s->periodic) */ +/* for (k = 0; k < 3; k++) { */ +/* if (cj->loc[k] - ci->loc[k] < -e->s->dim[k] / 2) */ +/* shift[k] = e->s->dim[k]; */ +/* else if (cj->loc[k] - ci->loc[k] > e->s->dim[k] / 2) */ +/* shift[k] = -e->s->dim[k]; */ +/* } */ + +/* /\* Loop over the parts in ci. *\/ */ +/* for (pid = 0; pid < count_i; pid++) { */ + +/* /\* Get a hold of the ith part in ci. *\/ */ +/* pi = &parts_i[pid]; */ +/* for (k = 0; k < 3; k++) pix[k] = pi->x[k] - shift[k]; */ + +/* /\* Loop over the parts in cj. *\/ */ +/* for (pjd = 0; pjd < count_j; pjd++) { */ + +/* /\* Get a pointer to the jth particle. *\/ */ +/* pj = &parts_j[pjd]; */ + +/* /\* Compute the pairwise distance. *\/ */ +/* r2 = 0.0f; */ +/* for (k = 0; k < 3; k++) { */ +/* dx[k] = pix[k] - pj->x[k]; */ +/* r2 += dx[k] * dx[k]; */ +/* } */ + +/* /\* Compute the interaction. *\/ */ +/* #ifndef VECTORIZE */ + +/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */ +/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e in */ +/* // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long */ +/* // long int)ci) / sizeof(struct cell) , ((long long int)cj) / */ +/* // sizeof(struct cell) ); */ + +/* runner_iact_grav(r2, dx, pi, pj); */ + +/* #else */ + +/* /\* Add this interaction to the queue. *\/ */ +/* r2q[icount] = r2; */ +/* dxq[3 * icount + 0] = dx[0]; */ +/* dxq[3 * icount + 1] = dx[1]; */ +/* dxq[3 * icount + 2] = dx[2]; */ +/* piq[icount] = pi; */ +/* pjq[icount] = pj; */ +/* icount += 1; */ + +/* /\* Flush? *\/ */ +/* if (icount == VEC_SIZE) { */ +/* runner_iact_vec_grav(r2q, dxq, piq, pjq); */ +/* icount = 0; */ +/* } */ + +/* #endif */ + +/* } /\* loop over the parts in cj. *\/ */ + +/* } /\* loop over the parts in ci. *\/ */ + +/* #ifdef VECTORIZE */ +/* /\* Pick up any leftovers. *\/ */ +/* if (icount > 0) */ +/* for (k = 0; k < icount; k++) */ +/* runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); */ +/* #endif */ + +/* TIMER_TOC(timer_dopair_grav); */ +/* } */ + +/* /\** */ +/* * @brief Compute the interactions within a cell. */ +/* * */ +/* * @param r The #runner. */ +/* * @param c The #cell. */ +/* *\/ */ + +/* void runner_doself_grav(struct runner *r, struct cell *restrict c) { */ + +/* int pid, pjd, k, count = c->gcount; */ +/* struct gpart *restrict parts = c->gparts; */ +/* struct gpart *restrict pi, *restrict pj; */ +/* double pix[3] = {0.0, 0.0, 0.0}; */ +/* float dx[3], r2; */ +/* const int ti_current = r->e->ti_current; */ +/* #ifdef VECTORIZE */ +/* int icount = 0; */ +/* float r2q[VEC_SIZE] __attribute__((aligned(16))); */ +/* float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); */ +/* struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; */ +/* #endif */ +/* TIMER_TIC */ + +/* /\* Anything to do here? *\/ */ +/* if (c->ti_end_min > ti_current) return; */ + +/* /\* Loop over every part in c. *\/ */ +/* for (pid = 0; pid < count; pid++) { */ + +/* /\* Get a hold of the ith part in ci. *\/ */ +/* pi = &parts[pid]; */ +/* for (k = 0; k < 3; k++) pix[k] = pi->x[k]; */ + +/* /\* Loop over every other part in c. *\/ */ +/* for (pjd = pid + 1; pjd < count; pjd++) { */ + +/* /\* Get a pointer to the jth particle. *\/ */ +/* pj = &parts[pjd]; */ + +/* /\* Compute the pairwise distance. *\/ */ +/* r2 = 0.0f; */ +/* for (k = 0; k < 3; k++) { */ +/* dx[k] = pix[k] - pj->x[k]; */ +/* r2 += dx[k] * dx[k]; */ +/* } */ + +/* /\* Compute the interaction. *\/ */ +/* #ifndef VECTORIZE */ + +/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */ +/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e." , */ +/* // pi->part->id , pj->part->id , sqrtf(r2) ); */ + +/* runner_iact_grav(r2, dx, pi, pj); */ + +/* #else */ + +/* /\* Add this interaction to the queue. *\/ */ +/* r2q[icount] = r2; */ +/* dxq[3 * icount + 0] = dx[0]; */ +/* dxq[3 * icount + 1] = dx[1]; */ +/* dxq[3 * icount + 2] = dx[2]; */ +/* piq[icount] = pi; */ +/* pjq[icount] = pj; */ +/* icount += 1; */ + +/* /\* Flush? *\/ */ +/* if (icount == VEC_SIZE) { */ +/* runner_iact_vec_grav(r2q, dxq, piq, pjq); */ +/* icount = 0; */ +/* } */ + +/* #endif */ + +/* } /\* loop over the remaining parts in c. *\/ */ + +/* } /\* loop over the parts in c. *\/ */ + +/* #ifdef VECTORIZE */ +/* /\* Pick up any leftovers. *\/ */ +/* if (icount > 0) */ +/* for (k = 0; k < icount; k++) */ +/* runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); */ +/* #endif */ + +/* TIMER_TOC(timer_doself_grav); */ +/* } */ + +/* /\** */ +/* * @brief Compute a gravity sub-task. */ +/* * */ +/* * @param r The #runner. */ +/* * @param ci The first #cell. */ +/* * @param cj The second #cell. */ +/* * @param gettimer Flag to record timer or not. */ +/* *\/ */ + +/* void runner_dosub_grav(struct runner *r, struct cell *ci, struct cell *cj, */ +/* int gettimer) { */ + +/* int j, k, periodic = r->e->s->periodic; */ +/* struct space *s = r->e->s; */ + +/* TIMER_TIC */ + +/* /\* Self-interaction? *\/ */ +/* if (cj == NULL) { */ + +/* /\* If the cell is split, recurse. *\/ */ +/* if (ci->split) { */ + +/* /\* Split this task into tasks on its progeny. *\/ */ +/* for (j = 0; j < 8; j++) */ +/* if (ci->progeny[j] != NULL) { */ +/* runner_dosub_grav(r, ci->progeny[j], NULL, 0); */ +/* for (k = j + 1; k < 8; k++) */ +/* if (ci->progeny[k] != NULL) */ +/* runner_dosub_grav(r, ci->progeny[j], ci->progeny[k], 0); */ +/* } */ - /* Split? */ - if (c->split) { +/* } */ - /* Apply this cell's acceleration on the multipoles below. */ - for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) { - struct multipole *mp = &c->progeny[k]->multipole; - mp->a[0] += m->a[0]; - mp->a[1] += m->a[1]; - mp->a[2] += m->a[2]; - } +/* /\* Otherwise, just make a pp task out of it. *\/ */ +/* else */ +/* runner_doself_grav(r, ci); */ - /* Recurse. */ - for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) runner_dograv_down(r, c->progeny[k]); +/* } */ - } +/* /\* Nope, pair. *\/ */ +/* else { */ + +/* /\* Get the opening angle theta. *\/ */ +/* float dx[3], theta; */ +/* for (k = 0; k < 3; k++) { */ +/* dx[k] = fabs(ci->loc[k] - cj->loc[k]); */ +/* if (periodic && dx[k] > 0.5 * s->dim[k]) dx[k] = -dx[k] + s->dim[k]; */ +/* if (dx[k] > 0.0f) dx[k] -= ci->h[k]; */ +/* } */ +/* theta = (dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */ +/* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]); */ + +/* /\* Split the interaction? *\/ */ +/* if (theta < const_theta_max * const_theta_max) { */ - /* No, leaf node. */ - else { - - /* Apply the multipole acceleration to all gparts. */ - for (int k = 0; k < c->gcount; k++) { - struct gpart *p = &c->gparts[k]; - p->a_grav[0] += m->a[0]; - p->a_grav[1] += m->a[1]; - p->a_grav[2] += m->a[2]; - } - } -} +/* /\* Are both ci and cj split? *\/ */ +/* if (ci->split && cj->split) { */ + +/* /\* Split this task into tasks on its progeny. *\/ */ +/* for (j = 0; j < 8; j++) */ +/* if (ci->progeny[j] != NULL) { */ +/* for (k = 0; k < 8; k++) */ +/* if (cj->progeny[k] != NULL) */ +/* runner_dosub_grav(r, ci->progeny[j], cj->progeny[k], 0); */ +/* } */ + +/* } */ + +/* /\* Otherwise, make a pp task out of it. *\/ */ +/* else */ +/* runner_dopair_grav(r, ci, cj); */ + +/* } */ + +/* /\* Otherwise, mm interaction is fine. *\/ */ +/* else */ +/* runner_dograv_mm(r, ci, cj); */ +/* } */ -/** - * @brief Compute the multipole-multipole interaction between two cells. - * - * @param r The #runner. - * @param ci The first #cell. - * @param cj The second #cell. - */ - -void runner_dograv_mm(struct runner *r, struct cell *restrict ci, - struct cell *restrict cj) { - - struct engine *e = r->e; - int k; - double shift[3] = {0.0, 0.0, 0.0}; - float dx[3], theta; - - /* Compute the shift between the cells. */ - for (k = 0; k < 3; k++) { - dx[k] = cj->loc[k] - ci->loc[k]; - if (r->e->s->periodic) { - if (dx[k] < -e->s->dim[k] / 2) - shift[k] = e->s->dim[k]; - else if (dx[k] > e->s->dim[k] / 2) - shift[k] = -e->s->dim[k]; - dx[k] += shift[k]; - } - } - theta = - sqrt((dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / - (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2])); - - /* Do an MM or an MP/PM? */ - if (theta > const_theta_max * 4) { - - /* Update the multipoles. */ - multipole_iact_mm(&ci->multipole, &cj->multipole, shift); - - } else { - - /* Interact the multipoles via their parts. */ - for (k = 0; k < ci->gcount; k++) - multipole_iact_mp(&cj->multipole, &ci->gparts[k], shift); - for (k = 0; k < cj->gcount; k++) - multipole_iact_mp(&ci->multipole, &cj->gparts[k], shift); - } -} - -/** - * @brief Compute the interactions between a cell pair. - * - * @param r The #runner. - * @param ci The first #cell. - * @param cj The second #cell. - */ - -void runner_dopair_grav(struct runner *r, struct cell *restrict ci, - struct cell *restrict cj) { - - struct engine *e = r->e; - int pid, pjd, k, count_i = ci->gcount, count_j = cj->gcount; - double shift[3] = {0.0, 0.0, 0.0}; - struct gpart *restrict parts_i = ci->gparts, *restrict parts_j = cj->gparts; - struct gpart *restrict pi, *restrict pj; - double pix[3]; - float dx[3], r2; - const int ti_current = r->e->ti_current; -#ifdef VECTORIZE - int icount = 0; - float r2q[VEC_SIZE] __attribute__((aligned(16))); - float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); - struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; -#endif - TIMER_TIC - - /* Anything to do here? */ - if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; - - /* Get the relative distance between the pairs, wrapping. */ - if (e->s->periodic) - for (k = 0; k < 3; k++) { - if (cj->loc[k] - ci->loc[k] < -e->s->dim[k] / 2) - shift[k] = e->s->dim[k]; - else if (cj->loc[k] - ci->loc[k] > e->s->dim[k] / 2) - shift[k] = -e->s->dim[k]; - } - - /* Loop over the parts in ci. */ - for (pid = 0; pid < count_i; pid++) { - - /* Get a hold of the ith part in ci. */ - pi = &parts_i[pid]; - for (k = 0; k < 3; k++) pix[k] = pi->x[k] - shift[k]; - - /* Loop over the parts in cj. */ - for (pjd = 0; pjd < count_j; pjd++) { - - /* Get a pointer to the jth particle. */ - pj = &parts_j[pjd]; - - /* Compute the pairwise distance. */ - r2 = 0.0f; - for (k = 0; k < 3; k++) { - dx[k] = pix[k] - pj->x[k]; - r2 += dx[k] * dx[k]; - } - -/* Compute the interaction. */ -#ifndef VECTORIZE - - // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) - // message( "interacting particles pi=%lli and pj=%lli with r=%.3e in - // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long - // long int)ci) / sizeof(struct cell) , ((long long int)cj) / - // sizeof(struct cell) ); - - runner_iact_grav(r2, dx, pi, pj); - -#else - - /* Add this interaction to the queue. */ - r2q[icount] = r2; - dxq[3 * icount + 0] = dx[0]; - dxq[3 * icount + 1] = dx[1]; - dxq[3 * icount + 2] = dx[2]; - piq[icount] = pi; - pjq[icount] = pj; - icount += 1; - - /* Flush? */ - if (icount == VEC_SIZE) { - runner_iact_vec_grav(r2q, dxq, piq, pjq); - icount = 0; - } - -#endif - - } /* loop over the parts in cj. */ - - } /* loop over the parts in ci. */ - -#ifdef VECTORIZE - /* Pick up any leftovers. */ - if (icount > 0) - for (k = 0; k < icount; k++) - runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); -#endif - - TIMER_TOC(timer_dopair_grav); -} - -/** - * @brief Compute the interactions within a cell. - * - * @param r The #runner. - * @param c The #cell. - */ - -void runner_doself_grav(struct runner *r, struct cell *restrict c) { - - int pid, pjd, k, count = c->gcount; - struct gpart *restrict parts = c->gparts; - struct gpart *restrict pi, *restrict pj; - double pix[3] = {0.0, 0.0, 0.0}; - float dx[3], r2; - const int ti_current = r->e->ti_current; -#ifdef VECTORIZE - int icount = 0; - float r2q[VEC_SIZE] __attribute__((aligned(16))); - float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); - struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; -#endif - TIMER_TIC - - /* Anything to do here? */ - if (c->ti_end_min > ti_current) return; - - /* Loop over every part in c. */ - for (pid = 0; pid < count; pid++) { - - /* Get a hold of the ith part in ci. */ - pi = &parts[pid]; - for (k = 0; k < 3; k++) pix[k] = pi->x[k]; - - /* Loop over every other part in c. */ - for (pjd = pid + 1; pjd < count; pjd++) { - - /* Get a pointer to the jth particle. */ - pj = &parts[pjd]; - - /* Compute the pairwise distance. */ - r2 = 0.0f; - for (k = 0; k < 3; k++) { - dx[k] = pix[k] - pj->x[k]; - r2 += dx[k] * dx[k]; - } - -/* Compute the interaction. */ -#ifndef VECTORIZE - - // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) - // message( "interacting particles pi=%lli and pj=%lli with r=%.3e." , - // pi->part->id , pj->part->id , sqrtf(r2) ); - - runner_iact_grav(r2, dx, pi, pj); - -#else - - /* Add this interaction to the queue. */ - r2q[icount] = r2; - dxq[3 * icount + 0] = dx[0]; - dxq[3 * icount + 1] = dx[1]; - dxq[3 * icount + 2] = dx[2]; - piq[icount] = pi; - pjq[icount] = pj; - icount += 1; - - /* Flush? */ - if (icount == VEC_SIZE) { - runner_iact_vec_grav(r2q, dxq, piq, pjq); - icount = 0; - } - -#endif - - } /* loop over the remaining parts in c. */ - - } /* loop over the parts in c. */ - -#ifdef VECTORIZE - /* Pick up any leftovers. */ - if (icount > 0) - for (k = 0; k < icount; k++) - runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); -#endif - - TIMER_TOC(timer_doself_grav); -} - -/** - * @brief Compute a gravity sub-task. - * - * @param r The #runner. - * @param ci The first #cell. - * @param cj The second #cell. - * @param gettimer Flag to record timer or not. - */ - -void runner_dosub_grav(struct runner *r, struct cell *ci, struct cell *cj, - int gettimer) { - - int j, k, periodic = r->e->s->periodic; - struct space *s = r->e->s; - - TIMER_TIC - - /* Self-interaction? */ - if (cj == NULL) { - - /* If the cell is split, recurse. */ - if (ci->split) { - - /* Split this task into tasks on its progeny. */ - for (j = 0; j < 8; j++) - if (ci->progeny[j] != NULL) { - runner_dosub_grav(r, ci->progeny[j], NULL, 0); - for (k = j + 1; k < 8; k++) - if (ci->progeny[k] != NULL) - runner_dosub_grav(r, ci->progeny[j], ci->progeny[k], 0); - } - - } - - /* Otherwise, just make a pp task out of it. */ - else - runner_doself_grav(r, ci); - - } - - /* Nope, pair. */ - else { - - /* Get the opening angle theta. */ - float dx[3], theta; - for (k = 0; k < 3; k++) { - dx[k] = fabs(ci->loc[k] - cj->loc[k]); - if (periodic && dx[k] > 0.5 * s->dim[k]) dx[k] = -dx[k] + s->dim[k]; - if (dx[k] > 0.0f) dx[k] -= ci->h[k]; - } - theta = (dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / - (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]); - - /* Split the interaction? */ - if (theta < const_theta_max * const_theta_max) { - - /* Are both ci and cj split? */ - if (ci->split && cj->split) { - - /* Split this task into tasks on its progeny. */ - for (j = 0; j < 8; j++) - if (ci->progeny[j] != NULL) { - for (k = 0; k < 8; k++) - if (cj->progeny[k] != NULL) - runner_dosub_grav(r, ci->progeny[j], cj->progeny[k], 0); - } - - } - - /* Otherwise, make a pp task out of it. */ - else - runner_dopair_grav(r, ci, cj); - - } - - /* Otherwise, mm interaction is fine. */ - else - runner_dograv_mm(r, ci, cj); - } - - if (gettimer) TIMER_TOC(timer_dosub_grav); -} +/* if (gettimer) TIMER_TOC(timer_dosub_grav); */ +/* } */ #endif /* SWIFT_RUNNER_DOIACT_GRAV_H */ diff --git a/src/scheduler.c b/src/scheduler.c index d1d343240..887e8d54f 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -518,130 +518,138 @@ void scheduler_splittasks(struct scheduler *s) { } /* pair interaction? */ /* Gravity interaction? */ - else if (t->type == task_type_grav_mm) { - - /* Get a handle on the cells involved. */ - struct cell *ci = t->ci; - struct cell *cj = t->cj; - - /* Self-interaction? */ - if (cj == NULL) { - - /* Ignore this task if the cell has no gparts. */ - if (ci->gcount == 0) t->type = task_type_none; - - /* If the cell is split, recurse. */ - else if (ci->split) { - - /* Make a single sub-task? */ - if (scheduler_dosub && ci->gcount < space_subsize / ci->gcount) { - - t->type = task_type_sub; - t->subtype = task_subtype_grav; - - } - - /* Otherwise, just split the task. */ - else { - - /* Split this task into tasks on its progeny. */ - t->type = task_type_none; - for (int j = 0; j < 8; j++) - if (ci->progeny[j] != NULL && ci->progeny[j]->gcount > 0) { - if (t->type == task_type_none) { - t->type = task_type_grav_mm; - t->ci = ci->progeny[j]; - t->cj = NULL; - } else - t = scheduler_addtask(s, task_type_grav_mm, task_subtype_none, - 0, 0, ci->progeny[j], NULL, 0); - for (int k = j + 1; k < 8; k++) - if (ci->progeny[k] != NULL && ci->progeny[k]->gcount > 0) { - if (t->type == task_type_none) { - t->type = task_type_grav_mm; - t->ci = ci->progeny[j]; - t->cj = ci->progeny[k]; - } else - t = scheduler_addtask(s, task_type_grav_mm, - task_subtype_none, 0, 0, - ci->progeny[j], ci->progeny[k], 0); - } - } - redo = (t->type != task_type_none); - } - - } - - /* Otherwise, just make a pp task out of it. */ - else - t->type = task_type_grav_pp; - - } - - /* Nope, pair. */ - else { - - /* Make a sub-task? */ - if (scheduler_dosub && ci->gcount < space_subsize / cj->gcount) { - - t->type = task_type_sub; - t->subtype = task_subtype_grav; - - } - - /* Otherwise, split the task. */ - else { - - /* Get the opening angle theta. */ - float dx[3], theta; - for (int k = 0; k < 3; k++) { - dx[k] = fabs(ci->loc[k] - cj->loc[k]); - if (s->space->periodic && dx[k] > 0.5 * s->space->dim[k]) - dx[k] = -dx[k] + s->space->dim[k]; - if (dx[k] > 0.0f) dx[k] -= ci->h[k]; - } - theta = - (dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / - (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]); - - /* Ignore this task if the cell has no gparts. */ - if (ci->gcount == 0 || cj->gcount == 0) t->type = task_type_none; - - /* Split the interaction? */ - else if (theta < const_theta_max * const_theta_max) { - - /* Are both ci and cj split? */ - if (ci->split && cj->split) { - - /* Split this task into tasks on its progeny. */ - t->type = task_type_none; - for (int j = 0; j < 8; j++) - if (ci->progeny[j] != NULL && ci->progeny[j]->gcount > 0) { - for (int k = 0; k < 8; k++) - if (cj->progeny[k] != NULL && cj->progeny[k]->gcount > 0) { - if (t->type == task_type_none) { - t->type = task_type_grav_mm; - t->ci = ci->progeny[j]; - t->cj = cj->progeny[k]; - } else - t = scheduler_addtask( - s, task_type_grav_mm, task_subtype_none, 0, 0, - ci->progeny[j], cj->progeny[k], 0); - } - } - redo = (t->type != task_type_none); - - } - - /* Otherwise, make a pp task out of it. */ - else - t->type = task_type_grav_pp; - } - } - - } /* gravity pair interaction? */ - - } /* gravity interaction? */ + /* else if (t->type == task_type_grav_mm) { */ + + /* /\* Get a handle on the cells involved. *\/ */ + /* struct cell *ci = t->ci; */ + /* struct cell *cj = t->cj; */ + + /* /\* Self-interaction? *\/ */ + /* if (cj == NULL) { */ + + /* /\* Ignore this task if the cell has no gparts. *\/ */ + /* if (ci->gcount == 0) t->type = task_type_none; */ + + /* /\* If the cell is split, recurse. *\/ */ + /* else if (ci->split) { */ + + /* /\* Make a single sub-task? *\/ */ + /* if (scheduler_dosub && ci->gcount < space_subsize / ci->gcount) { + */ + + /* t->type = task_type_sub; */ + /* t->subtype = task_subtype_grav; */ + + /* } */ + + /* /\* Otherwise, just split the task. *\/ */ + /* else { */ + + /* /\* Split this task into tasks on its progeny. *\/ */ + /* t->type = task_type_none; */ + /* for (int j = 0; j < 8; j++) */ + /* if (ci->progeny[j] != NULL && ci->progeny[j]->gcount > 0) { */ + /* if (t->type == task_type_none) { */ + /* t->type = task_type_grav_mm; */ + /* t->ci = ci->progeny[j]; */ + /* t->cj = NULL; */ + /* } else */ + /* t = scheduler_addtask(s, task_type_grav_mm, + * task_subtype_none, */ + /* 0, 0, ci->progeny[j], NULL, 0); */ + /* for (int k = j + 1; k < 8; k++) */ + /* if (ci->progeny[k] != NULL && ci->progeny[k]->gcount > 0) { + */ + /* if (t->type == task_type_none) { */ + /* t->type = task_type_grav_mm; */ + /* t->ci = ci->progeny[j]; */ + /* t->cj = ci->progeny[k]; */ + /* } else */ + /* t = scheduler_addtask(s, task_type_grav_mm, */ + /* task_subtype_none, 0, 0, */ + /* ci->progeny[j], ci->progeny[k], + * 0); */ + /* } */ + /* } */ + /* redo = (t->type != task_type_none); */ + /* } */ + + /* } */ + + /* /\* Otherwise, just make a pp task out of it. *\/ */ + /* else */ + /* t->type = task_type_grav_pp; */ + + /* } */ + + /* /\* Nope, pair. *\/ */ + /* else { */ + + /* /\* Make a sub-task? *\/ */ + /* if (scheduler_dosub && ci->gcount < space_subsize / cj->gcount) { */ + + /* t->type = task_type_sub; */ + /* t->subtype = task_subtype_grav; */ + + /* } */ + + /* /\* Otherwise, split the task. *\/ */ + /* else { */ + + /* /\* Get the opening angle theta. *\/ */ + /* float dx[3], theta; */ + /* for (int k = 0; k < 3; k++) { */ + /* dx[k] = fabs(ci->loc[k] - cj->loc[k]); */ + /* if (s->space->periodic && dx[k] > 0.5 * s->space->dim[k]) */ + /* dx[k] = -dx[k] + s->space->dim[k]; */ + /* if (dx[k] > 0.0f) dx[k] -= ci->h[k]; */ + /* } */ + /* theta = */ + /* (dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */ + /* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * + * ci->h[2]); */ + + /* /\* Ignore this task if the cell has no gparts. *\/ */ + /* if (ci->gcount == 0 || cj->gcount == 0) t->type = task_type_none; + */ + + /* /\* Split the interaction? *\/ */ + /* else if (theta < const_theta_max * const_theta_max) { */ + + /* /\* Are both ci and cj split? *\/ */ + /* if (ci->split && cj->split) { */ + + /* /\* Split this task into tasks on its progeny. *\/ */ + /* t->type = task_type_none; */ + /* for (int j = 0; j < 8; j++) */ + /* if (ci->progeny[j] != NULL && ci->progeny[j]->gcount > 0) { + */ + /* for (int k = 0; k < 8; k++) */ + /* if (cj->progeny[k] != NULL && cj->progeny[k]->gcount > 0) + * { */ + /* if (t->type == task_type_none) { */ + /* t->type = task_type_grav_mm; */ + /* t->ci = ci->progeny[j]; */ + /* t->cj = cj->progeny[k]; */ + /* } else */ + /* t = scheduler_addtask( */ + /* s, task_type_grav_mm, task_subtype_none, 0, 0, */ + /* ci->progeny[j], cj->progeny[k], 0); */ + /* } */ + /* } */ + /* redo = (t->type != task_type_none); */ + + /* } */ + + /* /\* Otherwise, make a pp task out of it. *\/ */ + /* else */ + /* t->type = task_type_grav_pp; */ + /* } */ + /* } */ + + /* } /\* gravity pair interaction? *\/ */ + + /* } /\* gravity interaction? *\/ */ } /* loop over all tasks. */ } diff --git a/src/space.c b/src/space.c index 267eca198..d87107a80 100644 --- a/src/space.c +++ b/src/space.c @@ -452,8 +452,7 @@ void space_rebuild(struct space *s, double cell_max, int verbose) { const int t = ind[k]; ind[k] = ind[nr_parts]; ind[nr_parts] = t; - } - else { + } else { /* Increment when not exchanging otherwise we need to retest "k".*/ k++; } @@ -488,8 +487,7 @@ void space_rebuild(struct space *s, double cell_max, int verbose) { const int t = gind[k]; gind[k] = gind[nr_gparts]; gind[nr_gparts] = t; - } - else { + } else { /* Increment when not exchanging otherwise we need to retest "k".*/ k++; } @@ -508,7 +506,6 @@ void space_rebuild(struct space *s, double cell_max, int verbose) { } }*/ - /* Exchange the strays, note that this potentially re-allocates the parts arrays. */ size_t nr_parts_exchanged = s->nr_parts - nr_parts; diff --git a/src/task.c b/src/task.c index 31c2bfcb3..77503d220 100644 --- a/src/task.c +++ b/src/task.c @@ -47,10 +47,10 @@ /* Task type names. */ const char *taskID_names[task_type_count] = { - "none", "sort", "self", "pair", "sub", - "init", "ghost", "drift", "kick", "send", - "recv", "grav_pp", "grav_mm", "grav_up", "grav_down", - "grav_external", "part_sort", "gpart_sort", "split_cell", "rewait"}; + "none", "sort", "self", "pair", "sub", + "init", "ghost", "drift", "kick", "send", + "recv", "grav_up", "grav_external", "part_sort", "gpart_sort", + "split_cell", "rewait"}; const char *subtaskID_names[task_type_count] = {"none", "density", "force", "grav"}; @@ -124,12 +124,12 @@ void task_unlock(struct task *t) { cell_unlocktree(t->ci); if (t->cj != NULL) cell_unlocktree(t->cj); break; - case task_type_grav_pp: - case task_type_grav_mm: - case task_type_grav_down: - cell_gunlocktree(t->ci); - if (t->cj != NULL) cell_gunlocktree(t->cj); - break; + /* case task_type_grav_pp: */ + /* case task_type_grav_mm: */ + /* case task_type_grav_down: */ + /* cell_gunlocktree(t->ci); */ + /* if (t->cj != NULL) cell_gunlocktree(t->cj); */ + /* break; */ default: break; } @@ -184,15 +184,15 @@ int task_lock(struct task *t) { } /* Gravity tasks? */ - else if (type == task_type_grav_mm || type == task_type_grav_pp || - type == task_type_grav_down) { - if (ci->ghold || (cj != NULL && cj->ghold)) return 0; - if (cell_glocktree(ci) != 0) return 0; - if (cj != NULL && cell_glocktree(cj) != 0) { - cell_gunlocktree(ci); - return 0; - } - } + /* else if (type == task_type_grav_mm || type == task_type_grav_pp || */ + /* type == task_type_grav_down) { */ + /* if (ci->ghold || (cj != NULL && cj->ghold)) return 0; */ + /* if (cell_glocktree(ci) != 0) return 0; */ + /* if (cj != NULL && cell_glocktree(cj) != 0) { */ + /* cell_gunlocktree(ci); */ + /* return 0; */ + /* } */ + /* } */ /* If we made it this far, we've got a lock. */ return 1; diff --git a/src/task.h b/src/task.h index 25cc886f4..4956860c9 100644 --- a/src/task.h +++ b/src/task.h @@ -44,10 +44,10 @@ enum task_types { task_type_kick, task_type_send, task_type_recv, - task_type_grav_pp, - task_type_grav_mm, + /* task_type_grav_pp, */ + /* task_type_grav_mm, */ task_type_grav_up, - task_type_grav_down, + /* task_type_grav_down, */ task_type_grav_external, task_type_part_sort, task_type_gpart_sort, -- GitLab From b13e428ba27f1846641a92a55dfbfb2dccf2f0d2 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 16 May 2016 17:12:40 +0100 Subject: [PATCH 02/72] Construct the 1st-order multipoles correctly --- src/const.h | 1 + src/engine.c | 4 +- src/multipole.c | 166 ++++++++++++++++++++------------------- src/multipole.h | 134 +++++++++++++++---------------- src/runner_doiact_grav.h | 59 ++++++++------ 5 files changed, 190 insertions(+), 174 deletions(-) diff --git a/src/const.h b/src/const.h index 6432ef6a9..8390da089 100644 --- a/src/const.h +++ b/src/const.h @@ -40,6 +40,7 @@ #define const_max_u_change 0.1f /* Gravity stuff. */ +#define multipole_order 1 #define const_theta_max 0.57735f #define const_G 6.672e-8f /* Gravitational constant. */ #define const_epsilon 0.0014f /* Gravity blending distance. */ diff --git a/src/engine.c b/src/engine.c index d5fe48bf1..e7c7e8aa3 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1947,7 +1947,7 @@ void engine_init_particles(struct engine *e) { /* Add the tasks corresponding to self-gravity to the masks */ if (e->policy & engine_policy_self_gravity) { - /* Nothing here for now */ + mask |= 1 << task_type_grav_up; } /* Add the tasks corresponding to external gravity to the masks */ @@ -2128,7 +2128,7 @@ void engine_step(struct engine *e) { /* Add the tasks corresponding to self-gravity to the masks */ if (e->policy & engine_policy_self_gravity) { - /* Nothing here for now */ + mask |= 1 << task_type_grav_up; } /* Add the tasks corresponding to external gravity to the masks */ diff --git a/src/multipole.c b/src/multipole.c index fc4701fea..23d845c32 100644 --- a/src/multipole.c +++ b/src/multipole.c @@ -1,6 +1,7 @@ /******************************************************************************* * This file is part of SWIFT. * Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk) + * 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -37,27 +38,28 @@ #include "multipole.h" /** - * @brief Merge two multipoles. + * @brief Add the second multipole to the first one. * - * @param ma The #multipole which will contain the merged result. - * @param mb The other #multipole. + * @param m_sum The #multipole which will contain the sum. + * @param m_other The #multipole to add. */ -void multipole_merge(struct multipole *ma, struct multipole *mb) { +void multipole_add(struct multipole *m_sum, const struct multipole *m_other) { -#if multipole_order == 1 +#if multipole_order != 1 +#error "Multipoles of order >1 not yet implemented." +#endif /* Correct the position. */ - float mma = ma->coeffs[0], mmb = mb->coeffs[0]; - float w = 1.0f / (mma + mmb); - for (int k = 0; k < 3; k++) ma->x[k] = (ma->x[k] * mma + mb->x[k] * mmb) * w; + const float M_tot = m_sum->mass + m_other->mass; + const float M_tot_inv = 1.f / M_tot; + for (int k = 0; k < 3; k++) + m_sum->CoM[k] = + (m_sum->CoM[k] * m_sum->mass + m_other->CoM[k] * m_other->mass) * + M_tot_inv; /* Add the particle to the moments. */ - ma->coeffs[0] = mma + mmb; - -#else -#error( "Multipoles of order %i not yet implemented." , multipole_order ) -#endif + m_sum->mass = M_tot; } /** @@ -69,19 +71,21 @@ void multipole_merge(struct multipole *ma, struct multipole *mb) { void multipole_addpart(struct multipole *m, struct gpart *p) { -#if multipole_order == 1 + /* #if multipole_order == 1 */ - /* Correct the position. */ - float mm = m->coeffs[0], mp = p->mass; - float w = 1.0f / (mm + mp); - for (int k = 0; k < 3; k++) m->x[k] = (m->x[k] * mm + p->x[k] * mp) * w; + /* /\* Correct the position. *\/ */ + /* float mm = m->coeffs[0], mp = p->mass; */ + /* float w = 1.0f / (mm + mp); */ + /* for (int k = 0; k < 3; k++) m->x[k] = (m->x[k] * mm + p->x[k] * mp) * w; + */ - /* Add the particle to the moments. */ - m->coeffs[0] = mm + mp; + /* /\* Add the particle to the moments. *\/ */ + /* m->coeffs[0] = mm + mp; */ -#else -#error( "Multipoles of order %i not yet implemented." , multipole_order ) -#endif + /* #else */ + /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + */ + /* #endif */ } /** @@ -94,76 +98,76 @@ void multipole_addpart(struct multipole *m, struct gpart *p) { void multipole_addparts(struct multipole *m, struct gpart *p, int N) { -#if multipole_order == 1 - - /* Get the combined mass and positions. */ - double xp[3] = {0.0, 0.0, 0.0}; - float mp = 0.0f, w; - for (int k = 0; k < N; k++) { - w = p[k].mass; - mp += w; - xp[0] += p[k].x[0] * w; - xp[1] += p[k].x[1] * w; - xp[2] += p[k].x[2] * w; - } - - /* Correct the position. */ - float mm = m->coeffs[0]; - w = 1.0f / (mm + mp); - for (int k = 0; k < 3; k++) m->x[k] = (m->x[k] * mm + xp[k]) * w; + /* #if multipole_order == 1 */ + + /* /\* Get the combined mass and positions. *\/ */ + /* double xp[3] = {0.0, 0.0, 0.0}; */ + /* float mp = 0.0f, w; */ + /* for (int k = 0; k < N; k++) { */ + /* w = p[k].mass; */ + /* mp += w; */ + /* xp[0] += p[k].x[0] * w; */ + /* xp[1] += p[k].x[1] * w; */ + /* xp[2] += p[k].x[2] * w; */ + /* } */ + + /* /\* Correct the position. *\/ */ + /* float mm = m->coeffs[0]; */ + /* w = 1.0f / (mm + mp); */ + /* for (int k = 0; k < 3; k++) m->x[k] = (m->x[k] * mm + xp[k]) * w; */ + + /* /\* Add the particle to the moments. *\/ */ + /* m->coeffs[0] = mm + mp; */ + + /* #else */ + /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + */ + /* #endif */ +} - /* Add the particle to the moments. */ - m->coeffs[0] = mm + mp; +/** +* @brief Reset the data of a #multipole. +* +* @param m The #multipole. +*/ +void multipole_reset(struct multipole *m) { -#else -#error( "Multipoles of order %i not yet implemented." , multipole_order ) -#endif + /* Just bzero the struct. */ + bzero(m, sizeof(struct multipole)); } /** - * @brief Init a multipole from a set of particles. - * - * @param m The #multipole. - * @param parts The #gpart. - * @param N The number of particles. - */ - -void multipole_init(struct multipole *m, struct gpart *parts, int N) { +* @brief Init a multipole from a set of particles. +* +* @param m The #multipole. +* @param parts The #gpart. +* @param N The number of particles. +*/ +void multipole_init(struct multipole *m, const struct gpart *gparts, + int gcount) { + +#if multipole_order != 1 +#error "Multipoles of order >1 not yet implemented." +#endif -#if multipole_order == 1 + /* Zero everything */ + multipole_reset(m); - float mass = 0.0f, w; + float mass = 0.0f; double x[3] = {0.0, 0.0, 0.0}; - int k; /* Collect the particle data. */ - for (k = 0; k < N; k++) { - w = parts[k].mass; + for (int k = 0; k < gcount; k++) { + const float w = gparts[k].mass; mass += w; - x[0] += parts[k].x[0] * w; - x[1] += parts[k].x[1] * w; - x[2] += parts[k].x[2] * w; + x[0] += gparts[k].x[0] * w; + x[1] += gparts[k].x[1] * w; + x[2] += gparts[k].x[2] * w; } /* Store the data on the multipole. */ - m->coeffs[0] = mass; - m->x[0] = x[0] / mass; - m->x[1] = x[1] / mass; - m->x[2] = x[2] / mass; - -#else -#error( "Multipoles of order %i not yet implemented." , multipole_order ) -#endif -} - -/** - * @brief Reset the data of a #multipole. - * - * @param m The #multipole. - */ - -void multipole_reset(struct multipole *m) { - - /* Just bzero the struct. */ - bzero(m, sizeof(struct multipole)); + m->mass = mass; + m->CoM[0] = x[0] / mass; + m->CoM[1] = x[1] / mass; + m->CoM[2] = x[2] / mass; } diff --git a/src/multipole.h b/src/multipole.h index 85ba44d3c..07e9ecbd4 100644 --- a/src/multipole.h +++ b/src/multipole.h @@ -1,6 +1,7 @@ /******************************************************************************* * This file is part of SWIFT. * Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk) + * 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -28,31 +29,33 @@ #include "kernel_gravity.h" #include "part.h" -/* Some constants. */ -#define multipole_order 1 - /* Multipole struct. */ struct multipole { /* Multipole location. */ - double x[3]; + double CoM[3]; + + /* Multipole mass */ + float mass; - /* Acceleration on this multipole. */ - float a[3]; + /* /\* Acceleration on this multipole. *\/ */ + /* float a[3]; */ - /* Multipole coefficients. */ - float coeffs[multipole_order * multipole_order]; + /* /\* Multipole coefficients. *\/ */ + /* float coeffs[multipole_order * multipole_order]; */ }; /* Multipole function prototypes. */ -static void multipole_iact_mm(struct multipole *ma, struct multipole *mb, - double *shift); -void multipole_merge(struct multipole *ma, struct multipole *mb); -void multipole_addpart(struct multipole *m, struct gpart *p); -void multipole_addparts(struct multipole *m, struct gpart *p, int N); -void multipole_init(struct multipole *m, struct gpart *parts, int N); +void multipole_add(struct multipole *m_sum, const struct multipole *m_term); +void multipole_init(struct multipole *m, const struct gpart *gparts, + int gcount); void multipole_reset(struct multipole *m); +/* static void multipole_iact_mm(struct multipole *ma, struct multipole *mb, */ +/* double *shift); */ +/* void multipole_addpart(struct multipole *m, struct gpart *p); */ +/* void multipole_addparts(struct multipole *m, struct gpart *p, int N); */ + /** * @brief Compute the pairwise interaction between two multipoles. * @@ -60,39 +63,38 @@ void multipole_reset(struct multipole *m); * @param mb The second #multipole. * @param shift The periodicity correction. */ - __attribute__((always_inline)) INLINE static void multipole_iact_mm( struct multipole *ma, struct multipole *mb, double *shift) { - - float dx[3], ir, r, r2 = 0.0f, acc; - int k; - - /* Compute the multipole distance. */ - for (k = 0; k < 3; k++) { - dx[k] = ma->x[k] - mb->x[k] - shift[k]; - r2 += dx[k] * dx[k]; - } - - /* Compute the normalized distance vector. */ - ir = 1.0f / sqrtf(r2); - r = r2 * ir; - - /* Evaluate the gravity kernel. */ - kernel_grav_eval(r, &acc); - - /* Scale the acceleration. */ - acc *= const_G * ir * ir * ir; - -/* Compute the forces on both multipoles. */ -#if multipole_order == 1 - float mma = ma->coeffs[0], mmb = mb->coeffs[0]; - for (k = 0; k < 3; k++) { - ma->a[k] -= dx[k] * acc * mmb; - mb->a[k] += dx[k] * acc * mma; - } -#else -#error( "Multipoles of order %i not yet implemented." , multipole_order ) -#endif + /* float dx[3], ir, r, r2 = 0.0f, acc; */ + /* int k; */ + + /* /\* Compute the multipole distance. *\/ */ + /* for (k = 0; k < 3; k++) { */ + /* dx[k] = ma->x[k] - mb->x[k] - shift[k]; */ + /* r2 += dx[k] * dx[k]; */ + /* } */ + + /* /\* Compute the normalized distance vector. *\/ */ + /* ir = 1.0f / sqrtf(r2); */ + /* r = r2 * ir; */ + + /* /\* Evaluate the gravity kernel. *\/ */ + /* kernel_grav_eval(r, &acc); */ + + /* /\* Scale the acceleration. *\/ */ + /* acc *= const_G * ir * ir * ir; */ + + /* /\* Compute the forces on both multipoles. *\/ */ + /* #if multipole_order == 1 */ + /* float mma = ma->coeffs[0], mmb = mb->coeffs[0]; */ + /* for (k = 0; k < 3; k++) { */ + /* ma->a[k] -= dx[k] * acc * mmb; */ + /* mb->a[k] += dx[k] * acc * mma; */ + /* } */ + /* #else */ + /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + */ + /* #endif */ } /** @@ -102,35 +104,35 @@ __attribute__((always_inline)) INLINE static void multipole_iact_mm( * @param p The #gpart. * @param shift The periodicity correction. */ - __attribute__((always_inline)) INLINE static void multipole_iact_mp( struct multipole *m, struct gpart *p, double *shift) { - float dx[3], ir, r, r2 = 0.0f, acc; - int k; + /* float dx[3], ir, r, r2 = 0.0f, acc; */ + /* int k; */ - /* Compute the multipole distance. */ - for (k = 0; k < 3; k++) { - dx[k] = m->x[k] - p->x[k] - shift[k]; - r2 += dx[k] * dx[k]; - } + /* /\* Compute the multipole distance. *\/ */ + /* for (k = 0; k < 3; k++) { */ + /* dx[k] = m->x[k] - p->x[k] - shift[k]; */ + /* r2 += dx[k] * dx[k]; */ + /* } */ - /* Compute the normalized distance vector. */ - ir = 1.0f / sqrtf(r2); - r = r2 * ir; + /* /\* Compute the normalized distance vector. *\/ */ + /* ir = 1.0f / sqrtf(r2); */ + /* r = r2 * ir; */ - /* Evaluate the gravity kernel. */ - kernel_grav_eval(r, &acc); + /* /\* Evaluate the gravity kernel. *\/ */ + /* kernel_grav_eval(r, &acc); */ - /* Scale the acceleration. */ - acc *= const_G * ir * ir * ir * m->coeffs[0]; + /* /\* Scale the acceleration. *\/ */ + /* acc *= const_G * ir * ir * ir * m->coeffs[0]; */ -/* Compute the forces on both multipoles. */ -#if multipole_order == 1 - for (k = 0; k < 3; k++) p->a_grav[k] += dx[k] * acc; -#else -#error( "Multipoles of order %i not yet implemented." , multipole_order ) -#endif + /* /\* Compute the forces on both multipoles. *\/ */ + /* #if multipole_order == 1 */ + /* for (k = 0; k < 3; k++) p->a_grav[k] += dx[k] * acc; */ + /* #else */ + /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + */ + /* #endif */ } #endif /* SWIFT_MULTIPOLE_H */ diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 19e778795..31aac5682 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -1,6 +1,7 @@ /******************************************************************************* * This file is part of SWIFT. * Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk) + * 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -39,7 +40,8 @@ /* int pid, pjd, k, sid; */ /* double rshift, shift[3] = {0.0, 0.0, 0.0}, nshift[3]; */ /* struct entry *restrict sort_i, *restrict sort_j; */ -/* struct gpart *restrict pi, *restrict pj, *restrict parts_i, *restrict parts_j; */ +/* struct gpart *restrict pi, *restrict pj, *restrict parts_i, *restrict + * parts_j; */ /* double pix[3]; */ /* float dx[3], r2, h_max, di, dj; */ /* int count_i, count_j, cnj, cnj_new; */ @@ -77,7 +79,8 @@ /* /\* Get some other useful values. *\/ */ /* h_max = */ -/* sqrtf(ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]) * */ +/* sqrtf(ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]) + * * */ /* const_theta_max; */ /* count_i = ci->gcount; */ /* count_j = cj->gcount; */ @@ -114,9 +117,12 @@ /* #ifndef VECTORIZE */ -/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */ -/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e in */ -/* // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long */ +/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 + * ) */ +/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e + * in */ +/* // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long + */ /* // long int)ci) / sizeof(struct cell) , ((long long int)cj) / */ /* // sizeof(struct cell) ); */ @@ -206,11 +212,7 @@ void runner_dograv_up(struct runner *r, struct cell *c) { - /* Re-set this cell's multipole. */ - multipole_reset(&c->multipole); - - /* Split? */ - if (c->split) { + if (c->split) {/* Regular node */ /* Recurse. */ for (int k = 0; k < 8; k++) @@ -218,17 +220,16 @@ void runner_dograv_up(struct runner *r, struct cell *c) { /* Collect the multipoles from the progeny. */ multipole_reset(&c->multipole); - for (int k = 0; k < 8; k++) + for (int k = 0; k < 8; k++) { if (c->progeny[k] != NULL) - multipole_merge(&c->multipole, &c->progeny[k]->multipole); + multipole_add(&c->multipole, &c->progeny[k]->multipole); + } - } + } else {/* Leaf node. */ - /* No, leaf node. */ - else - - /* Just collect the multipole. */ + /* Just construct the multipole from the gparts. */ multipole_init(&c->multipole, c->gparts, c->gcount); + } } /* /\** */ @@ -303,7 +304,8 @@ void runner_dograv_up(struct runner *r, struct cell *c) { /* } */ /* theta = */ /* sqrt((dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */ -/* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2])); */ +/* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * + * ci->h[2])); */ /* /\* Do an MM or an MP/PM? *\/ */ /* if (theta > const_theta_max * 4) { */ @@ -335,7 +337,8 @@ void runner_dograv_up(struct runner *r, struct cell *c) { /* struct engine *e = r->e; */ /* int pid, pjd, k, count_i = ci->gcount, count_j = cj->gcount; */ /* double shift[3] = {0.0, 0.0, 0.0}; */ -/* struct gpart *restrict parts_i = ci->gparts, *restrict parts_j = cj->gparts; */ +/* struct gpart *restrict parts_i = ci->gparts, *restrict parts_j = + * cj->gparts; */ /* struct gpart *restrict pi, *restrict pj; */ /* double pix[3]; */ /* float dx[3], r2; */ @@ -383,9 +386,12 @@ void runner_dograv_up(struct runner *r, struct cell *c) { /* /\* Compute the interaction. *\/ */ /* #ifndef VECTORIZE */ -/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */ -/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e in */ -/* // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long */ +/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 + * ) */ +/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e + * in */ +/* // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long + */ /* // long int)ci) / sizeof(struct cell) , ((long long int)cj) / */ /* // sizeof(struct cell) ); */ @@ -473,8 +479,10 @@ void runner_dograv_up(struct runner *r, struct cell *c) { /* /\* Compute the interaction. *\/ */ /* #ifndef VECTORIZE */ -/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */ -/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e." , */ +/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 + * ) */ +/* // message( "interacting particles pi=%lli and pj=%lli with + * r=%.3e." , */ /* // pi->part->id , pj->part->id , sqrtf(r2) ); */ /* runner_iact_grav(r2, dx, pi, pj); */ @@ -563,7 +571,8 @@ void runner_dograv_up(struct runner *r, struct cell *c) { /* if (dx[k] > 0.0f) dx[k] -= ci->h[k]; */ /* } */ /* theta = (dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */ -/* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]); */ +/* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * + * ci->h[2]); */ /* /\* Split the interaction? *\/ */ /* if (theta < const_theta_max * const_theta_max) { */ -- GitLab From f3cb258e88398bdec1ab64fe92fb72fbccc62cb5 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 16 May 2016 15:38:30 +0100 Subject: [PATCH 03/72] Removed all the gravity tasks apart from the 'up' ones. --- src/engine.c | 50 +- src/runner.c | 28 +- src/runner_doiact_grav.h | 1018 +++++++++++++++++++------------------- src/scheduler.c | 256 +++++----- src/space.c | 7 +- src/task.c | 38 +- src/task.h | 6 +- 7 files changed, 707 insertions(+), 696 deletions(-) diff --git a/src/engine.c b/src/engine.c index 05b0739c5..d5fe48bf1 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1340,28 +1340,31 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { void engine_make_gravityinteraction_tasks(struct engine *e) { struct space *s = e->s; - struct scheduler *sched = &e->sched; + /* struct scheduler *sched = &e->sched; */ const int nr_cells = s->nr_cells; - struct cell *cells = s->cells; + /* struct cell *cells = s->cells; */ /* Loop over all cells. */ for (int i = 0; i < nr_cells; i++) { - /* If it has gravity particles, add a self-task */ - if (cells[i].gcount > 0) { - scheduler_addtask(sched, task_type_grav_mm, task_subtype_none, -1, 0, - &cells[i], NULL, 0); - - /* Loop over all remainding cells */ - for (int j = i + 1; j < nr_cells; j++) { - - /* If that other cell has gravity parts, add a pair interaction */ - if (cells[j].gcount > 0) { - scheduler_addtask(sched, task_type_grav_mm, task_subtype_none, -1, 0, - &cells[i], &cells[j], 0); - } - } - } + /* /\* If it has gravity particles, add a self-task *\/ */ + /* if (cells[i].gcount > 0) { */ + /* scheduler_addtask(sched, task_type_grav_mm, task_subtype_none, -1, 0, + */ + /* &cells[i], NULL, 0); */ + + /* /\* Loop over all remainding cells *\/ */ + /* for (int j = i + 1; j < nr_cells; j++) { */ + + /* /\* If that other cell has gravity parts, add a pair interaction *\/ + */ + /* if (cells[j].gcount > 0) { */ + /* scheduler_addtask(sched, task_type_grav_mm, task_subtype_none, -1, + * 0, */ + /* &cells[i], &cells[j], 0); */ + /* } */ + /* } */ + /* } */ } } @@ -1390,9 +1393,12 @@ void engine_make_gravityrecursive_tasks(struct engine *e) { struct task *up = scheduler_addtask(sched, task_type_grav_up, task_subtype_none, 0, 0, &cells[k], NULL, 0); - struct task *down = - scheduler_addtask(sched, task_type_grav_down, task_subtype_none, 0, 0, - &cells[k], NULL, 0); + + struct task *down = NULL; + /* struct task *down = */ + /* scheduler_addtask(sched, task_type_grav_down, task_subtype_none, 0, + * 0, */ + /* &cells[k], NULL, 0); */ /* Push tasks down the cell hierarchy. */ engine_addtasks_grav(e, &cells[k], up, down); @@ -1428,8 +1434,8 @@ void engine_maketasks(struct engine *e) { engine_make_hydroloop_tasks(e); /* Add the gravity mm tasks. */ - if (e->policy & engine_policy_self_gravity) - engine_make_gravityinteraction_tasks(e); + /* if (e->policy & engine_policy_self_gravity) */ + /* engine_make_gravityinteraction_tasks(e); */ /* Split the tasks. */ scheduler_splittasks(sched); diff --git a/src/runner.c b/src/runner.c index 6254fcfd2..5d4808ff1 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1354,8 +1354,8 @@ void *runner_main(void *data) { runner_dosub1_density(r, ci, cj, t->flags, 1); else if (t->subtype == task_subtype_force) runner_dosub2_force(r, ci, cj, t->flags, 1); - else if (t->subtype == task_subtype_grav) - runner_dosub_grav(r, ci, cj, 1); + /* else if (t->subtype == task_subtype_grav) */ + /* runner_dosub_grav(r, ci, cj, 1); */ else error("Unknown task subtype."); break; @@ -1376,21 +1376,21 @@ void *runner_main(void *data) { case task_type_recv: runner_dorecv_cell(r, ci, 1); break; - case task_type_grav_pp: - if (t->cj == NULL) - runner_doself_grav(r, t->ci); - else - runner_dopair_grav(r, t->ci, t->cj); - break; - case task_type_grav_mm: - runner_dograv_mm(r, t->ci, t->cj); - break; + /* case task_type_grav_pp: */ + /* if (t->cj == NULL) */ + /* runner_doself_grav(r, t->ci); */ + /* else */ + /* runner_dopair_grav(r, t->ci, t->cj); */ + /* break; */ + /* case task_type_grav_mm: */ + /* runner_dograv_mm(r, t->ci, t->cj); */ + /* break; */ case task_type_grav_up: runner_dograv_up(r, t->ci); break; - case task_type_grav_down: - runner_dograv_down(r, t->ci); - break; + /* case task_type_grav_down: */ + /* runner_dograv_down(r, t->ci); */ + /* break; */ case task_type_grav_external: runner_dograv_external(r, t->ci, 1); break; diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 02626295a..19e778795 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -24,177 +24,177 @@ #include "clocks.h" #include "part.h" -/** - * @brief Compute the sorted gravity interactions between a cell pair. - * - * @param r The #runner. - * @param ci The first #cell. - * @param cj The second #cell. - */ - -void runner_dopair_grav_new(struct runner *r, struct cell *ci, - struct cell *cj) { - - struct engine *restrict e = r->e; - int pid, pjd, k, sid; - double rshift, shift[3] = {0.0, 0.0, 0.0}, nshift[3]; - struct entry *restrict sort_i, *restrict sort_j; - struct gpart *restrict pi, *restrict pj, *restrict parts_i, *restrict parts_j; - double pix[3]; - float dx[3], r2, h_max, di, dj; - int count_i, count_j, cnj, cnj_new; - const int ti_current = e->ti_current; - struct multipole m; -#ifdef VECTORIZE - int icount = 0; - float r2q[VEC_SIZE] __attribute__((aligned(16))); - float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); - struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; -#endif - TIMER_TIC - - /* Anything to do here? */ - if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; - - /* Get the sort ID. */ - sid = space_getsid(e->s, &ci, &cj, shift); - - /* Make sure the cells are sorted. */ - runner_dogsort(r, ci, (1 << sid), 0); - runner_dogsort(r, cj, (1 << sid), 0); - - /* Have the cells been sorted? */ - if (!(ci->gsorted & (1 << sid)) || !(cj->gsorted & (1 << sid))) - error("Trying to interact unsorted cells."); - - /* Get the cutoff shift. */ - for (rshift = 0.0, k = 0; k < 3; k++) - rshift += shift[k] * runner_shift[3 * sid + k]; - - /* Pick-out the sorted lists. */ - sort_i = &ci->gsort[sid * (ci->count + 1)]; - sort_j = &cj->gsort[sid * (cj->count + 1)]; - - /* Get some other useful values. */ - h_max = - sqrtf(ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]) * - const_theta_max; - count_i = ci->gcount; - count_j = cj->gcount; - parts_i = ci->gparts; - parts_j = cj->gparts; - cnj = count_j; - multipole_reset(&m); - nshift[0] = -shift[0]; - nshift[1] = -shift[1]; - nshift[2] = -shift[2]; - - /* Loop over the parts in ci. */ - for (pid = count_i - 1; pid >= 0; pid--) { - - /* Get a hold of the ith part in ci. */ - pi = &parts_i[sort_i[pid].i]; - if (pi->ti_end > ti_current) continue; - di = sort_i[pid].d + h_max - rshift; - - for (k = 0; k < 3; k++) pix[k] = pi->x[k] - shift[k]; - - /* Loop over the parts in cj. */ - for (pjd = 0; pjd < cnj && sort_j[pjd].d < di; pjd++) { - - /* Get a pointer to the jth particle. */ - pj = &parts_j[sort_j[pjd].i]; - - /* Compute the pairwise distance. */ - r2 = 0.0f; - for (k = 0; k < 3; k++) { - dx[k] = pix[k] - pj->x[k]; - r2 += dx[k] * dx[k]; - } - -#ifndef VECTORIZE - - // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) - // message( "interacting particles pi=%lli and pj=%lli with r=%.3e in - // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long - // long int)ci) / sizeof(struct cell) , ((long long int)cj) / - // sizeof(struct cell) ); +/* /\** */ +/* * @brief Compute the sorted gravity interactions between a cell pair. */ +/* * */ +/* * @param r The #runner. */ +/* * @param ci The first #cell. */ +/* * @param cj The second #cell. */ +/* *\/ */ + +/* void runner_dopair_grav_new(struct runner *r, struct cell *ci, */ +/* struct cell *cj) { */ + +/* struct engine *restrict e = r->e; */ +/* int pid, pjd, k, sid; */ +/* double rshift, shift[3] = {0.0, 0.0, 0.0}, nshift[3]; */ +/* struct entry *restrict sort_i, *restrict sort_j; */ +/* struct gpart *restrict pi, *restrict pj, *restrict parts_i, *restrict parts_j; */ +/* double pix[3]; */ +/* float dx[3], r2, h_max, di, dj; */ +/* int count_i, count_j, cnj, cnj_new; */ +/* const int ti_current = e->ti_current; */ +/* struct multipole m; */ +/* #ifdef VECTORIZE */ +/* int icount = 0; */ +/* float r2q[VEC_SIZE] __attribute__((aligned(16))); */ +/* float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); */ +/* struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; */ +/* #endif */ +/* TIMER_TIC */ + +/* /\* Anything to do here? *\/ */ +/* if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; */ + +/* /\* Get the sort ID. *\/ */ +/* sid = space_getsid(e->s, &ci, &cj, shift); */ + +/* /\* Make sure the cells are sorted. *\/ */ +/* runner_dogsort(r, ci, (1 << sid), 0); */ +/* runner_dogsort(r, cj, (1 << sid), 0); */ + +/* /\* Have the cells been sorted? *\/ */ +/* if (!(ci->gsorted & (1 << sid)) || !(cj->gsorted & (1 << sid))) */ +/* error("Trying to interact unsorted cells."); */ + +/* /\* Get the cutoff shift. *\/ */ +/* for (rshift = 0.0, k = 0; k < 3; k++) */ +/* rshift += shift[k] * runner_shift[3 * sid + k]; */ + +/* /\* Pick-out the sorted lists. *\/ */ +/* sort_i = &ci->gsort[sid * (ci->count + 1)]; */ +/* sort_j = &cj->gsort[sid * (cj->count + 1)]; */ + +/* /\* Get some other useful values. *\/ */ +/* h_max = */ +/* sqrtf(ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]) * */ +/* const_theta_max; */ +/* count_i = ci->gcount; */ +/* count_j = cj->gcount; */ +/* parts_i = ci->gparts; */ +/* parts_j = cj->gparts; */ +/* cnj = count_j; */ +/* multipole_reset(&m); */ +/* nshift[0] = -shift[0]; */ +/* nshift[1] = -shift[1]; */ +/* nshift[2] = -shift[2]; */ + +/* /\* Loop over the parts in ci. *\/ */ +/* for (pid = count_i - 1; pid >= 0; pid--) { */ + +/* /\* Get a hold of the ith part in ci. *\/ */ +/* pi = &parts_i[sort_i[pid].i]; */ +/* if (pi->ti_end > ti_current) continue; */ +/* di = sort_i[pid].d + h_max - rshift; */ + +/* for (k = 0; k < 3; k++) pix[k] = pi->x[k] - shift[k]; */ + +/* /\* Loop over the parts in cj. *\/ */ +/* for (pjd = 0; pjd < cnj && sort_j[pjd].d < di; pjd++) { */ + +/* /\* Get a pointer to the jth particle. *\/ */ +/* pj = &parts_j[sort_j[pjd].i]; */ + +/* /\* Compute the pairwise distance. *\/ */ +/* r2 = 0.0f; */ +/* for (k = 0; k < 3; k++) { */ +/* dx[k] = pix[k] - pj->x[k]; */ +/* r2 += dx[k] * dx[k]; */ +/* } */ + +/* #ifndef VECTORIZE */ + +/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */ +/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e in */ +/* // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long */ +/* // long int)ci) / sizeof(struct cell) , ((long long int)cj) / */ +/* // sizeof(struct cell) ); */ + +/* runner_iact_grav(r2, dx, pi, pj); */ + +/* #else */ + +/* /\* Add this interaction to the queue. *\/ */ +/* r2q[icount] = r2; */ +/* dxq[3 * icount + 0] = dx[0]; */ +/* dxq[3 * icount + 1] = dx[1]; */ +/* dxq[3 * icount + 2] = dx[2]; */ +/* piq[icount] = pi; */ +/* pjq[icount] = pj; */ +/* icount += 1; */ + +/* /\* Flush? *\/ */ +/* if (icount == VEC_SIZE) { */ +/* runner_iact_vec_grav(r2q, dxq, piq, pjq); */ +/* icount = 0; */ +/* } */ - runner_iact_grav(r2, dx, pi, pj); +/* #endif */ -#else +/* } /\* loop over the parts in cj. *\/ */ - /* Add this interaction to the queue. */ - r2q[icount] = r2; - dxq[3 * icount + 0] = dx[0]; - dxq[3 * icount + 1] = dx[1]; - dxq[3 * icount + 2] = dx[2]; - piq[icount] = pi; - pjq[icount] = pj; - icount += 1; - - /* Flush? */ - if (icount == VEC_SIZE) { - runner_iact_vec_grav(r2q, dxq, piq, pjq); - icount = 0; - } - -#endif +/* /\* Set the new limit. *\/ */ +/* cnj_new = pjd; */ - } /* loop over the parts in cj. */ +/* /\* Add trailing parts to the multipole. *\/ */ +/* for (pjd = cnj_new; pjd < cnj; pjd++) { */ - /* Set the new limit. */ - cnj_new = pjd; +/* /\* Add the part to the multipole. *\/ */ +/* multipole_addpart(&m, &parts_j[sort_j[pjd].i]); */ - /* Add trailing parts to the multipole. */ - for (pjd = cnj_new; pjd < cnj; pjd++) { +/* } /\* add trailing parts to the multipole. *\/ */ - /* Add the part to the multipole. */ - multipole_addpart(&m, &parts_j[sort_j[pjd].i]); +/* /\* Set the new cnj. *\/ */ +/* cnj = cnj_new; */ - } /* add trailing parts to the multipole. */ +/* /\* Interact the ith particle with the multipole. *\/ */ +/* multipole_iact_mp(&m, pi, nshift); */ - /* Set the new cnj. */ - cnj = cnj_new; +/* } /\* loop over the parts in ci. *\/ */ - /* Interact the ith particle with the multipole. */ - multipole_iact_mp(&m, pi, nshift); +/* #ifdef VECTORIZE */ +/* /\* Pick up any leftovers. *\/ */ +/* if (icount > 0) */ +/* for (k = 0; k < icount; k++) */ +/* runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); */ +/* #endif */ - } /* loop over the parts in ci. */ +/* /\* Re-set the multipole. *\/ */ +/* multipole_reset(&m); */ -#ifdef VECTORIZE - /* Pick up any leftovers. */ - if (icount > 0) - for (k = 0; k < icount; k++) - runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); -#endif +/* /\* Loop over the parts in cj and interact with the multipole in ci. *\/ */ +/* for (pid = count_i - 1, pjd = 0; pjd < count_j; pjd++) { */ - /* Re-set the multipole. */ - multipole_reset(&m); +/* /\* Get the position of pj along the axis. *\/ */ +/* dj = sort_j[pjd].d - h_max + rshift; */ - /* Loop over the parts in cj and interact with the multipole in ci. */ - for (pid = count_i - 1, pjd = 0; pjd < count_j; pjd++) { +/* /\* Add any left-over parts in cell_i to the multipole. *\/ */ +/* while (pid >= 0 && sort_i[pid].d < dj) { */ - /* Get the position of pj along the axis. */ - dj = sort_j[pjd].d - h_max + rshift; +/* /\* Add this particle to the multipole. *\/ */ +/* multipole_addpart(&m, &parts_i[sort_i[pid].i]); */ - /* Add any left-over parts in cell_i to the multipole. */ - while (pid >= 0 && sort_i[pid].d < dj) { +/* /\* Decrease pid. *\/ */ +/* pid -= 1; */ +/* } */ - /* Add this particle to the multipole. */ - multipole_addpart(&m, &parts_i[sort_i[pid].i]); +/* /\* Interact pj with the multipole. *\/ */ +/* multipole_iact_mp(&m, &parts_j[sort_j[pjd].i], shift); */ - /* Decrease pid. */ - pid -= 1; - } +/* } /\* loop over the parts in cj and interact with the multipole. *\/ */ - /* Interact pj with the multipole. */ - multipole_iact_mp(&m, &parts_j[sort_j[pjd].i], shift); - - } /* loop over the parts in cj and interact with the multipole. */ - - TIMER_TOC(TIMER_DOPAIR); -} +/* TIMER_TOC(TIMER_DOPAIR); */ +/* } */ /** * @brief Compute the recursive upward sweep, i.e. construct the @@ -231,367 +231,367 @@ void runner_dograv_up(struct runner *r, struct cell *c) { multipole_init(&c->multipole, c->gparts, c->gcount); } -/** - * @brief Compute the recursive downward sweep, i.e. apply the multipole - * acceleration on all the particles. - * - * @param r The #runner. - * @param c The top-level #cell. - */ - -void runner_dograv_down(struct runner *r, struct cell *c) { - - struct multipole *m = &c->multipole; +/* /\** */ +/* * @brief Compute the recursive downward sweep, i.e. apply the multipole */ +/* * acceleration on all the particles. */ +/* * */ +/* * @param r The #runner. */ +/* * @param c The top-level #cell. */ +/* *\/ */ + +/* void runner_dograv_down(struct runner *r, struct cell *c) { */ + +/* struct multipole *m = &c->multipole; */ + +/* /\* Split? *\/ */ +/* if (c->split) { */ + +/* /\* Apply this cell's acceleration on the multipoles below. *\/ */ +/* for (int k = 0; k < 8; k++) */ +/* if (c->progeny[k] != NULL) { */ +/* struct multipole *mp = &c->progeny[k]->multipole; */ +/* mp->a[0] += m->a[0]; */ +/* mp->a[1] += m->a[1]; */ +/* mp->a[2] += m->a[2]; */ +/* } */ + +/* /\* Recurse. *\/ */ +/* for (int k = 0; k < 8; k++) */ +/* if (c->progeny[k] != NULL) runner_dograv_down(r, c->progeny[k]); */ + +/* } */ + +/* /\* No, leaf node. *\/ */ +/* else { */ + +/* /\* Apply the multipole acceleration to all gparts. *\/ */ +/* for (int k = 0; k < c->gcount; k++) { */ +/* struct gpart *p = &c->gparts[k]; */ +/* p->a_grav[0] += m->a[0]; */ +/* p->a_grav[1] += m->a[1]; */ +/* p->a_grav[2] += m->a[2]; */ +/* } */ +/* } */ +/* } */ + +/* /\** */ +/* * @brief Compute the multipole-multipole interaction between two cells. */ +/* * */ +/* * @param r The #runner. */ +/* * @param ci The first #cell. */ +/* * @param cj The second #cell. */ +/* *\/ */ + +/* void runner_dograv_mm(struct runner *r, struct cell *restrict ci, */ +/* struct cell *restrict cj) { */ + +/* struct engine *e = r->e; */ +/* int k; */ +/* double shift[3] = {0.0, 0.0, 0.0}; */ +/* float dx[3], theta; */ + +/* /\* Compute the shift between the cells. *\/ */ +/* for (k = 0; k < 3; k++) { */ +/* dx[k] = cj->loc[k] - ci->loc[k]; */ +/* if (r->e->s->periodic) { */ +/* if (dx[k] < -e->s->dim[k] / 2) */ +/* shift[k] = e->s->dim[k]; */ +/* else if (dx[k] > e->s->dim[k] / 2) */ +/* shift[k] = -e->s->dim[k]; */ +/* dx[k] += shift[k]; */ +/* } */ +/* } */ +/* theta = */ +/* sqrt((dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */ +/* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2])); */ + +/* /\* Do an MM or an MP/PM? *\/ */ +/* if (theta > const_theta_max * 4) { */ + +/* /\* Update the multipoles. *\/ */ +/* multipole_iact_mm(&ci->multipole, &cj->multipole, shift); */ + +/* } else { */ + +/* /\* Interact the multipoles via their parts. *\/ */ +/* for (k = 0; k < ci->gcount; k++) */ +/* multipole_iact_mp(&cj->multipole, &ci->gparts[k], shift); */ +/* for (k = 0; k < cj->gcount; k++) */ +/* multipole_iact_mp(&ci->multipole, &cj->gparts[k], shift); */ +/* } */ +/* } */ + +/* /\** */ +/* * @brief Compute the interactions between a cell pair. */ +/* * */ +/* * @param r The #runner. */ +/* * @param ci The first #cell. */ +/* * @param cj The second #cell. */ +/* *\/ */ + +/* void runner_dopair_grav(struct runner *r, struct cell *restrict ci, */ +/* struct cell *restrict cj) { */ + +/* struct engine *e = r->e; */ +/* int pid, pjd, k, count_i = ci->gcount, count_j = cj->gcount; */ +/* double shift[3] = {0.0, 0.0, 0.0}; */ +/* struct gpart *restrict parts_i = ci->gparts, *restrict parts_j = cj->gparts; */ +/* struct gpart *restrict pi, *restrict pj; */ +/* double pix[3]; */ +/* float dx[3], r2; */ +/* const int ti_current = r->e->ti_current; */ +/* #ifdef VECTORIZE */ +/* int icount = 0; */ +/* float r2q[VEC_SIZE] __attribute__((aligned(16))); */ +/* float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); */ +/* struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; */ +/* #endif */ +/* TIMER_TIC */ + +/* /\* Anything to do here? *\/ */ +/* if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; */ + +/* /\* Get the relative distance between the pairs, wrapping. *\/ */ +/* if (e->s->periodic) */ +/* for (k = 0; k < 3; k++) { */ +/* if (cj->loc[k] - ci->loc[k] < -e->s->dim[k] / 2) */ +/* shift[k] = e->s->dim[k]; */ +/* else if (cj->loc[k] - ci->loc[k] > e->s->dim[k] / 2) */ +/* shift[k] = -e->s->dim[k]; */ +/* } */ + +/* /\* Loop over the parts in ci. *\/ */ +/* for (pid = 0; pid < count_i; pid++) { */ + +/* /\* Get a hold of the ith part in ci. *\/ */ +/* pi = &parts_i[pid]; */ +/* for (k = 0; k < 3; k++) pix[k] = pi->x[k] - shift[k]; */ + +/* /\* Loop over the parts in cj. *\/ */ +/* for (pjd = 0; pjd < count_j; pjd++) { */ + +/* /\* Get a pointer to the jth particle. *\/ */ +/* pj = &parts_j[pjd]; */ + +/* /\* Compute the pairwise distance. *\/ */ +/* r2 = 0.0f; */ +/* for (k = 0; k < 3; k++) { */ +/* dx[k] = pix[k] - pj->x[k]; */ +/* r2 += dx[k] * dx[k]; */ +/* } */ + +/* /\* Compute the interaction. *\/ */ +/* #ifndef VECTORIZE */ + +/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */ +/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e in */ +/* // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long */ +/* // long int)ci) / sizeof(struct cell) , ((long long int)cj) / */ +/* // sizeof(struct cell) ); */ + +/* runner_iact_grav(r2, dx, pi, pj); */ + +/* #else */ + +/* /\* Add this interaction to the queue. *\/ */ +/* r2q[icount] = r2; */ +/* dxq[3 * icount + 0] = dx[0]; */ +/* dxq[3 * icount + 1] = dx[1]; */ +/* dxq[3 * icount + 2] = dx[2]; */ +/* piq[icount] = pi; */ +/* pjq[icount] = pj; */ +/* icount += 1; */ + +/* /\* Flush? *\/ */ +/* if (icount == VEC_SIZE) { */ +/* runner_iact_vec_grav(r2q, dxq, piq, pjq); */ +/* icount = 0; */ +/* } */ + +/* #endif */ + +/* } /\* loop over the parts in cj. *\/ */ + +/* } /\* loop over the parts in ci. *\/ */ + +/* #ifdef VECTORIZE */ +/* /\* Pick up any leftovers. *\/ */ +/* if (icount > 0) */ +/* for (k = 0; k < icount; k++) */ +/* runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); */ +/* #endif */ + +/* TIMER_TOC(timer_dopair_grav); */ +/* } */ + +/* /\** */ +/* * @brief Compute the interactions within a cell. */ +/* * */ +/* * @param r The #runner. */ +/* * @param c The #cell. */ +/* *\/ */ + +/* void runner_doself_grav(struct runner *r, struct cell *restrict c) { */ + +/* int pid, pjd, k, count = c->gcount; */ +/* struct gpart *restrict parts = c->gparts; */ +/* struct gpart *restrict pi, *restrict pj; */ +/* double pix[3] = {0.0, 0.0, 0.0}; */ +/* float dx[3], r2; */ +/* const int ti_current = r->e->ti_current; */ +/* #ifdef VECTORIZE */ +/* int icount = 0; */ +/* float r2q[VEC_SIZE] __attribute__((aligned(16))); */ +/* float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); */ +/* struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; */ +/* #endif */ +/* TIMER_TIC */ + +/* /\* Anything to do here? *\/ */ +/* if (c->ti_end_min > ti_current) return; */ + +/* /\* Loop over every part in c. *\/ */ +/* for (pid = 0; pid < count; pid++) { */ + +/* /\* Get a hold of the ith part in ci. *\/ */ +/* pi = &parts[pid]; */ +/* for (k = 0; k < 3; k++) pix[k] = pi->x[k]; */ + +/* /\* Loop over every other part in c. *\/ */ +/* for (pjd = pid + 1; pjd < count; pjd++) { */ + +/* /\* Get a pointer to the jth particle. *\/ */ +/* pj = &parts[pjd]; */ + +/* /\* Compute the pairwise distance. *\/ */ +/* r2 = 0.0f; */ +/* for (k = 0; k < 3; k++) { */ +/* dx[k] = pix[k] - pj->x[k]; */ +/* r2 += dx[k] * dx[k]; */ +/* } */ + +/* /\* Compute the interaction. *\/ */ +/* #ifndef VECTORIZE */ + +/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */ +/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e." , */ +/* // pi->part->id , pj->part->id , sqrtf(r2) ); */ + +/* runner_iact_grav(r2, dx, pi, pj); */ + +/* #else */ + +/* /\* Add this interaction to the queue. *\/ */ +/* r2q[icount] = r2; */ +/* dxq[3 * icount + 0] = dx[0]; */ +/* dxq[3 * icount + 1] = dx[1]; */ +/* dxq[3 * icount + 2] = dx[2]; */ +/* piq[icount] = pi; */ +/* pjq[icount] = pj; */ +/* icount += 1; */ + +/* /\* Flush? *\/ */ +/* if (icount == VEC_SIZE) { */ +/* runner_iact_vec_grav(r2q, dxq, piq, pjq); */ +/* icount = 0; */ +/* } */ + +/* #endif */ + +/* } /\* loop over the remaining parts in c. *\/ */ + +/* } /\* loop over the parts in c. *\/ */ + +/* #ifdef VECTORIZE */ +/* /\* Pick up any leftovers. *\/ */ +/* if (icount > 0) */ +/* for (k = 0; k < icount; k++) */ +/* runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); */ +/* #endif */ + +/* TIMER_TOC(timer_doself_grav); */ +/* } */ + +/* /\** */ +/* * @brief Compute a gravity sub-task. */ +/* * */ +/* * @param r The #runner. */ +/* * @param ci The first #cell. */ +/* * @param cj The second #cell. */ +/* * @param gettimer Flag to record timer or not. */ +/* *\/ */ + +/* void runner_dosub_grav(struct runner *r, struct cell *ci, struct cell *cj, */ +/* int gettimer) { */ + +/* int j, k, periodic = r->e->s->periodic; */ +/* struct space *s = r->e->s; */ + +/* TIMER_TIC */ + +/* /\* Self-interaction? *\/ */ +/* if (cj == NULL) { */ + +/* /\* If the cell is split, recurse. *\/ */ +/* if (ci->split) { */ + +/* /\* Split this task into tasks on its progeny. *\/ */ +/* for (j = 0; j < 8; j++) */ +/* if (ci->progeny[j] != NULL) { */ +/* runner_dosub_grav(r, ci->progeny[j], NULL, 0); */ +/* for (k = j + 1; k < 8; k++) */ +/* if (ci->progeny[k] != NULL) */ +/* runner_dosub_grav(r, ci->progeny[j], ci->progeny[k], 0); */ +/* } */ - /* Split? */ - if (c->split) { +/* } */ - /* Apply this cell's acceleration on the multipoles below. */ - for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) { - struct multipole *mp = &c->progeny[k]->multipole; - mp->a[0] += m->a[0]; - mp->a[1] += m->a[1]; - mp->a[2] += m->a[2]; - } +/* /\* Otherwise, just make a pp task out of it. *\/ */ +/* else */ +/* runner_doself_grav(r, ci); */ - /* Recurse. */ - for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) runner_dograv_down(r, c->progeny[k]); +/* } */ - } +/* /\* Nope, pair. *\/ */ +/* else { */ + +/* /\* Get the opening angle theta. *\/ */ +/* float dx[3], theta; */ +/* for (k = 0; k < 3; k++) { */ +/* dx[k] = fabs(ci->loc[k] - cj->loc[k]); */ +/* if (periodic && dx[k] > 0.5 * s->dim[k]) dx[k] = -dx[k] + s->dim[k]; */ +/* if (dx[k] > 0.0f) dx[k] -= ci->h[k]; */ +/* } */ +/* theta = (dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */ +/* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]); */ + +/* /\* Split the interaction? *\/ */ +/* if (theta < const_theta_max * const_theta_max) { */ - /* No, leaf node. */ - else { - - /* Apply the multipole acceleration to all gparts. */ - for (int k = 0; k < c->gcount; k++) { - struct gpart *p = &c->gparts[k]; - p->a_grav[0] += m->a[0]; - p->a_grav[1] += m->a[1]; - p->a_grav[2] += m->a[2]; - } - } -} +/* /\* Are both ci and cj split? *\/ */ +/* if (ci->split && cj->split) { */ + +/* /\* Split this task into tasks on its progeny. *\/ */ +/* for (j = 0; j < 8; j++) */ +/* if (ci->progeny[j] != NULL) { */ +/* for (k = 0; k < 8; k++) */ +/* if (cj->progeny[k] != NULL) */ +/* runner_dosub_grav(r, ci->progeny[j], cj->progeny[k], 0); */ +/* } */ + +/* } */ + +/* /\* Otherwise, make a pp task out of it. *\/ */ +/* else */ +/* runner_dopair_grav(r, ci, cj); */ + +/* } */ + +/* /\* Otherwise, mm interaction is fine. *\/ */ +/* else */ +/* runner_dograv_mm(r, ci, cj); */ +/* } */ -/** - * @brief Compute the multipole-multipole interaction between two cells. - * - * @param r The #runner. - * @param ci The first #cell. - * @param cj The second #cell. - */ - -void runner_dograv_mm(struct runner *r, struct cell *restrict ci, - struct cell *restrict cj) { - - struct engine *e = r->e; - int k; - double shift[3] = {0.0, 0.0, 0.0}; - float dx[3], theta; - - /* Compute the shift between the cells. */ - for (k = 0; k < 3; k++) { - dx[k] = cj->loc[k] - ci->loc[k]; - if (r->e->s->periodic) { - if (dx[k] < -e->s->dim[k] / 2) - shift[k] = e->s->dim[k]; - else if (dx[k] > e->s->dim[k] / 2) - shift[k] = -e->s->dim[k]; - dx[k] += shift[k]; - } - } - theta = - sqrt((dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / - (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2])); - - /* Do an MM or an MP/PM? */ - if (theta > const_theta_max * 4) { - - /* Update the multipoles. */ - multipole_iact_mm(&ci->multipole, &cj->multipole, shift); - - } else { - - /* Interact the multipoles via their parts. */ - for (k = 0; k < ci->gcount; k++) - multipole_iact_mp(&cj->multipole, &ci->gparts[k], shift); - for (k = 0; k < cj->gcount; k++) - multipole_iact_mp(&ci->multipole, &cj->gparts[k], shift); - } -} - -/** - * @brief Compute the interactions between a cell pair. - * - * @param r The #runner. - * @param ci The first #cell. - * @param cj The second #cell. - */ - -void runner_dopair_grav(struct runner *r, struct cell *restrict ci, - struct cell *restrict cj) { - - struct engine *e = r->e; - int pid, pjd, k, count_i = ci->gcount, count_j = cj->gcount; - double shift[3] = {0.0, 0.0, 0.0}; - struct gpart *restrict parts_i = ci->gparts, *restrict parts_j = cj->gparts; - struct gpart *restrict pi, *restrict pj; - double pix[3]; - float dx[3], r2; - const int ti_current = r->e->ti_current; -#ifdef VECTORIZE - int icount = 0; - float r2q[VEC_SIZE] __attribute__((aligned(16))); - float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); - struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; -#endif - TIMER_TIC - - /* Anything to do here? */ - if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; - - /* Get the relative distance between the pairs, wrapping. */ - if (e->s->periodic) - for (k = 0; k < 3; k++) { - if (cj->loc[k] - ci->loc[k] < -e->s->dim[k] / 2) - shift[k] = e->s->dim[k]; - else if (cj->loc[k] - ci->loc[k] > e->s->dim[k] / 2) - shift[k] = -e->s->dim[k]; - } - - /* Loop over the parts in ci. */ - for (pid = 0; pid < count_i; pid++) { - - /* Get a hold of the ith part in ci. */ - pi = &parts_i[pid]; - for (k = 0; k < 3; k++) pix[k] = pi->x[k] - shift[k]; - - /* Loop over the parts in cj. */ - for (pjd = 0; pjd < count_j; pjd++) { - - /* Get a pointer to the jth particle. */ - pj = &parts_j[pjd]; - - /* Compute the pairwise distance. */ - r2 = 0.0f; - for (k = 0; k < 3; k++) { - dx[k] = pix[k] - pj->x[k]; - r2 += dx[k] * dx[k]; - } - -/* Compute the interaction. */ -#ifndef VECTORIZE - - // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) - // message( "interacting particles pi=%lli and pj=%lli with r=%.3e in - // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long - // long int)ci) / sizeof(struct cell) , ((long long int)cj) / - // sizeof(struct cell) ); - - runner_iact_grav(r2, dx, pi, pj); - -#else - - /* Add this interaction to the queue. */ - r2q[icount] = r2; - dxq[3 * icount + 0] = dx[0]; - dxq[3 * icount + 1] = dx[1]; - dxq[3 * icount + 2] = dx[2]; - piq[icount] = pi; - pjq[icount] = pj; - icount += 1; - - /* Flush? */ - if (icount == VEC_SIZE) { - runner_iact_vec_grav(r2q, dxq, piq, pjq); - icount = 0; - } - -#endif - - } /* loop over the parts in cj. */ - - } /* loop over the parts in ci. */ - -#ifdef VECTORIZE - /* Pick up any leftovers. */ - if (icount > 0) - for (k = 0; k < icount; k++) - runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); -#endif - - TIMER_TOC(timer_dopair_grav); -} - -/** - * @brief Compute the interactions within a cell. - * - * @param r The #runner. - * @param c The #cell. - */ - -void runner_doself_grav(struct runner *r, struct cell *restrict c) { - - int pid, pjd, k, count = c->gcount; - struct gpart *restrict parts = c->gparts; - struct gpart *restrict pi, *restrict pj; - double pix[3] = {0.0, 0.0, 0.0}; - float dx[3], r2; - const int ti_current = r->e->ti_current; -#ifdef VECTORIZE - int icount = 0; - float r2q[VEC_SIZE] __attribute__((aligned(16))); - float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); - struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; -#endif - TIMER_TIC - - /* Anything to do here? */ - if (c->ti_end_min > ti_current) return; - - /* Loop over every part in c. */ - for (pid = 0; pid < count; pid++) { - - /* Get a hold of the ith part in ci. */ - pi = &parts[pid]; - for (k = 0; k < 3; k++) pix[k] = pi->x[k]; - - /* Loop over every other part in c. */ - for (pjd = pid + 1; pjd < count; pjd++) { - - /* Get a pointer to the jth particle. */ - pj = &parts[pjd]; - - /* Compute the pairwise distance. */ - r2 = 0.0f; - for (k = 0; k < 3; k++) { - dx[k] = pix[k] - pj->x[k]; - r2 += dx[k] * dx[k]; - } - -/* Compute the interaction. */ -#ifndef VECTORIZE - - // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) - // message( "interacting particles pi=%lli and pj=%lli with r=%.3e." , - // pi->part->id , pj->part->id , sqrtf(r2) ); - - runner_iact_grav(r2, dx, pi, pj); - -#else - - /* Add this interaction to the queue. */ - r2q[icount] = r2; - dxq[3 * icount + 0] = dx[0]; - dxq[3 * icount + 1] = dx[1]; - dxq[3 * icount + 2] = dx[2]; - piq[icount] = pi; - pjq[icount] = pj; - icount += 1; - - /* Flush? */ - if (icount == VEC_SIZE) { - runner_iact_vec_grav(r2q, dxq, piq, pjq); - icount = 0; - } - -#endif - - } /* loop over the remaining parts in c. */ - - } /* loop over the parts in c. */ - -#ifdef VECTORIZE - /* Pick up any leftovers. */ - if (icount > 0) - for (k = 0; k < icount; k++) - runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); -#endif - - TIMER_TOC(timer_doself_grav); -} - -/** - * @brief Compute a gravity sub-task. - * - * @param r The #runner. - * @param ci The first #cell. - * @param cj The second #cell. - * @param gettimer Flag to record timer or not. - */ - -void runner_dosub_grav(struct runner *r, struct cell *ci, struct cell *cj, - int gettimer) { - - int j, k, periodic = r->e->s->periodic; - struct space *s = r->e->s; - - TIMER_TIC - - /* Self-interaction? */ - if (cj == NULL) { - - /* If the cell is split, recurse. */ - if (ci->split) { - - /* Split this task into tasks on its progeny. */ - for (j = 0; j < 8; j++) - if (ci->progeny[j] != NULL) { - runner_dosub_grav(r, ci->progeny[j], NULL, 0); - for (k = j + 1; k < 8; k++) - if (ci->progeny[k] != NULL) - runner_dosub_grav(r, ci->progeny[j], ci->progeny[k], 0); - } - - } - - /* Otherwise, just make a pp task out of it. */ - else - runner_doself_grav(r, ci); - - } - - /* Nope, pair. */ - else { - - /* Get the opening angle theta. */ - float dx[3], theta; - for (k = 0; k < 3; k++) { - dx[k] = fabs(ci->loc[k] - cj->loc[k]); - if (periodic && dx[k] > 0.5 * s->dim[k]) dx[k] = -dx[k] + s->dim[k]; - if (dx[k] > 0.0f) dx[k] -= ci->h[k]; - } - theta = (dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / - (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]); - - /* Split the interaction? */ - if (theta < const_theta_max * const_theta_max) { - - /* Are both ci and cj split? */ - if (ci->split && cj->split) { - - /* Split this task into tasks on its progeny. */ - for (j = 0; j < 8; j++) - if (ci->progeny[j] != NULL) { - for (k = 0; k < 8; k++) - if (cj->progeny[k] != NULL) - runner_dosub_grav(r, ci->progeny[j], cj->progeny[k], 0); - } - - } - - /* Otherwise, make a pp task out of it. */ - else - runner_dopair_grav(r, ci, cj); - - } - - /* Otherwise, mm interaction is fine. */ - else - runner_dograv_mm(r, ci, cj); - } - - if (gettimer) TIMER_TOC(timer_dosub_grav); -} +/* if (gettimer) TIMER_TOC(timer_dosub_grav); */ +/* } */ #endif /* SWIFT_RUNNER_DOIACT_GRAV_H */ diff --git a/src/scheduler.c b/src/scheduler.c index d1d343240..887e8d54f 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -518,130 +518,138 @@ void scheduler_splittasks(struct scheduler *s) { } /* pair interaction? */ /* Gravity interaction? */ - else if (t->type == task_type_grav_mm) { - - /* Get a handle on the cells involved. */ - struct cell *ci = t->ci; - struct cell *cj = t->cj; - - /* Self-interaction? */ - if (cj == NULL) { - - /* Ignore this task if the cell has no gparts. */ - if (ci->gcount == 0) t->type = task_type_none; - - /* If the cell is split, recurse. */ - else if (ci->split) { - - /* Make a single sub-task? */ - if (scheduler_dosub && ci->gcount < space_subsize / ci->gcount) { - - t->type = task_type_sub; - t->subtype = task_subtype_grav; - - } - - /* Otherwise, just split the task. */ - else { - - /* Split this task into tasks on its progeny. */ - t->type = task_type_none; - for (int j = 0; j < 8; j++) - if (ci->progeny[j] != NULL && ci->progeny[j]->gcount > 0) { - if (t->type == task_type_none) { - t->type = task_type_grav_mm; - t->ci = ci->progeny[j]; - t->cj = NULL; - } else - t = scheduler_addtask(s, task_type_grav_mm, task_subtype_none, - 0, 0, ci->progeny[j], NULL, 0); - for (int k = j + 1; k < 8; k++) - if (ci->progeny[k] != NULL && ci->progeny[k]->gcount > 0) { - if (t->type == task_type_none) { - t->type = task_type_grav_mm; - t->ci = ci->progeny[j]; - t->cj = ci->progeny[k]; - } else - t = scheduler_addtask(s, task_type_grav_mm, - task_subtype_none, 0, 0, - ci->progeny[j], ci->progeny[k], 0); - } - } - redo = (t->type != task_type_none); - } - - } - - /* Otherwise, just make a pp task out of it. */ - else - t->type = task_type_grav_pp; - - } - - /* Nope, pair. */ - else { - - /* Make a sub-task? */ - if (scheduler_dosub && ci->gcount < space_subsize / cj->gcount) { - - t->type = task_type_sub; - t->subtype = task_subtype_grav; - - } - - /* Otherwise, split the task. */ - else { - - /* Get the opening angle theta. */ - float dx[3], theta; - for (int k = 0; k < 3; k++) { - dx[k] = fabs(ci->loc[k] - cj->loc[k]); - if (s->space->periodic && dx[k] > 0.5 * s->space->dim[k]) - dx[k] = -dx[k] + s->space->dim[k]; - if (dx[k] > 0.0f) dx[k] -= ci->h[k]; - } - theta = - (dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / - (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]); - - /* Ignore this task if the cell has no gparts. */ - if (ci->gcount == 0 || cj->gcount == 0) t->type = task_type_none; - - /* Split the interaction? */ - else if (theta < const_theta_max * const_theta_max) { - - /* Are both ci and cj split? */ - if (ci->split && cj->split) { - - /* Split this task into tasks on its progeny. */ - t->type = task_type_none; - for (int j = 0; j < 8; j++) - if (ci->progeny[j] != NULL && ci->progeny[j]->gcount > 0) { - for (int k = 0; k < 8; k++) - if (cj->progeny[k] != NULL && cj->progeny[k]->gcount > 0) { - if (t->type == task_type_none) { - t->type = task_type_grav_mm; - t->ci = ci->progeny[j]; - t->cj = cj->progeny[k]; - } else - t = scheduler_addtask( - s, task_type_grav_mm, task_subtype_none, 0, 0, - ci->progeny[j], cj->progeny[k], 0); - } - } - redo = (t->type != task_type_none); - - } - - /* Otherwise, make a pp task out of it. */ - else - t->type = task_type_grav_pp; - } - } - - } /* gravity pair interaction? */ - - } /* gravity interaction? */ + /* else if (t->type == task_type_grav_mm) { */ + + /* /\* Get a handle on the cells involved. *\/ */ + /* struct cell *ci = t->ci; */ + /* struct cell *cj = t->cj; */ + + /* /\* Self-interaction? *\/ */ + /* if (cj == NULL) { */ + + /* /\* Ignore this task if the cell has no gparts. *\/ */ + /* if (ci->gcount == 0) t->type = task_type_none; */ + + /* /\* If the cell is split, recurse. *\/ */ + /* else if (ci->split) { */ + + /* /\* Make a single sub-task? *\/ */ + /* if (scheduler_dosub && ci->gcount < space_subsize / ci->gcount) { + */ + + /* t->type = task_type_sub; */ + /* t->subtype = task_subtype_grav; */ + + /* } */ + + /* /\* Otherwise, just split the task. *\/ */ + /* else { */ + + /* /\* Split this task into tasks on its progeny. *\/ */ + /* t->type = task_type_none; */ + /* for (int j = 0; j < 8; j++) */ + /* if (ci->progeny[j] != NULL && ci->progeny[j]->gcount > 0) { */ + /* if (t->type == task_type_none) { */ + /* t->type = task_type_grav_mm; */ + /* t->ci = ci->progeny[j]; */ + /* t->cj = NULL; */ + /* } else */ + /* t = scheduler_addtask(s, task_type_grav_mm, + * task_subtype_none, */ + /* 0, 0, ci->progeny[j], NULL, 0); */ + /* for (int k = j + 1; k < 8; k++) */ + /* if (ci->progeny[k] != NULL && ci->progeny[k]->gcount > 0) { + */ + /* if (t->type == task_type_none) { */ + /* t->type = task_type_grav_mm; */ + /* t->ci = ci->progeny[j]; */ + /* t->cj = ci->progeny[k]; */ + /* } else */ + /* t = scheduler_addtask(s, task_type_grav_mm, */ + /* task_subtype_none, 0, 0, */ + /* ci->progeny[j], ci->progeny[k], + * 0); */ + /* } */ + /* } */ + /* redo = (t->type != task_type_none); */ + /* } */ + + /* } */ + + /* /\* Otherwise, just make a pp task out of it. *\/ */ + /* else */ + /* t->type = task_type_grav_pp; */ + + /* } */ + + /* /\* Nope, pair. *\/ */ + /* else { */ + + /* /\* Make a sub-task? *\/ */ + /* if (scheduler_dosub && ci->gcount < space_subsize / cj->gcount) { */ + + /* t->type = task_type_sub; */ + /* t->subtype = task_subtype_grav; */ + + /* } */ + + /* /\* Otherwise, split the task. *\/ */ + /* else { */ + + /* /\* Get the opening angle theta. *\/ */ + /* float dx[3], theta; */ + /* for (int k = 0; k < 3; k++) { */ + /* dx[k] = fabs(ci->loc[k] - cj->loc[k]); */ + /* if (s->space->periodic && dx[k] > 0.5 * s->space->dim[k]) */ + /* dx[k] = -dx[k] + s->space->dim[k]; */ + /* if (dx[k] > 0.0f) dx[k] -= ci->h[k]; */ + /* } */ + /* theta = */ + /* (dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */ + /* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * + * ci->h[2]); */ + + /* /\* Ignore this task if the cell has no gparts. *\/ */ + /* if (ci->gcount == 0 || cj->gcount == 0) t->type = task_type_none; + */ + + /* /\* Split the interaction? *\/ */ + /* else if (theta < const_theta_max * const_theta_max) { */ + + /* /\* Are both ci and cj split? *\/ */ + /* if (ci->split && cj->split) { */ + + /* /\* Split this task into tasks on its progeny. *\/ */ + /* t->type = task_type_none; */ + /* for (int j = 0; j < 8; j++) */ + /* if (ci->progeny[j] != NULL && ci->progeny[j]->gcount > 0) { + */ + /* for (int k = 0; k < 8; k++) */ + /* if (cj->progeny[k] != NULL && cj->progeny[k]->gcount > 0) + * { */ + /* if (t->type == task_type_none) { */ + /* t->type = task_type_grav_mm; */ + /* t->ci = ci->progeny[j]; */ + /* t->cj = cj->progeny[k]; */ + /* } else */ + /* t = scheduler_addtask( */ + /* s, task_type_grav_mm, task_subtype_none, 0, 0, */ + /* ci->progeny[j], cj->progeny[k], 0); */ + /* } */ + /* } */ + /* redo = (t->type != task_type_none); */ + + /* } */ + + /* /\* Otherwise, make a pp task out of it. *\/ */ + /* else */ + /* t->type = task_type_grav_pp; */ + /* } */ + /* } */ + + /* } /\* gravity pair interaction? *\/ */ + + /* } /\* gravity interaction? *\/ */ } /* loop over all tasks. */ } diff --git a/src/space.c b/src/space.c index 267eca198..d87107a80 100644 --- a/src/space.c +++ b/src/space.c @@ -452,8 +452,7 @@ void space_rebuild(struct space *s, double cell_max, int verbose) { const int t = ind[k]; ind[k] = ind[nr_parts]; ind[nr_parts] = t; - } - else { + } else { /* Increment when not exchanging otherwise we need to retest "k".*/ k++; } @@ -488,8 +487,7 @@ void space_rebuild(struct space *s, double cell_max, int verbose) { const int t = gind[k]; gind[k] = gind[nr_gparts]; gind[nr_gparts] = t; - } - else { + } else { /* Increment when not exchanging otherwise we need to retest "k".*/ k++; } @@ -508,7 +506,6 @@ void space_rebuild(struct space *s, double cell_max, int verbose) { } }*/ - /* Exchange the strays, note that this potentially re-allocates the parts arrays. */ size_t nr_parts_exchanged = s->nr_parts - nr_parts; diff --git a/src/task.c b/src/task.c index 31c2bfcb3..77503d220 100644 --- a/src/task.c +++ b/src/task.c @@ -47,10 +47,10 @@ /* Task type names. */ const char *taskID_names[task_type_count] = { - "none", "sort", "self", "pair", "sub", - "init", "ghost", "drift", "kick", "send", - "recv", "grav_pp", "grav_mm", "grav_up", "grav_down", - "grav_external", "part_sort", "gpart_sort", "split_cell", "rewait"}; + "none", "sort", "self", "pair", "sub", + "init", "ghost", "drift", "kick", "send", + "recv", "grav_up", "grav_external", "part_sort", "gpart_sort", + "split_cell", "rewait"}; const char *subtaskID_names[task_type_count] = {"none", "density", "force", "grav"}; @@ -124,12 +124,12 @@ void task_unlock(struct task *t) { cell_unlocktree(t->ci); if (t->cj != NULL) cell_unlocktree(t->cj); break; - case task_type_grav_pp: - case task_type_grav_mm: - case task_type_grav_down: - cell_gunlocktree(t->ci); - if (t->cj != NULL) cell_gunlocktree(t->cj); - break; + /* case task_type_grav_pp: */ + /* case task_type_grav_mm: */ + /* case task_type_grav_down: */ + /* cell_gunlocktree(t->ci); */ + /* if (t->cj != NULL) cell_gunlocktree(t->cj); */ + /* break; */ default: break; } @@ -184,15 +184,15 @@ int task_lock(struct task *t) { } /* Gravity tasks? */ - else if (type == task_type_grav_mm || type == task_type_grav_pp || - type == task_type_grav_down) { - if (ci->ghold || (cj != NULL && cj->ghold)) return 0; - if (cell_glocktree(ci) != 0) return 0; - if (cj != NULL && cell_glocktree(cj) != 0) { - cell_gunlocktree(ci); - return 0; - } - } + /* else if (type == task_type_grav_mm || type == task_type_grav_pp || */ + /* type == task_type_grav_down) { */ + /* if (ci->ghold || (cj != NULL && cj->ghold)) return 0; */ + /* if (cell_glocktree(ci) != 0) return 0; */ + /* if (cj != NULL && cell_glocktree(cj) != 0) { */ + /* cell_gunlocktree(ci); */ + /* return 0; */ + /* } */ + /* } */ /* If we made it this far, we've got a lock. */ return 1; diff --git a/src/task.h b/src/task.h index 25cc886f4..4956860c9 100644 --- a/src/task.h +++ b/src/task.h @@ -44,10 +44,10 @@ enum task_types { task_type_kick, task_type_send, task_type_recv, - task_type_grav_pp, - task_type_grav_mm, + /* task_type_grav_pp, */ + /* task_type_grav_mm, */ task_type_grav_up, - task_type_grav_down, + /* task_type_grav_down, */ task_type_grav_external, task_type_part_sort, task_type_gpart_sort, -- GitLab From 5a80ae0ce51ccb8933fb432b2e8678dec401ebeb Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 16 May 2016 17:12:40 +0100 Subject: [PATCH 04/72] Construct the 1st-order multipoles correctly --- src/const.h | 1 + src/engine.c | 4 +- src/multipole.c | 166 ++++++++++++++++++++------------------- src/multipole.h | 134 +++++++++++++++---------------- src/runner_doiact_grav.h | 59 ++++++++------ 5 files changed, 190 insertions(+), 174 deletions(-) diff --git a/src/const.h b/src/const.h index 6432ef6a9..8390da089 100644 --- a/src/const.h +++ b/src/const.h @@ -40,6 +40,7 @@ #define const_max_u_change 0.1f /* Gravity stuff. */ +#define multipole_order 1 #define const_theta_max 0.57735f #define const_G 6.672e-8f /* Gravitational constant. */ #define const_epsilon 0.0014f /* Gravity blending distance. */ diff --git a/src/engine.c b/src/engine.c index d5fe48bf1..e7c7e8aa3 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1947,7 +1947,7 @@ void engine_init_particles(struct engine *e) { /* Add the tasks corresponding to self-gravity to the masks */ if (e->policy & engine_policy_self_gravity) { - /* Nothing here for now */ + mask |= 1 << task_type_grav_up; } /* Add the tasks corresponding to external gravity to the masks */ @@ -2128,7 +2128,7 @@ void engine_step(struct engine *e) { /* Add the tasks corresponding to self-gravity to the masks */ if (e->policy & engine_policy_self_gravity) { - /* Nothing here for now */ + mask |= 1 << task_type_grav_up; } /* Add the tasks corresponding to external gravity to the masks */ diff --git a/src/multipole.c b/src/multipole.c index fc4701fea..23d845c32 100644 --- a/src/multipole.c +++ b/src/multipole.c @@ -1,6 +1,7 @@ /******************************************************************************* * This file is part of SWIFT. * Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk) + * 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -37,27 +38,28 @@ #include "multipole.h" /** - * @brief Merge two multipoles. + * @brief Add the second multipole to the first one. * - * @param ma The #multipole which will contain the merged result. - * @param mb The other #multipole. + * @param m_sum The #multipole which will contain the sum. + * @param m_other The #multipole to add. */ -void multipole_merge(struct multipole *ma, struct multipole *mb) { +void multipole_add(struct multipole *m_sum, const struct multipole *m_other) { -#if multipole_order == 1 +#if multipole_order != 1 +#error "Multipoles of order >1 not yet implemented." +#endif /* Correct the position. */ - float mma = ma->coeffs[0], mmb = mb->coeffs[0]; - float w = 1.0f / (mma + mmb); - for (int k = 0; k < 3; k++) ma->x[k] = (ma->x[k] * mma + mb->x[k] * mmb) * w; + const float M_tot = m_sum->mass + m_other->mass; + const float M_tot_inv = 1.f / M_tot; + for (int k = 0; k < 3; k++) + m_sum->CoM[k] = + (m_sum->CoM[k] * m_sum->mass + m_other->CoM[k] * m_other->mass) * + M_tot_inv; /* Add the particle to the moments. */ - ma->coeffs[0] = mma + mmb; - -#else -#error( "Multipoles of order %i not yet implemented." , multipole_order ) -#endif + m_sum->mass = M_tot; } /** @@ -69,19 +71,21 @@ void multipole_merge(struct multipole *ma, struct multipole *mb) { void multipole_addpart(struct multipole *m, struct gpart *p) { -#if multipole_order == 1 + /* #if multipole_order == 1 */ - /* Correct the position. */ - float mm = m->coeffs[0], mp = p->mass; - float w = 1.0f / (mm + mp); - for (int k = 0; k < 3; k++) m->x[k] = (m->x[k] * mm + p->x[k] * mp) * w; + /* /\* Correct the position. *\/ */ + /* float mm = m->coeffs[0], mp = p->mass; */ + /* float w = 1.0f / (mm + mp); */ + /* for (int k = 0; k < 3; k++) m->x[k] = (m->x[k] * mm + p->x[k] * mp) * w; + */ - /* Add the particle to the moments. */ - m->coeffs[0] = mm + mp; + /* /\* Add the particle to the moments. *\/ */ + /* m->coeffs[0] = mm + mp; */ -#else -#error( "Multipoles of order %i not yet implemented." , multipole_order ) -#endif + /* #else */ + /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + */ + /* #endif */ } /** @@ -94,76 +98,76 @@ void multipole_addpart(struct multipole *m, struct gpart *p) { void multipole_addparts(struct multipole *m, struct gpart *p, int N) { -#if multipole_order == 1 - - /* Get the combined mass and positions. */ - double xp[3] = {0.0, 0.0, 0.0}; - float mp = 0.0f, w; - for (int k = 0; k < N; k++) { - w = p[k].mass; - mp += w; - xp[0] += p[k].x[0] * w; - xp[1] += p[k].x[1] * w; - xp[2] += p[k].x[2] * w; - } - - /* Correct the position. */ - float mm = m->coeffs[0]; - w = 1.0f / (mm + mp); - for (int k = 0; k < 3; k++) m->x[k] = (m->x[k] * mm + xp[k]) * w; + /* #if multipole_order == 1 */ + + /* /\* Get the combined mass and positions. *\/ */ + /* double xp[3] = {0.0, 0.0, 0.0}; */ + /* float mp = 0.0f, w; */ + /* for (int k = 0; k < N; k++) { */ + /* w = p[k].mass; */ + /* mp += w; */ + /* xp[0] += p[k].x[0] * w; */ + /* xp[1] += p[k].x[1] * w; */ + /* xp[2] += p[k].x[2] * w; */ + /* } */ + + /* /\* Correct the position. *\/ */ + /* float mm = m->coeffs[0]; */ + /* w = 1.0f / (mm + mp); */ + /* for (int k = 0; k < 3; k++) m->x[k] = (m->x[k] * mm + xp[k]) * w; */ + + /* /\* Add the particle to the moments. *\/ */ + /* m->coeffs[0] = mm + mp; */ + + /* #else */ + /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + */ + /* #endif */ +} - /* Add the particle to the moments. */ - m->coeffs[0] = mm + mp; +/** +* @brief Reset the data of a #multipole. +* +* @param m The #multipole. +*/ +void multipole_reset(struct multipole *m) { -#else -#error( "Multipoles of order %i not yet implemented." , multipole_order ) -#endif + /* Just bzero the struct. */ + bzero(m, sizeof(struct multipole)); } /** - * @brief Init a multipole from a set of particles. - * - * @param m The #multipole. - * @param parts The #gpart. - * @param N The number of particles. - */ - -void multipole_init(struct multipole *m, struct gpart *parts, int N) { +* @brief Init a multipole from a set of particles. +* +* @param m The #multipole. +* @param parts The #gpart. +* @param N The number of particles. +*/ +void multipole_init(struct multipole *m, const struct gpart *gparts, + int gcount) { + +#if multipole_order != 1 +#error "Multipoles of order >1 not yet implemented." +#endif -#if multipole_order == 1 + /* Zero everything */ + multipole_reset(m); - float mass = 0.0f, w; + float mass = 0.0f; double x[3] = {0.0, 0.0, 0.0}; - int k; /* Collect the particle data. */ - for (k = 0; k < N; k++) { - w = parts[k].mass; + for (int k = 0; k < gcount; k++) { + const float w = gparts[k].mass; mass += w; - x[0] += parts[k].x[0] * w; - x[1] += parts[k].x[1] * w; - x[2] += parts[k].x[2] * w; + x[0] += gparts[k].x[0] * w; + x[1] += gparts[k].x[1] * w; + x[2] += gparts[k].x[2] * w; } /* Store the data on the multipole. */ - m->coeffs[0] = mass; - m->x[0] = x[0] / mass; - m->x[1] = x[1] / mass; - m->x[2] = x[2] / mass; - -#else -#error( "Multipoles of order %i not yet implemented." , multipole_order ) -#endif -} - -/** - * @brief Reset the data of a #multipole. - * - * @param m The #multipole. - */ - -void multipole_reset(struct multipole *m) { - - /* Just bzero the struct. */ - bzero(m, sizeof(struct multipole)); + m->mass = mass; + m->CoM[0] = x[0] / mass; + m->CoM[1] = x[1] / mass; + m->CoM[2] = x[2] / mass; } diff --git a/src/multipole.h b/src/multipole.h index 85ba44d3c..07e9ecbd4 100644 --- a/src/multipole.h +++ b/src/multipole.h @@ -1,6 +1,7 @@ /******************************************************************************* * This file is part of SWIFT. * Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk) + * 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -28,31 +29,33 @@ #include "kernel_gravity.h" #include "part.h" -/* Some constants. */ -#define multipole_order 1 - /* Multipole struct. */ struct multipole { /* Multipole location. */ - double x[3]; + double CoM[3]; + + /* Multipole mass */ + float mass; - /* Acceleration on this multipole. */ - float a[3]; + /* /\* Acceleration on this multipole. *\/ */ + /* float a[3]; */ - /* Multipole coefficients. */ - float coeffs[multipole_order * multipole_order]; + /* /\* Multipole coefficients. *\/ */ + /* float coeffs[multipole_order * multipole_order]; */ }; /* Multipole function prototypes. */ -static void multipole_iact_mm(struct multipole *ma, struct multipole *mb, - double *shift); -void multipole_merge(struct multipole *ma, struct multipole *mb); -void multipole_addpart(struct multipole *m, struct gpart *p); -void multipole_addparts(struct multipole *m, struct gpart *p, int N); -void multipole_init(struct multipole *m, struct gpart *parts, int N); +void multipole_add(struct multipole *m_sum, const struct multipole *m_term); +void multipole_init(struct multipole *m, const struct gpart *gparts, + int gcount); void multipole_reset(struct multipole *m); +/* static void multipole_iact_mm(struct multipole *ma, struct multipole *mb, */ +/* double *shift); */ +/* void multipole_addpart(struct multipole *m, struct gpart *p); */ +/* void multipole_addparts(struct multipole *m, struct gpart *p, int N); */ + /** * @brief Compute the pairwise interaction between two multipoles. * @@ -60,39 +63,38 @@ void multipole_reset(struct multipole *m); * @param mb The second #multipole. * @param shift The periodicity correction. */ - __attribute__((always_inline)) INLINE static void multipole_iact_mm( struct multipole *ma, struct multipole *mb, double *shift) { - - float dx[3], ir, r, r2 = 0.0f, acc; - int k; - - /* Compute the multipole distance. */ - for (k = 0; k < 3; k++) { - dx[k] = ma->x[k] - mb->x[k] - shift[k]; - r2 += dx[k] * dx[k]; - } - - /* Compute the normalized distance vector. */ - ir = 1.0f / sqrtf(r2); - r = r2 * ir; - - /* Evaluate the gravity kernel. */ - kernel_grav_eval(r, &acc); - - /* Scale the acceleration. */ - acc *= const_G * ir * ir * ir; - -/* Compute the forces on both multipoles. */ -#if multipole_order == 1 - float mma = ma->coeffs[0], mmb = mb->coeffs[0]; - for (k = 0; k < 3; k++) { - ma->a[k] -= dx[k] * acc * mmb; - mb->a[k] += dx[k] * acc * mma; - } -#else -#error( "Multipoles of order %i not yet implemented." , multipole_order ) -#endif + /* float dx[3], ir, r, r2 = 0.0f, acc; */ + /* int k; */ + + /* /\* Compute the multipole distance. *\/ */ + /* for (k = 0; k < 3; k++) { */ + /* dx[k] = ma->x[k] - mb->x[k] - shift[k]; */ + /* r2 += dx[k] * dx[k]; */ + /* } */ + + /* /\* Compute the normalized distance vector. *\/ */ + /* ir = 1.0f / sqrtf(r2); */ + /* r = r2 * ir; */ + + /* /\* Evaluate the gravity kernel. *\/ */ + /* kernel_grav_eval(r, &acc); */ + + /* /\* Scale the acceleration. *\/ */ + /* acc *= const_G * ir * ir * ir; */ + + /* /\* Compute the forces on both multipoles. *\/ */ + /* #if multipole_order == 1 */ + /* float mma = ma->coeffs[0], mmb = mb->coeffs[0]; */ + /* for (k = 0; k < 3; k++) { */ + /* ma->a[k] -= dx[k] * acc * mmb; */ + /* mb->a[k] += dx[k] * acc * mma; */ + /* } */ + /* #else */ + /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + */ + /* #endif */ } /** @@ -102,35 +104,35 @@ __attribute__((always_inline)) INLINE static void multipole_iact_mm( * @param p The #gpart. * @param shift The periodicity correction. */ - __attribute__((always_inline)) INLINE static void multipole_iact_mp( struct multipole *m, struct gpart *p, double *shift) { - float dx[3], ir, r, r2 = 0.0f, acc; - int k; + /* float dx[3], ir, r, r2 = 0.0f, acc; */ + /* int k; */ - /* Compute the multipole distance. */ - for (k = 0; k < 3; k++) { - dx[k] = m->x[k] - p->x[k] - shift[k]; - r2 += dx[k] * dx[k]; - } + /* /\* Compute the multipole distance. *\/ */ + /* for (k = 0; k < 3; k++) { */ + /* dx[k] = m->x[k] - p->x[k] - shift[k]; */ + /* r2 += dx[k] * dx[k]; */ + /* } */ - /* Compute the normalized distance vector. */ - ir = 1.0f / sqrtf(r2); - r = r2 * ir; + /* /\* Compute the normalized distance vector. *\/ */ + /* ir = 1.0f / sqrtf(r2); */ + /* r = r2 * ir; */ - /* Evaluate the gravity kernel. */ - kernel_grav_eval(r, &acc); + /* /\* Evaluate the gravity kernel. *\/ */ + /* kernel_grav_eval(r, &acc); */ - /* Scale the acceleration. */ - acc *= const_G * ir * ir * ir * m->coeffs[0]; + /* /\* Scale the acceleration. *\/ */ + /* acc *= const_G * ir * ir * ir * m->coeffs[0]; */ -/* Compute the forces on both multipoles. */ -#if multipole_order == 1 - for (k = 0; k < 3; k++) p->a_grav[k] += dx[k] * acc; -#else -#error( "Multipoles of order %i not yet implemented." , multipole_order ) -#endif + /* /\* Compute the forces on both multipoles. *\/ */ + /* #if multipole_order == 1 */ + /* for (k = 0; k < 3; k++) p->a_grav[k] += dx[k] * acc; */ + /* #else */ + /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + */ + /* #endif */ } #endif /* SWIFT_MULTIPOLE_H */ diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 19e778795..31aac5682 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -1,6 +1,7 @@ /******************************************************************************* * This file is part of SWIFT. * Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk) + * 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -39,7 +40,8 @@ /* int pid, pjd, k, sid; */ /* double rshift, shift[3] = {0.0, 0.0, 0.0}, nshift[3]; */ /* struct entry *restrict sort_i, *restrict sort_j; */ -/* struct gpart *restrict pi, *restrict pj, *restrict parts_i, *restrict parts_j; */ +/* struct gpart *restrict pi, *restrict pj, *restrict parts_i, *restrict + * parts_j; */ /* double pix[3]; */ /* float dx[3], r2, h_max, di, dj; */ /* int count_i, count_j, cnj, cnj_new; */ @@ -77,7 +79,8 @@ /* /\* Get some other useful values. *\/ */ /* h_max = */ -/* sqrtf(ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]) * */ +/* sqrtf(ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]) + * * */ /* const_theta_max; */ /* count_i = ci->gcount; */ /* count_j = cj->gcount; */ @@ -114,9 +117,12 @@ /* #ifndef VECTORIZE */ -/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */ -/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e in */ -/* // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long */ +/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 + * ) */ +/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e + * in */ +/* // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long + */ /* // long int)ci) / sizeof(struct cell) , ((long long int)cj) / */ /* // sizeof(struct cell) ); */ @@ -206,11 +212,7 @@ void runner_dograv_up(struct runner *r, struct cell *c) { - /* Re-set this cell's multipole. */ - multipole_reset(&c->multipole); - - /* Split? */ - if (c->split) { + if (c->split) {/* Regular node */ /* Recurse. */ for (int k = 0; k < 8; k++) @@ -218,17 +220,16 @@ void runner_dograv_up(struct runner *r, struct cell *c) { /* Collect the multipoles from the progeny. */ multipole_reset(&c->multipole); - for (int k = 0; k < 8; k++) + for (int k = 0; k < 8; k++) { if (c->progeny[k] != NULL) - multipole_merge(&c->multipole, &c->progeny[k]->multipole); + multipole_add(&c->multipole, &c->progeny[k]->multipole); + } - } + } else {/* Leaf node. */ - /* No, leaf node. */ - else - - /* Just collect the multipole. */ + /* Just construct the multipole from the gparts. */ multipole_init(&c->multipole, c->gparts, c->gcount); + } } /* /\** */ @@ -303,7 +304,8 @@ void runner_dograv_up(struct runner *r, struct cell *c) { /* } */ /* theta = */ /* sqrt((dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */ -/* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2])); */ +/* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * + * ci->h[2])); */ /* /\* Do an MM or an MP/PM? *\/ */ /* if (theta > const_theta_max * 4) { */ @@ -335,7 +337,8 @@ void runner_dograv_up(struct runner *r, struct cell *c) { /* struct engine *e = r->e; */ /* int pid, pjd, k, count_i = ci->gcount, count_j = cj->gcount; */ /* double shift[3] = {0.0, 0.0, 0.0}; */ -/* struct gpart *restrict parts_i = ci->gparts, *restrict parts_j = cj->gparts; */ +/* struct gpart *restrict parts_i = ci->gparts, *restrict parts_j = + * cj->gparts; */ /* struct gpart *restrict pi, *restrict pj; */ /* double pix[3]; */ /* float dx[3], r2; */ @@ -383,9 +386,12 @@ void runner_dograv_up(struct runner *r, struct cell *c) { /* /\* Compute the interaction. *\/ */ /* #ifndef VECTORIZE */ -/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */ -/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e in */ -/* // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long */ +/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 + * ) */ +/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e + * in */ +/* // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long + */ /* // long int)ci) / sizeof(struct cell) , ((long long int)cj) / */ /* // sizeof(struct cell) ); */ @@ -473,8 +479,10 @@ void runner_dograv_up(struct runner *r, struct cell *c) { /* /\* Compute the interaction. *\/ */ /* #ifndef VECTORIZE */ -/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) */ -/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e." , */ +/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 + * ) */ +/* // message( "interacting particles pi=%lli and pj=%lli with + * r=%.3e." , */ /* // pi->part->id , pj->part->id , sqrtf(r2) ); */ /* runner_iact_grav(r2, dx, pi, pj); */ @@ -563,7 +571,8 @@ void runner_dograv_up(struct runner *r, struct cell *c) { /* if (dx[k] > 0.0f) dx[k] -= ci->h[k]; */ /* } */ /* theta = (dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */ -/* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]); */ +/* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * + * ci->h[2]); */ /* /\* Split the interaction? *\/ */ /* if (theta < const_theta_max * const_theta_max) { */ -- GitLab From c10d011031eb21a096c18624f40e7c1f7b091387 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 16 May 2016 19:15:24 +0100 Subject: [PATCH 05/72] Quadrupoles are now constructed --- src/const.h | 2 +- src/multipole.c | 193 ++++++++++++++++++++++++++++++------------------ src/multipole.h | 10 +-- 3 files changed, 127 insertions(+), 78 deletions(-) diff --git a/src/const.h b/src/const.h index 8390da089..87852ba5e 100644 --- a/src/const.h +++ b/src/const.h @@ -40,7 +40,7 @@ #define const_max_u_change 0.1f /* Gravity stuff. */ -#define multipole_order 1 +#define multipole_order 2 #define const_theta_max 0.57735f #define const_G 6.672e-8f /* Gravitational constant. */ #define const_epsilon 0.0014f /* Gravity blending distance. */ diff --git a/src/multipole.c b/src/multipole.c index 23d845c32..dcd4f120d 100644 --- a/src/multipole.c +++ b/src/multipole.c @@ -22,44 +22,140 @@ #include "../config.h" /* Some standard headers. */ -#include -#include -#include -#include -#include -#include - -/* MPI headers. */ -#ifdef WITH_MPI -#include -#endif +#include /* This object's header. */ #include "multipole.h" +/** +* @brief Reset the data of a #multipole. +* +* @param m The #multipole. +*/ +void multipole_reset(struct multipole *m) { + + /* Just bzero the struct. */ + bzero(m, sizeof(struct multipole)); +} + +/** +* @brief Init a multipole from a set of particles. +* +* @param m The #multipole. +* @param gparts The #gpart. +* @param gcount The number of particles. +*/ +void multipole_init(struct multipole *m, const struct gpart *gparts, + int gcount) { + +#if multipole_order > 2 +#error "Multipoles of order >2 not yet implemented." +#endif + + /* Zero everything */ + multipole_reset(m); + + /* Temporary variables */ + double mass = 0.0; + double com[3] = {0.0, 0.0, 0.0}; + +#if multipole_order >= 2 + double I_xx = 0.0, I_yy = 0.0, I_zz = 0.0; + double I_xy = 0.0, I_xz = 0.0, I_yz = 0.0; +#endif + + /* Collect the particle data. */ + for (int k = 0; k < gcount; k++) { + const float w = gparts[k].mass; + + mass += w; + com[0] += gparts[k].x[0] * w; + com[1] += gparts[k].x[1] * w; + com[2] += gparts[k].x[2] * w; + +#if multipole_order >= 2 + I_xx += gparts[k].x[0] * gparts[k].x[0] * w; + I_yy += gparts[k].x[1] * gparts[k].x[1] * w; + I_zz += gparts[k].x[2] * gparts[k].x[2] * w; + I_xy += gparts[k].x[0] * gparts[k].x[1] * w; + I_xz += gparts[k].x[0] * gparts[k].x[2] * w; + I_yz += gparts[k].x[1] * gparts[k].x[2] * w; +#endif + } + + const double imass = 1.0 / mass; + + /* Store the data on the multipole. */ + m->mass = mass; + m->CoM[0] = com[0] * imass; + m->CoM[1] = com[1] * imass; + m->CoM[2] = com[2] * imass; + +#if multipole_order >= 2 + m->I_xx = I_xx - imass * com[0] * com[0]; + m->I_yy = I_yy - imass * com[1] * com[1]; + m->I_zz = I_zz - imass * com[2] * com[2]; + m->I_xy = I_xy - imass * com[0] * com[1]; + m->I_xz = I_xz - imass * com[0] * com[2]; + m->I_yz = I_yz - imass * com[1] * com[2]; +#endif +} + /** * @brief Add the second multipole to the first one. * - * @param m_sum The #multipole which will contain the sum. - * @param m_other The #multipole to add. + * @param ma The #multipole which will contain the sum. + * @param mb The #multipole to add. */ -void multipole_add(struct multipole *m_sum, const struct multipole *m_other) { +void multipole_add(struct multipole *ma, const struct multipole *mb) { -#if multipole_order != 1 -#error "Multipoles of order >1 not yet implemented." +#if multipole_order > 2 +#error "Multipoles of order >2 not yet implemented." #endif /* Correct the position. */ - const float M_tot = m_sum->mass + m_other->mass; - const float M_tot_inv = 1.f / M_tot; - for (int k = 0; k < 3; k++) - m_sum->CoM[k] = - (m_sum->CoM[k] * m_sum->mass + m_other->CoM[k] * m_other->mass) * - M_tot_inv; - - /* Add the particle to the moments. */ - m_sum->mass = M_tot; + const double ma_mass = ma->mass; + const double mb_mass = mb->mass; + const double M_tot = ma_mass + mb_mass; + const double M_tot_inv = 1.0 / M_tot; + + const double ma_CoM[3] = {ma->CoM[0], ma->CoM[1], ma->CoM[2]}; + const double mb_CoM[3] = {mb->CoM[0], mb->CoM[1], mb->CoM[2]}; + +#if multipole_order >= 2 + const double ma_I_xx = (double)ma->I_xx + ma_mass * ma_CoM[0] * ma_CoM[0]; + const double ma_I_yy = (double)ma->I_yy + ma_mass * ma_CoM[1] * ma_CoM[1]; + const double ma_I_zz = (double)ma->I_zz + ma_mass * ma_CoM[2] * ma_CoM[2]; + const double ma_I_xy = (double)ma->I_xy + ma_mass * ma_CoM[0] * ma_CoM[1]; + const double ma_I_xz = (double)ma->I_xz + ma_mass * ma_CoM[0] * ma_CoM[2]; + const double ma_I_yz = (double)ma->I_yz + ma_mass * ma_CoM[1] * ma_CoM[2]; + + const double mb_I_xx = (double)mb->I_xx + mb_mass * mb_CoM[0] * mb_CoM[0]; + const double mb_I_yy = (double)mb->I_yy + mb_mass * mb_CoM[1] * mb_CoM[1]; + const double mb_I_zz = (double)mb->I_zz + mb_mass * mb_CoM[2] * mb_CoM[2]; + const double mb_I_xy = (double)mb->I_xy + mb_mass * mb_CoM[0] * mb_CoM[1]; + const double mb_I_xz = (double)mb->I_xz + mb_mass * mb_CoM[0] * mb_CoM[2]; + const double mb_I_yz = (double)mb->I_yz + mb_mass * mb_CoM[1] * mb_CoM[2]; +#endif + + /* New mass */ + ma->mass = M_tot; + + /* New CoM */ + ma->CoM[0] = (ma_CoM[0] * ma_mass + mb_CoM[0] * mb_mass) * M_tot_inv; + ma->CoM[1] = (ma_CoM[1] * ma_mass + mb_CoM[1] * mb_mass) * M_tot_inv; + ma->CoM[2] = (ma_CoM[2] * ma_mass + mb_CoM[2] * mb_mass) * M_tot_inv; + +/* New quadrupole */ +#if multipole_order >= 2 + ma->I_xx = (ma_I_xx + mb_I_xx) - M_tot * ma->CoM[0] * ma->CoM[0]; + ma->I_yy = (ma_I_yy + mb_I_yy) - M_tot * ma->CoM[1] * ma->CoM[1]; + ma->I_zz = (ma_I_zz + mb_I_zz) - M_tot * ma->CoM[2] * ma->CoM[2]; + ma->I_xy = (ma_I_xy + mb_I_xy) - M_tot * ma->CoM[0] * ma->CoM[1]; + ma->I_xz = (ma_I_xz + mb_I_xz) - M_tot * ma->CoM[0] * ma->CoM[2]; + ma->I_yz = (ma_I_yz + mb_I_yz) - M_tot * ma->CoM[1] * ma->CoM[2]; +#endif } /** @@ -124,50 +220,3 @@ void multipole_addparts(struct multipole *m, struct gpart *p, int N) { */ /* #endif */ } - -/** -* @brief Reset the data of a #multipole. -* -* @param m The #multipole. -*/ -void multipole_reset(struct multipole *m) { - - /* Just bzero the struct. */ - bzero(m, sizeof(struct multipole)); -} - -/** -* @brief Init a multipole from a set of particles. -* -* @param m The #multipole. -* @param parts The #gpart. -* @param N The number of particles. -*/ -void multipole_init(struct multipole *m, const struct gpart *gparts, - int gcount) { - -#if multipole_order != 1 -#error "Multipoles of order >1 not yet implemented." -#endif - - /* Zero everything */ - multipole_reset(m); - - float mass = 0.0f; - double x[3] = {0.0, 0.0, 0.0}; - - /* Collect the particle data. */ - for (int k = 0; k < gcount; k++) { - const float w = gparts[k].mass; - mass += w; - x[0] += gparts[k].x[0] * w; - x[1] += gparts[k].x[1] * w; - x[2] += gparts[k].x[2] * w; - } - - /* Store the data on the multipole. */ - m->mass = mass; - m->CoM[0] = x[0] / mass; - m->CoM[1] = x[1] / mass; - m->CoM[2] = x[2] / mass; -} diff --git a/src/multipole.h b/src/multipole.h index 07e9ecbd4..e9fa348b3 100644 --- a/src/multipole.h +++ b/src/multipole.h @@ -38,11 +38,11 @@ struct multipole { /* Multipole mass */ float mass; - /* /\* Acceleration on this multipole. *\/ */ - /* float a[3]; */ - - /* /\* Multipole coefficients. *\/ */ - /* float coeffs[multipole_order * multipole_order]; */ +#if multipole_order >= 2 + /* Quadrupole terms */ + float I_xx, I_yy, I_zz; + float I_xy, I_xz, I_yz; +#endif }; /* Multipole function prototypes. */ -- GitLab From 9102030d50487a97d827584dff2d31b3392920bf Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 16 May 2016 23:25:15 +0100 Subject: [PATCH 06/72] Added function to check the multipole construction. --- src/cell.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/cell.h | 1 + src/engine.c | 3 +++ 3 files changed, 59 insertions(+) diff --git a/src/cell.c b/src/cell.c index 29072173b..b7b1e8fb9 100644 --- a/src/cell.c +++ b/src/cell.c @@ -661,3 +661,58 @@ void cell_clean_links(struct cell *c, void *data) { c->force = NULL; c->nr_force = 0; } + +/** + * @brief Computes the multi-pole brutally and compare to the + * recursively computed one. + * + * @param c Cell to act upon + * @param data Unused parameter + */ +void cell_check_multipole(struct cell *c, void *data) { + + struct multipole ma; + + if (c->gcount > 0) { + + /* Brute-force calculation */ + multipole_init(&ma, c->gparts, c->gcount); + + /* Compare with recursive one */ + struct multipole mb = c->multipole; + + if (fabsf(ma.mass - mb.mass) / fabsf(ma.mass + mb.mass) > 1e-5) + error("Multipole masses are different (%12.15e vs. %12.15e)", ma.mass, + mb.mass); + + for (int k = 0; k < 3; ++k) + if (fabsf(ma.CoM[k] - mb.CoM[k]) / fabsf(ma.CoM[k] + mb.CoM[k]) > 1e-5) + error("Multipole CoM are different (%12.15e vs. %12.15e", ma.CoM[k], + mb.CoM[k]); + + if (fabsf(ma.I_xx - mb.I_xx) / fabsf(ma.I_xx + mb.I_xx) > 1e-5 && + ma.I_xx > 1e-9) + error("Multipole I_xx are different (%12.15e vs. %12.15e)", ma.I_xx, + mb.I_xx); + if (fabsf(ma.I_yy - mb.I_yy) / fabsf(ma.I_yy + mb.I_yy) > 1e-5 && + ma.I_yy > 1e-9) + error("Multipole I_yy are different (%12.15e vs. %12.15e)", ma.I_yy, + mb.I_yy); + if (fabsf(ma.I_zz - mb.I_zz) / fabsf(ma.I_zz + mb.I_zz) > 1e-5 && + ma.I_zz > 1e-9) + error("Multipole I_zz are different (%12.15e vs. %12.15e)", ma.I_zz, + mb.I_zz); + if (fabsf(ma.I_xy - mb.I_xy) / fabsf(ma.I_xy + mb.I_xy) > 1e-5 && + ma.I_xy > 1e-9) + error("Multipole I_xy are different (%12.15e vs. %12.15e)", ma.I_xy, + mb.I_xy); + if (fabsf(ma.I_xz - mb.I_xz) / fabsf(ma.I_xz + mb.I_xz) > 1e-5 && + ma.I_xz > 1e-9) + error("Multipole I_xz are different (%12.15e vs. %12.15e)", ma.I_xz, + mb.I_xz); + if (fabsf(ma.I_yz - mb.I_yz) / fabsf(ma.I_yz + mb.I_yz) > 1e-5 && + ma.I_yz > 1e-9) + error("Multipole I_yz are different (%12.15e vs. %12.15e)", ma.I_yz, + mb.I_yz); + } +} diff --git a/src/cell.h b/src/cell.h index fbdaa928b..1bdf67c5d 100644 --- a/src/cell.h +++ b/src/cell.h @@ -188,5 +188,6 @@ 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); +void cell_check_multipole(struct cell *c, void *data); #endif /* SWIFT_CELL_H */ diff --git a/src/engine.c b/src/engine.c index e7c7e8aa3..e38a2da52 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2150,6 +2150,9 @@ void engine_step(struct engine *e) { TIMER_TOC2(timer_step); + /* Check that the multipoles are correct */ + space_map_cells_pre(s, 1, cell_check_multipole, NULL); + clocks_gettime(&time2); e->wallclock_time = (float)clocks_diff(&time1, &time2); -- GitLab From a699286020f69b593a3ca07c81d6af8932e4470f Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 16 May 2016 23:47:21 +0100 Subject: [PATCH 07/72] MPI task related code only in MPI mode. --- src/engine.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/engine.c b/src/engine.c index e38a2da52..aad07e21b 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1468,26 +1468,27 @@ void engine_maketasks(struct engine *e) { of its super-cell. */ engine_make_extra_hydroloop_tasks(e); +#ifdef WITH_MPI + /* Add the communication tasks if MPI is being used. */ - if (e->policy & engine_policy_mpi) { - /* Loop over the proxies. */ - for (int pid = 0; pid < e->nr_proxies; pid++) { + /* Loop over the proxies. */ + for (int pid = 0; pid < e->nr_proxies; pid++) { - /* Get a handle on the proxy. */ - struct proxy *p = &e->proxies[pid]; + /* Get a handle on the proxy. */ + struct proxy *p = &e->proxies[pid]; - /* Loop through the proxy's incoming cells and add the - recv tasks. */ - for (int k = 0; k < p->nr_cells_in; k++) - engine_addtasks_recv(e, p->cells_in[k], NULL, NULL); + /* Loop through the proxy's incoming cells and add the + recv tasks. */ + for (int k = 0; k < p->nr_cells_in; k++) + engine_addtasks_recv(e, p->cells_in[k], NULL, NULL); - /* Loop through the proxy's outgoing cells and add the - send tasks. */ - for (int k = 0; k < p->nr_cells_out; k++) - engine_addtasks_send(e, p->cells_out[k], p->cells_in[0]); - } + /* Loop through the proxy's outgoing cells and add the + send tasks. */ + for (int k = 0; k < p->nr_cells_out; k++) + engine_addtasks_send(e, p->cells_out[k], p->cells_in[0]); } +#endif /* Set the unlocks per task. */ scheduler_set_unlocks(sched); -- GitLab From aa7f301ffd352c02b3d5102e32228da158bebb0d Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 16 May 2016 23:57:18 +0100 Subject: [PATCH 08/72] No more dogsort --- src/runner.c | 286 +++++++++++++++++++++++++-------------------------- 1 file changed, 143 insertions(+), 143 deletions(-) diff --git a/src/runner.c b/src/runner.c index 5d4808ff1..d45af599b 100644 --- a/src/runner.c +++ b/src/runner.c @@ -423,150 +423,150 @@ void runner_dosort(struct runner *r, struct cell *c, int flags, int clock) { if (clock) TIMER_TOC(timer_dosort); } -void runner_dogsort(struct runner *r, struct cell *c, int flags, int clock) { - - struct entry *finger; - struct entry *fingers[8]; - struct gpart *gparts = c->gparts; - struct entry *gsort; - int j, k, count = c->gcount; - int i, ind, off[8], inds[8], temp_i, missing; - // float shift[3]; - float buff[8], px[3]; - - TIMER_TIC - - /* Clean-up the flags, i.e. filter out what's already been sorted. */ - flags &= ~c->gsorted; - if (flags == 0) return; - - /* start by allocating the entry arrays. */ - if (c->gsort == NULL || c->gsortsize < count) { - if (c->gsort != NULL) free(c->gsort); - c->gsortsize = count * 1.1; - if ((c->gsort = (struct entry *)malloc(sizeof(struct entry) * - (c->gsortsize + 1) * 13)) == NULL) - error("Failed to allocate sort memory."); - } - gsort = c->gsort; - - /* Does this cell have any progeny? */ - if (c->split) { - - /* Fill in the gaps within the progeny. */ - for (k = 0; k < 8; k++) { - if (c->progeny[k] == NULL) continue; - missing = flags & ~c->progeny[k]->gsorted; - if (missing) runner_dogsort(r, c->progeny[k], missing, 0); - } - - /* Loop over the 13 different sort arrays. */ - for (j = 0; j < 13; j++) { - - /* Has this sort array been flagged? */ - if (!(flags & (1 << j))) continue; - - /* Init the particle index offsets. */ - for (off[0] = 0, k = 1; k < 8; k++) - if (c->progeny[k - 1] != NULL) - off[k] = off[k - 1] + c->progeny[k - 1]->gcount; - else - off[k] = off[k - 1]; - - /* Init the entries and indices. */ - for (k = 0; k < 8; k++) { - inds[k] = k; - if (c->progeny[k] != NULL && c->progeny[k]->gcount > 0) { - fingers[k] = &c->progeny[k]->gsort[j * (c->progeny[k]->gcount + 1)]; - buff[k] = fingers[k]->d; - off[k] = off[k]; - } else - buff[k] = FLT_MAX; - } - - /* Sort the buffer. */ - for (i = 0; i < 7; i++) - for (k = i + 1; k < 8; k++) - if (buff[inds[k]] < buff[inds[i]]) { - temp_i = inds[i]; - inds[i] = inds[k]; - inds[k] = temp_i; - } - - /* For each entry in the new sort list. */ - finger = &gsort[j * (count + 1)]; - for (ind = 0; ind < count; ind++) { - - /* Copy the minimum into the new sort array. */ - finger[ind].d = buff[inds[0]]; - finger[ind].i = fingers[inds[0]]->i + off[inds[0]]; - - /* Update the buffer. */ - fingers[inds[0]] += 1; - buff[inds[0]] = fingers[inds[0]]->d; - - /* Find the smallest entry. */ - for (k = 1; k < 8 && buff[inds[k]] < buff[inds[k - 1]]; k++) { - temp_i = inds[k - 1]; - inds[k - 1] = inds[k]; - inds[k] = temp_i; - } - - } /* Merge. */ - - /* Add a sentinel. */ - gsort[j * (count + 1) + count].d = FLT_MAX; - gsort[j * (count + 1) + count].i = 0; - - /* Mark as sorted. */ - c->gsorted |= (1 << j); - - } /* loop over sort arrays. */ - - } /* progeny? */ - - /* Otherwise, just sort. */ - else { - - /* Fill the sort array. */ - for (k = 0; k < count; k++) { - px[0] = gparts[k].x[0]; - px[1] = gparts[k].x[1]; - px[2] = gparts[k].x[2]; - for (j = 0; j < 13; j++) - if (flags & (1 << j)) { - gsort[j * (count + 1) + k].i = k; - gsort[j * (count + 1) + k].d = px[0] * runner_shift[3 * j + 0] + - px[1] * runner_shift[3 * j + 1] + - px[2] * runner_shift[3 * j + 2]; - } - } - - /* Add the sentinel and sort. */ - for (j = 0; j < 13; j++) - if (flags & (1 << j)) { - gsort[j * (count + 1) + count].d = FLT_MAX; - gsort[j * (count + 1) + count].i = 0; - runner_dosort_ascending(&gsort[j * (count + 1)], count); - c->gsorted |= (1 << j); - } - } - - /* Verify the sorting. */ - /* for ( j = 0 ; j < 13 ; j++ ) { - if ( !( flags & (1 << j) ) ) - continue; - finger = &c->gsort[ j*(count + 1) ]; - for ( k = 1 ; k < count ; k++ ) { - if ( finger[k].d < finger[k-1].d ) - error( "Sorting failed, ascending array." ); - if ( finger[k].i < 0 || finger[k].i >= count ) - error( "Sorting failed, indices borked." ); - } - } */ +/* void runner_dogsort(struct runner *r, struct cell *c, int flags, int clock) { */ + +/* struct entry *finger; */ +/* struct entry *fingers[8]; */ +/* struct gpart *gparts = c->gparts; */ +/* struct entry *gsort; */ +/* int j, k, count = c->gcount; */ +/* int i, ind, off[8], inds[8], temp_i, missing; */ +/* // float shift[3]; */ +/* float buff[8], px[3]; */ + +/* TIMER_TIC */ + +/* /\* Clean-up the flags, i.e. filter out what's already been sorted. *\/ */ +/* flags &= ~c->gsorted; */ +/* if (flags == 0) return; */ + +/* /\* start by allocating the entry arrays. *\/ */ +/* if (c->gsort == NULL || c->gsortsize < count) { */ +/* if (c->gsort != NULL) free(c->gsort); */ +/* c->gsortsize = count * 1.1; */ +/* if ((c->gsort = (struct entry *)malloc(sizeof(struct entry) * */ +/* (c->gsortsize + 1) * 13)) == NULL) */ +/* error("Failed to allocate sort memory."); */ +/* } */ +/* gsort = c->gsort; */ + +/* /\* Does this cell have any progeny? *\/ */ +/* if (c->split) { */ + +/* /\* Fill in the gaps within the progeny. *\/ */ +/* for (k = 0; k < 8; k++) { */ +/* if (c->progeny[k] == NULL) continue; */ +/* missing = flags & ~c->progeny[k]->gsorted; */ +/* if (missing) runner_dogsort(r, c->progeny[k], missing, 0); */ +/* } */ + +/* /\* Loop over the 13 different sort arrays. *\/ */ +/* for (j = 0; j < 13; j++) { */ + +/* /\* Has this sort array been flagged? *\/ */ +/* if (!(flags & (1 << j))) continue; */ + +/* /\* Init the particle index offsets. *\/ */ +/* for (off[0] = 0, k = 1; k < 8; k++) */ +/* if (c->progeny[k - 1] != NULL) */ +/* off[k] = off[k - 1] + c->progeny[k - 1]->gcount; */ +/* else */ +/* off[k] = off[k - 1]; */ + +/* /\* Init the entries and indices. *\/ */ +/* for (k = 0; k < 8; k++) { */ +/* inds[k] = k; */ +/* if (c->progeny[k] != NULL && c->progeny[k]->gcount > 0) { */ +/* fingers[k] = &c->progeny[k]->gsort[j * (c->progeny[k]->gcount + 1)]; */ +/* buff[k] = fingers[k]->d; */ +/* off[k] = off[k]; */ +/* } else */ +/* buff[k] = FLT_MAX; */ +/* } */ + +/* /\* Sort the buffer. *\/ */ +/* for (i = 0; i < 7; i++) */ +/* for (k = i + 1; k < 8; k++) */ +/* if (buff[inds[k]] < buff[inds[i]]) { */ +/* temp_i = inds[i]; */ +/* inds[i] = inds[k]; */ +/* inds[k] = temp_i; */ +/* } */ + +/* /\* For each entry in the new sort list. *\/ */ +/* finger = &gsort[j * (count + 1)]; */ +/* for (ind = 0; ind < count; ind++) { */ + +/* /\* Copy the minimum into the new sort array. *\/ */ +/* finger[ind].d = buff[inds[0]]; */ +/* finger[ind].i = fingers[inds[0]]->i + off[inds[0]]; */ + +/* /\* Update the buffer. *\/ */ +/* fingers[inds[0]] += 1; */ +/* buff[inds[0]] = fingers[inds[0]]->d; */ + +/* /\* Find the smallest entry. *\/ */ +/* for (k = 1; k < 8 && buff[inds[k]] < buff[inds[k - 1]]; k++) { */ +/* temp_i = inds[k - 1]; */ +/* inds[k - 1] = inds[k]; */ +/* inds[k] = temp_i; */ +/* } */ + +/* } /\* Merge. *\/ */ + +/* /\* Add a sentinel. *\/ */ +/* gsort[j * (count + 1) + count].d = FLT_MAX; */ +/* gsort[j * (count + 1) + count].i = 0; */ + +/* /\* Mark as sorted. *\/ */ +/* c->gsorted |= (1 << j); */ + +/* } /\* loop over sort arrays. *\/ */ + +/* } /\* progeny? *\/ */ + +/* /\* Otherwise, just sort. *\/ */ +/* else { */ + +/* /\* Fill the sort array. *\/ */ +/* for (k = 0; k < count; k++) { */ +/* px[0] = gparts[k].x[0]; */ +/* px[1] = gparts[k].x[1]; */ +/* px[2] = gparts[k].x[2]; */ +/* for (j = 0; j < 13; j++) */ +/* if (flags & (1 << j)) { */ +/* gsort[j * (count + 1) + k].i = k; */ +/* gsort[j * (count + 1) + k].d = px[0] * runner_shift[3 * j + 0] + */ +/* px[1] * runner_shift[3 * j + 1] + */ +/* px[2] * runner_shift[3 * j + 2]; */ +/* } */ +/* } */ + +/* /\* Add the sentinel and sort. *\/ */ +/* for (j = 0; j < 13; j++) */ +/* if (flags & (1 << j)) { */ +/* gsort[j * (count + 1) + count].d = FLT_MAX; */ +/* gsort[j * (count + 1) + count].i = 0; */ +/* runner_dosort_ascending(&gsort[j * (count + 1)], count); */ +/* c->gsorted |= (1 << j); */ +/* } */ +/* } */ - if (clock) TIMER_TOC(timer_dosort); -} +/* /\* Verify the sorting. *\/ */ +/* /\* for ( j = 0 ; j < 13 ; j++ ) { */ +/* if ( !( flags & (1 << j) ) ) */ +/* continue; */ +/* finger = &c->gsort[ j*(count + 1) ]; */ +/* for ( k = 1 ; k < count ; k++ ) { */ +/* if ( finger[k].d < finger[k-1].d ) */ +/* error( "Sorting failed, ascending array." ); */ +/* if ( finger[k].i < 0 || finger[k].i >= count ) */ +/* error( "Sorting failed, indices borked." ); */ +/* } */ +/* } *\/ */ + +/* if (clock) TIMER_TOC(timer_dosort); */ +/* } */ /** * @brief Initialize the particles before the density calculation -- GitLab From 3f6051643f210e839955ad5b55088cb5b2a74bbc Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 16 May 2016 23:59:57 +0100 Subject: [PATCH 09/72] No more external gravity debugging stuff --- src/runner.c | 208 +-------------------------------------------------- 1 file changed, 1 insertion(+), 207 deletions(-) diff --git a/src/runner.c b/src/runner.c index d45af599b..9e920eec6 100644 --- a/src/runner.c +++ b/src/runner.c @@ -73,21 +73,6 @@ const float runner_shift[13 * 3] = { const char runner_flip[27] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -/* #define MY_CELL 428428428 */ -/* #define DX 0.1 */ -/* #define NX 1000 */ -/* #define CELL_ID \ */ -/* ((int)(c->loc[0] / DX) * NX *NX + (int)(c->loc[1] / DX) * NX + \ */ -/* (int)(c->loc[2] / DX)) */ -/* #define OUT \ */ -/* if (CELL_ID == MY_CELL) { \ */ -/* message(" cell= %d gcount=%d time=%f \n", CELL_ID, c->gcount, - * r->e->time); \ */ -/* } */ -/* #define OUT message(" cell %d %d %f \n",CELL_ID, c->count, r->e->time); */ -/* #define OUT if(CELL_ID == MY_CELL) message("\n cell %f %f %f %d %d */ -/* %f\n",c->loc[0],c->loc[1],c->loc[2], CELL_ID, c->count, r->e->time); */ - /* Import the density loop functions. */ #define FUNCTION density #include "runner_doiact.h" @@ -128,7 +113,7 @@ void runner_dograv_external(struct runner *r, struct cell *c, int timer) { OUT; #endif - /* Loop over the parts in this cell. */ + /* Loop over the gparts in this cell. */ for (i = 0; i < gcount; i++) { /* Get a direct pointer on the part. */ @@ -138,52 +123,6 @@ void runner_dograv_external(struct runner *r, struct cell *c, int timer) { if (g->ti_end <= ti_current) { external_gravity(potential, constants, g); - - /* /\* check for energy and angular momentum conservation - begin by */ - /* * synchronizing velocity*\/ */ - /* const float dx = g->x[0] - r->e->potential->point_mass.x; */ - /* const float dy = g->x[1] - r->e->potential->point_mass.y; */ - /* const float dz = g->x[2] - r->e->potential->point_mass.z; */ - /* const float dr = sqrtf((dx * dx) + (dy * dy) + (dz * dz)); */ - /* const float rinv = 1.f / sqrtf(dx * dx + dy * dy + dz * dz); */ - - /* const int current_dti = g->ti_end - g->ti_begin; */ - /* const float dt = 0.5f * current_dti * r->e->timeBase; */ - /* const float vx = g->v_full[0] + dt * g->a_grav[0]; */ - /* const float vy = g->v_full[1] + dt * g->a_grav[1]; */ - /* const float vz = g->v_full[2] + dt * g->a_grav[2]; */ - - /* /\* E/L *\/ */ - /* float L[3], E; */ - /* E = 0.5 * ((vx * vx) + (vy * vy) + (vz * vz)) - */ - /* r->e->physical_constants->newton_gravity * */ - /* r->e->potential->point_mass.mass * rinv; */ - /* L[0] = dy * vz - dz * vy; */ - /* L[1] = dz * vx - dx * vz; */ - /* L[2] = dx * vy - dy * vx; */ - /* if (abs(g->id) == 1) { */ - /* float v2 = vx * vx + vy * vy + vz * vz; */ - /* float fg = r->e->physical_constants->newton_gravity * */ - /* r->e->potential->point_mass.mass * rinv; */ - /* float fga = sqrtf((g->a_grav[0] * g->a_grav[0]) + */ - /* (g->a_grav[1] * g->a_grav[1]) + */ - /* (g->a_grav[2] * g->a_grav[2])) * */ - /* dr; */ - /* // message("grav_external time= %f\t V_c^2= %f GM/r= %f E= %f L[2]= - * %f */ - /* // x= %f y= %f vx= %f vy= %f\n", r->e->time, v2, fg, E, L[2], - * g->x[0], */ - /* // g->x[1], vx, vy); */ - /* message("%f\t %f %f %f %f %f %f %f %f %f %f %f %f %f\n", r->e->time, - */ - /* g->tx, g->tv, dt, v2, fg, fga, dr, E, L[2], g->x[0], g->x[1], - */ - /* vx, vy); */ - /* /\* message(" G=%e M=%e\n", r->e->physical_constants->newton_gravity, - */ - /* * r->e->potential->point_mass.mass); *\/ */ - /* /\* exit(-1); *\/ */ - /* } */ } } if (timer) TIMER_TOC(timer_dograv_external); @@ -423,151 +362,6 @@ void runner_dosort(struct runner *r, struct cell *c, int flags, int clock) { if (clock) TIMER_TOC(timer_dosort); } -/* void runner_dogsort(struct runner *r, struct cell *c, int flags, int clock) { */ - -/* struct entry *finger; */ -/* struct entry *fingers[8]; */ -/* struct gpart *gparts = c->gparts; */ -/* struct entry *gsort; */ -/* int j, k, count = c->gcount; */ -/* int i, ind, off[8], inds[8], temp_i, missing; */ -/* // float shift[3]; */ -/* float buff[8], px[3]; */ - -/* TIMER_TIC */ - -/* /\* Clean-up the flags, i.e. filter out what's already been sorted. *\/ */ -/* flags &= ~c->gsorted; */ -/* if (flags == 0) return; */ - -/* /\* start by allocating the entry arrays. *\/ */ -/* if (c->gsort == NULL || c->gsortsize < count) { */ -/* if (c->gsort != NULL) free(c->gsort); */ -/* c->gsortsize = count * 1.1; */ -/* if ((c->gsort = (struct entry *)malloc(sizeof(struct entry) * */ -/* (c->gsortsize + 1) * 13)) == NULL) */ -/* error("Failed to allocate sort memory."); */ -/* } */ -/* gsort = c->gsort; */ - -/* /\* Does this cell have any progeny? *\/ */ -/* if (c->split) { */ - -/* /\* Fill in the gaps within the progeny. *\/ */ -/* for (k = 0; k < 8; k++) { */ -/* if (c->progeny[k] == NULL) continue; */ -/* missing = flags & ~c->progeny[k]->gsorted; */ -/* if (missing) runner_dogsort(r, c->progeny[k], missing, 0); */ -/* } */ - -/* /\* Loop over the 13 different sort arrays. *\/ */ -/* for (j = 0; j < 13; j++) { */ - -/* /\* Has this sort array been flagged? *\/ */ -/* if (!(flags & (1 << j))) continue; */ - -/* /\* Init the particle index offsets. *\/ */ -/* for (off[0] = 0, k = 1; k < 8; k++) */ -/* if (c->progeny[k - 1] != NULL) */ -/* off[k] = off[k - 1] + c->progeny[k - 1]->gcount; */ -/* else */ -/* off[k] = off[k - 1]; */ - -/* /\* Init the entries and indices. *\/ */ -/* for (k = 0; k < 8; k++) { */ -/* inds[k] = k; */ -/* if (c->progeny[k] != NULL && c->progeny[k]->gcount > 0) { */ -/* fingers[k] = &c->progeny[k]->gsort[j * (c->progeny[k]->gcount + 1)]; */ -/* buff[k] = fingers[k]->d; */ -/* off[k] = off[k]; */ -/* } else */ -/* buff[k] = FLT_MAX; */ -/* } */ - -/* /\* Sort the buffer. *\/ */ -/* for (i = 0; i < 7; i++) */ -/* for (k = i + 1; k < 8; k++) */ -/* if (buff[inds[k]] < buff[inds[i]]) { */ -/* temp_i = inds[i]; */ -/* inds[i] = inds[k]; */ -/* inds[k] = temp_i; */ -/* } */ - -/* /\* For each entry in the new sort list. *\/ */ -/* finger = &gsort[j * (count + 1)]; */ -/* for (ind = 0; ind < count; ind++) { */ - -/* /\* Copy the minimum into the new sort array. *\/ */ -/* finger[ind].d = buff[inds[0]]; */ -/* finger[ind].i = fingers[inds[0]]->i + off[inds[0]]; */ - -/* /\* Update the buffer. *\/ */ -/* fingers[inds[0]] += 1; */ -/* buff[inds[0]] = fingers[inds[0]]->d; */ - -/* /\* Find the smallest entry. *\/ */ -/* for (k = 1; k < 8 && buff[inds[k]] < buff[inds[k - 1]]; k++) { */ -/* temp_i = inds[k - 1]; */ -/* inds[k - 1] = inds[k]; */ -/* inds[k] = temp_i; */ -/* } */ - -/* } /\* Merge. *\/ */ - -/* /\* Add a sentinel. *\/ */ -/* gsort[j * (count + 1) + count].d = FLT_MAX; */ -/* gsort[j * (count + 1) + count].i = 0; */ - -/* /\* Mark as sorted. *\/ */ -/* c->gsorted |= (1 << j); */ - -/* } /\* loop over sort arrays. *\/ */ - -/* } /\* progeny? *\/ */ - -/* /\* Otherwise, just sort. *\/ */ -/* else { */ - -/* /\* Fill the sort array. *\/ */ -/* for (k = 0; k < count; k++) { */ -/* px[0] = gparts[k].x[0]; */ -/* px[1] = gparts[k].x[1]; */ -/* px[2] = gparts[k].x[2]; */ -/* for (j = 0; j < 13; j++) */ -/* if (flags & (1 << j)) { */ -/* gsort[j * (count + 1) + k].i = k; */ -/* gsort[j * (count + 1) + k].d = px[0] * runner_shift[3 * j + 0] + */ -/* px[1] * runner_shift[3 * j + 1] + */ -/* px[2] * runner_shift[3 * j + 2]; */ -/* } */ -/* } */ - -/* /\* Add the sentinel and sort. *\/ */ -/* for (j = 0; j < 13; j++) */ -/* if (flags & (1 << j)) { */ -/* gsort[j * (count + 1) + count].d = FLT_MAX; */ -/* gsort[j * (count + 1) + count].i = 0; */ -/* runner_dosort_ascending(&gsort[j * (count + 1)], count); */ -/* c->gsorted |= (1 << j); */ -/* } */ -/* } */ - -/* /\* Verify the sorting. *\/ */ -/* /\* for ( j = 0 ; j < 13 ; j++ ) { */ -/* if ( !( flags & (1 << j) ) ) */ -/* continue; */ -/* finger = &c->gsort[ j*(count + 1) ]; */ -/* for ( k = 1 ; k < count ; k++ ) { */ -/* if ( finger[k].d < finger[k-1].d ) */ -/* error( "Sorting failed, ascending array." ); */ -/* if ( finger[k].i < 0 || finger[k].i >= count ) */ -/* error( "Sorting failed, indices borked." ); */ -/* } */ -/* } *\/ */ - -/* if (clock) TIMER_TOC(timer_dosort); */ -/* } */ - /** * @brief Initialize the particles before the density calculation * -- GitLab From a6d9a03d3c25fc8483f75decce5c8064de58ef61 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 17 May 2016 18:18:03 +0100 Subject: [PATCH 10/72] Backup --- src/{runner_doiact_grav.h => runner_doiact_grav_old.h} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{runner_doiact_grav.h => runner_doiact_grav_old.h} (100%) diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav_old.h similarity index 100% rename from src/runner_doiact_grav.h rename to src/runner_doiact_grav_old.h -- GitLab From 27493025dfc1517fa471b1cdae34ed5d4bc7e5a6 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 17 May 2016 19:30:40 +0100 Subject: [PATCH 11/72] Implemented the (unsoftened) pp and pm calculations --- src/runner_doiact_grav.h | 212 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 src/runner_doiact_grav.h diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h new file mode 100644 index 000000000..396206eb7 --- /dev/null +++ b/src/runner_doiact_grav.h @@ -0,0 +1,212 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk) + * 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + ******************************************************************************/ +#ifndef SWIFT_RUNNER_DOIACT_GRAV_H +#define SWIFT_RUNNER_DOIACT_GRAV_H + +/* Includes. */ +#include "cell.h" +#include "clocks.h" +#include "part.h" + +/** + * @brief Compute the recursive upward sweep, i.e. construct the + * multipoles in a cell hierarchy. + * + * @param r The #runner. + * @param c The top-level #cell. + */ +void runner_dograv_up(struct runner *r, struct cell *c) { + + if (c->split) {/* Regular node */ + + /* Recurse. */ + for (int k = 0; k < 8; k++) + if (c->progeny[k] != NULL) runner_dograv_up(r, c->progeny[k]); + + /* Collect the multipoles from the progeny. */ + multipole_reset(&c->multipole); + for (int k = 0; k < 8; k++) { + if (c->progeny[k] != NULL) + multipole_add(&c->multipole, &c->progeny[k]->multipole); + } + + } else {/* Leaf node. */ + + /* Just construct the multipole from the gparts. */ + multipole_init(&c->multipole, c->gparts, c->gcount); + } +} + +/** + * @brief Computes the interaction of all the particles in a cell with the + * multipole of another cell. + * + * @param r The #runner. + * @param ci The #cell with particles to interct. + * @param cj The #cell with the multipole. + */ +void runner_dograv_pm(struct runner *r, struct cell *ci, struct cell *cj) { + + const struct engine *e = r->e; + const int gcount = ci->gcount; + struct gpart *restrict gparts = ci->gparts; + const struct multipole multi = cj->multipole; + const int ti_current = e->ti_current; + + TIMER_TIC; + + /* Anything to do here? */ + if (ci->ti_end_min > ti_current) return; + + if (gcount == 0) error("Empty cell!"); // MATTHIEU sanity check + + if (multi.mass == 0.0) // MATTHIEU sanity check + error("Multipole does not seem to have been set."); + + /* Loop over every particle in leaf. */ + for (int pid = 0; pid < gcount; pid++) { + + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &gparts[pid]; + + if (gp->ti_end > ti_current) continue; + + /* Compute the pairwise distance. */ + const float dx[3] = {multi.CoM[0] - gp->x[0], // x + multi.CoM[1] - gp->x[1], // y + multi.CoM[2] - gp->x[2]}; // z + const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; + + /* Apply the gravitational acceleration. */ + const float ir = 1.0f / sqrtf(r2); + const float mrinv3 = multi.mass * ir * ir * ir; + +#if multipole_order < 2 + + /* 0th and 1st order terms */ + gp->a_grav[0] += mrinv3 * dx[0]; + gp->a_grav[1] += mrinv3 * dx[1]; + gp->a_grav[2] += mrinv3 * dx[2]; + +#elif multipole_order == 2 + + /* Terms up to 2nd order (quadrupole) */ + + /* Follows the notation in Bonsai */ + const float mrinv5 = mrinv3 * ir * ir; + const float mrinv7 = mrinv5 * ir * ir; + + const float D1 = -mrinv3; + const float D2 = 3.f * mrinv5; + const float D3 = -15.f * mrinv7; + + const float q = multi.I_xx + multi.I_yy + multi.I_zz; + const float qRx = + multi.I_xx * dx[0] + multi.I_xy * dx[1] + multi.I_xz * dx[2]; + const float qRy = + multi.I_xy * dx[0] + multi.I_yy * dx[1] + multi.I_yz * dx[2]; + const float qRz = + multi.I_xz * dx[0] + multi.I_yz * dx[1] + multi.I_zz * dx[2]; + const float qRR = qRx * dx[0] + qRy * dx[1] + qRz * dx[2]; + const float C = D1 + 0.5f * D2 * q + 0.5f * D3 * qRR; + + gp->a_grav[0] -= C * dx[0] + D2 * qRx; + gp->a_grav[1] -= C * dx[1] + D2 * qRy; + gp->a_grav[2] -= C * dx[2] + D2 * qRz; + +#else +#error "Multipoles of order >2 not yet implemented." +#endif + } + + TIMER_TOC(TIMER_DOPAIR); // MATTHIEU +} + +/** + * @brief Computes the interaction of all the particles in a cell with all the + * particles of another cell. + * + * @param r The #runner. + * @param ci The first #cell. + * @param cj The other #cell. + */ +void runner_dograv_pp(struct runner *r, struct cell *ci, struct cell *cj) { + + const struct engine *e = r->e; + const int gcount_i = ci->gcount; + const int gcount_j = cj->gcount; + struct gpart *restrict gparts_i = ci->gparts; + struct gpart *restrict gparts_j = cj->gparts; + const int ti_current = e->ti_current; + + TIMER_TIC; + + /* Anything to do here? */ + if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; + + if(ci->h[0] != cj->h[0]) // MATTHIEU sanity check + error("Non matching cell sizes !! h_i=%f h_j=%f\n", ci->h[0], cj->h[0]); + + /* Loop over all particles in ci... */ + for (int pid = 0; pid < gcount_i; pid++) { + + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gpi = &gparts_i[pid]; + const float mi = gpi->mass; + + /* Loop over every particle in the other cell. */ + for (int pjd = 0; pjd < gcount_j; pjd++) { + + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gpj = &gparts_j[pjd]; + const float mj = gpj->mass; + + /* Compute the pairwise distance. */ + const float dx[3] = {gpi->x[0] - gpj->x[0], // x + gpi->x[1] - gpj->x[1], // y + gpi->x[2] - gpj->x[2]}; // z + const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; + + /* Apply the gravitational acceleration. */ + const float ir = 1.0f / sqrtf(r2); + const float w = ir * ir * ir; + const float wdx[3] = {w*dx[0], w*dx[1], w*dx[2]}; + + if(gpi->ti_end <= ti_current) { + gpi->a_grav[0] -= wdx[0] * mj; + gpi->a_grav[1] -= wdx[1] * mj; + gpi->a_grav[2] -= wdx[2] * mj; + } + if(gpj->ti_end <= ti_current) { + gpj->a_grav[0] += wdx[0] * mi; + gpj->a_grav[1] += wdx[1] * mi; + gpj->a_grav[2] += wdx[2] * mi; + } + + } + + } + + + + TIMER_TOC(TIMER_DOPAIR); // MATTHIEU +} + +#endif /* SWIFT_RUNNER_DOIACT_GRAV_H */ -- GitLab From fad655a6dd85e0a692eaf1de22a2a39c0eb0114d Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 17 May 2016 21:45:57 +0100 Subject: [PATCH 12/72] Added function to compute interactions within a cell --- src/const.h | 2 + src/runner_doiact_grav.h | 133 ++++++++++++++++++++++++++++++--------- 2 files changed, 104 insertions(+), 31 deletions(-) diff --git a/src/const.h b/src/const.h index 87852ba5e..e6941f2ca 100644 --- a/src/const.h +++ b/src/const.h @@ -61,4 +61,6 @@ /* Gravity properties */ #define EXTERNAL_POTENTIAL_POINTMASS +#define SANITY_CHECK + #endif /* SWIFT_CONST_H */ diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 396206eb7..1007b09ed 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -62,7 +62,8 @@ void runner_dograv_up(struct runner *r, struct cell *c) { * @param ci The #cell with particles to interct. * @param cj The #cell with the multipole. */ -void runner_dograv_pm(struct runner *r, struct cell *ci, struct cell *cj) { +__attribute__((always_inline)) INLINE static void runner_dograv_pair_pm( + struct runner *r, struct cell *ci, struct cell *cj) { const struct engine *e = r->e; const int gcount = ci->gcount; @@ -72,14 +73,16 @@ void runner_dograv_pm(struct runner *r, struct cell *ci, struct cell *cj) { TIMER_TIC; +#ifdef SANITY_CHECK + if (gcount == 0) error("Empty cell!"); // MATTHIEU sanity check + + if (multi.mass == 0.0) // MATTHIEU sanity check + error("Multipole does not seem to have been set."); +#endif + /* Anything to do here? */ if (ci->ti_end_min > ti_current) return; - if (gcount == 0) error("Empty cell!"); // MATTHIEU sanity check - - if (multi.mass == 0.0) // MATTHIEU sanity check - error("Multipole does not seem to have been set."); - /* Loop over every particle in leaf. */ for (int pid = 0; pid < gcount; pid++) { @@ -87,7 +90,7 @@ void runner_dograv_pm(struct runner *r, struct cell *ci, struct cell *cj) { struct gpart *restrict gp = &gparts[pid]; if (gp->ti_end > ti_current) continue; - + /* Compute the pairwise distance. */ const float dx[3] = {multi.CoM[0] - gp->x[0], // x multi.CoM[1] - gp->x[1], // y @@ -146,8 +149,11 @@ void runner_dograv_pm(struct runner *r, struct cell *ci, struct cell *cj) { * @param r The #runner. * @param ci The first #cell. * @param cj The other #cell. + * + * @todo Use a local cache for the particles. */ -void runner_dograv_pp(struct runner *r, struct cell *ci, struct cell *cj) { +__attribute__((always_inline)) INLINE static void runner_dograv_pair_pp( + struct runner *r, struct cell *ci, struct cell *cj) { const struct engine *e = r->e; const int gcount_i = ci->gcount; @@ -158,55 +164,120 @@ void runner_dograv_pp(struct runner *r, struct cell *ci, struct cell *cj) { TIMER_TIC; +#ifdef SANITY_CHECK + if (ci->h[0] != cj->h[0]) // MATTHIEU sanity check + error("Non matching cell sizes !! h_i=%f h_j=%f\n", ci->h[0], cj->h[0]); +#endif + /* Anything to do here? */ if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; - if(ci->h[0] != cj->h[0]) // MATTHIEU sanity check - error("Non matching cell sizes !! h_i=%f h_j=%f\n", ci->h[0], cj->h[0]); - /* Loop over all particles in ci... */ for (int pid = 0; pid < gcount_i; pid++) { /* Get a hold of the ith part in ci. */ struct gpart *restrict gpi = &gparts_i[pid]; const float mi = gpi->mass; - + /* Loop over every particle in the other cell. */ for (int pjd = 0; pjd < gcount_j; pjd++) { - /* Get a hold of the ith part in ci. */ + /* Get a hold of the jth part in cj. */ struct gpart *restrict gpj = &gparts_j[pjd]; const float mj = gpj->mass; - + /* Compute the pairwise distance. */ const float dx[3] = {gpi->x[0] - gpj->x[0], // x - gpi->x[1] - gpj->x[1], // y - gpi->x[2] - gpj->x[2]}; // z + gpi->x[1] - gpj->x[1], // y + gpi->x[2] - gpj->x[2]}; // z const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; - + /* Apply the gravitational acceleration. */ const float ir = 1.0f / sqrtf(r2); const float w = ir * ir * ir; - const float wdx[3] = {w*dx[0], w*dx[1], w*dx[2]}; - - if(gpi->ti_end <= ti_current) { - gpi->a_grav[0] -= wdx[0] * mj; - gpi->a_grav[1] -= wdx[1] * mj; - gpi->a_grav[2] -= wdx[2] * mj; + const float wdx[3] = {w * dx[0], w * dx[1], w * dx[2]}; + + if (gpi->ti_end <= ti_current) { + gpi->a_grav[0] -= wdx[0] * mj; + gpi->a_grav[1] -= wdx[1] * mj; + gpi->a_grav[2] -= wdx[2] * mj; } - if(gpj->ti_end <= ti_current) { - gpj->a_grav[0] += wdx[0] * mi; - gpj->a_grav[1] += wdx[1] * mi; - gpj->a_grav[2] += wdx[2] * mi; + if (gpj->ti_end <= ti_current) { + gpj->a_grav[0] += wdx[0] * mi; + gpj->a_grav[1] += wdx[1] * mi; + gpj->a_grav[2] += wdx[2] * mi; } - } - } - - TIMER_TOC(TIMER_DOPAIR); // MATTHIEU } +/** + * @brief Computes the interaction of all the particles in a cell directly + * + * @param r The #runner. + * @param ci The first #cell. + * + * @todo Use a local cache for the particles. + */ +__attribute__((always_inline)) + INLINE static void runner_dograv_self_pp(struct runner *r, struct cell *c) { + + const struct engine *e = r->e; + const int gcount = c->gcount; + struct gpart *restrict gparts = c->gparts; + const int ti_current = e->ti_current; + + TIMER_TIC; + +#ifdef SANITY_CHECK + if (c->gcount == 0) // MATTHIEU sanity check + error("Empty cell !"); +#endif + + /* Anything to do here? */ + if (c->ti_end_min > ti_current) return; + + /* Loop over all particles in ci... */ + for (int pid = 0; pid < gcount; pid++) { + + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gpi = &gparts[pid]; + const float mi = gpi->mass; + + /* Loop over every particle in the other cell. */ + for (int pjd = pid + 1; pjd < gcount; pjd++) { + + /* Get a hold of the jth part in ci. */ + struct gpart *restrict gpj = &gparts[pjd]; + const float mj = gpj->mass; + + /* Compute the pairwise distance. */ + const float dx[3] = {gpi->x[0] - gpj->x[0], // x + gpi->x[1] - gpj->x[1], // y + gpi->x[2] - gpj->x[2]}; // z + const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; + + /* Apply the gravitational acceleration. */ + const float ir = 1.0f / sqrtf(r2); + const float w = ir * ir * ir; + const float wdx[3] = {w * dx[0], w * dx[1], w * dx[2]}; + + if (gpi->ti_end <= ti_current) { + gpi->a_grav[0] -= wdx[0] * mj; + gpi->a_grav[1] -= wdx[1] * mj; + gpi->a_grav[2] -= wdx[2] * mj; + } + if (gpj->ti_end <= ti_current) { + gpj->a_grav[0] += wdx[0] * mi; + gpj->a_grav[1] += wdx[1] * mi; + gpj->a_grav[2] += wdx[2] * mi; + } + } + } + + TIMER_TOC(TIMER_DOSELF); // MATTHIEU +} + #endif /* SWIFT_RUNNER_DOIACT_GRAV_H */ -- GitLab From 8ab00c1b2f3dd6485e77cca24e446fbc31b96787 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 17 May 2016 22:04:30 +0100 Subject: [PATCH 13/72] Added a tool function to compute all gravity accelerations with the brute-force algorithm --- src/tools.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/tools.h | 1 + 2 files changed, 56 insertions(+) diff --git a/src/tools.c b/src/tools.c index 7b468426b..db7285d91 100644 --- a/src/tools.c +++ b/src/tools.c @@ -480,3 +480,58 @@ void shuffle_particles(struct part *parts, const int count) { } else error("Array not big enough to shuffle!"); } + +/** + * @brief Computes the forces between all g-particles using the N^2 algorithm + * + * Overwrites the accelerations of the gparts with the values. + * Do not use for actual runs. + * + * @brief gparts The array of particles. + * @brief gcount The number of particles. + */ +void gravity_n2(struct gpart *gparts, const int gcount) { + + /* Reset everything */ + for (int pid = 0; pid < gcount; pid++) { + struct gpart *restrict gpi = &gparts[pid]; + gpi->a_grav[0] = 0.f; + gpi->a_grav[1] = 0.f; + gpi->a_grav[2] = 0.f; + } + + /* Loop over all particles in ci... */ + for (int pid = 0; pid < gcount; pid++) { + + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gpi = &gparts[pid]; + const float mi = gpi->mass; + + /* Loop over every particle in the other cell. */ + for (int pjd = pid + 1; pjd < gcount; pjd++) { + + /* Get a hold of the jth part in ci. */ + struct gpart *restrict gpj = &gparts[pjd]; + const float mj = gpj->mass; + + /* Compute the pairwise distance. */ + const float dx[3] = {gpi->x[0] - gpj->x[0], // x + gpi->x[1] - gpj->x[1], // y + gpi->x[2] - gpj->x[2]}; // z + const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; + + /* Apply the gravitational acceleration. */ + const float ir = 1.0f / sqrtf(r2); + const float w = ir * ir * ir; + const float wdx[3] = {w * dx[0], w * dx[1], w * dx[2]}; + + gpi->a_grav[0] -= wdx[0] * mj; + gpi->a_grav[1] -= wdx[1] * mj; + gpi->a_grav[2] -= wdx[2] * mj; + + gpj->a_grav[0] += wdx[0] * mi; + gpj->a_grav[1] += wdx[1] * mi; + gpj->a_grav[2] += wdx[2] * mi; + } + } +} diff --git a/src/tools.h b/src/tools.h index 8e0212652..90bc4da01 100644 --- a/src/tools.h +++ b/src/tools.h @@ -40,5 +40,6 @@ void pairs_n2(double *dim, struct part *__restrict__ parts, int N, double random_uniform(double a, double b); void shuffle_particles(struct part *parts, const int count); +void gravity_n2(struct gpart *gparts, const int gcount); #endif /* SWIFT_TOOL_H */ -- GitLab From ee51bafffffe4e3df764d097d2c63dce60774f1e Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 26 May 2016 18:31:26 +0100 Subject: [PATCH 14/72] Post-merge corrections --- src/runner.c | 6 +- src/runner_doiact_grav.h | 174 +-------------------------------------- 2 files changed, 4 insertions(+), 176 deletions(-) diff --git a/src/runner.c b/src/runner.c index c59c80ffb..5921691fb 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1183,9 +1183,9 @@ void *runner_main(void *data) { case task_type_grav_up: runner_dograv_up(r, t->ci); break; - case task_type_grav_down: - runner_dograv_down(r, t->ci); - break; + /* case task_type_grav_down: */ + /* runner_dograv_down(r, t->ci); */ + /* break; */ case task_type_grav_external: runner_do_grav_external(r, t->ci, 1); break; diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index a4d34e802..5ea19adf5 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -25,178 +25,6 @@ #include "clocks.h" #include "part.h" -/** - * @brief Compute the sorted gravity interactions between a cell pair. - * - * @param r The #runner. - * @param ci The first #cell. - * @param cj The second #cell. - */ - -void runner_dopair_grav_new(struct runner *r, struct cell *ci, - struct cell *cj) { - - struct engine *restrict e = r->e; - int pid, pjd, k, sid; - double rshift, shift[3] = {0.0, 0.0, 0.0}, nshift[3]; - struct entry *restrict sort_i, *restrict sort_j; - struct gpart *restrict pi, *restrict pj, *restrict parts_i, *restrict parts_j; - double pix[3]; - float dx[3], r2, h_max, di, dj; - int count_i, count_j, cnj, cnj_new; - const int ti_current = e->ti_current; - struct multipole m; -#ifdef VECTORIZE - int icount = 0; - float r2q[VEC_SIZE] __attribute__((aligned(16))); - float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); - struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; -#endif - TIMER_TIC - - /* Anything to do here? */ - if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; - - /* Get the sort ID. */ - sid = space_getsid(e->s, &ci, &cj, shift); - - /* Make sure the cells are sorted. */ - runner_dogsort(r, ci, (1 << sid), 0); - runner_dogsort(r, cj, (1 << sid), 0); - - /* Have the cells been sorted? */ - if (!(ci->gsorted & (1 << sid)) || !(cj->gsorted & (1 << sid))) - error("Trying to interact unsorted cells."); - - /* Get the cutoff shift. */ - for (rshift = 0.0, k = 0; k < 3; k++) - rshift += shift[k] * runner_shift[3 * sid + k]; - - /* Pick-out the sorted lists. */ - sort_i = &ci->gsort[sid * (ci->count + 1)]; - sort_j = &cj->gsort[sid * (cj->count + 1)]; - - /* Get some other useful values. */ - h_max = - sqrtf(ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]) * - const_theta_max; - count_i = ci->gcount; - count_j = cj->gcount; - parts_i = ci->gparts; - parts_j = cj->gparts; - cnj = count_j; - multipole_reset(&m); - nshift[0] = -shift[0]; - nshift[1] = -shift[1]; - nshift[2] = -shift[2]; - - /* Loop over the parts in ci. */ - for (pid = count_i - 1; pid >= 0; pid--) { - - /* Get a hold of the ith part in ci. */ - pi = &parts_i[sort_i[pid].i]; - if (pi->ti_end > ti_current) continue; - di = sort_i[pid].d + h_max - rshift; - - for (k = 0; k < 3; k++) pix[k] = pi->x[k] - shift[k]; - - /* Loop over the parts in cj. */ - for (pjd = 0; pjd < cnj && sort_j[pjd].d < di; pjd++) { - - /* Get a pointer to the jth particle. */ - pj = &parts_j[sort_j[pjd].i]; - - /* Compute the pairwise distance. */ - r2 = 0.0f; - for (k = 0; k < 3; k++) { - dx[k] = pix[k] - pj->x[k]; - r2 += dx[k] * dx[k]; - } - -#ifndef VECTORIZE - - // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 ) - // message( "interacting particles pi=%lli and pj=%lli with r=%.3e in - // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long - // long int)ci) / sizeof(struct cell) , ((long long int)cj) / - // sizeof(struct cell) ); - - runner_iact_grav(r2, dx, pi, pj); - -#else - - /* Add this interaction to the queue. */ - r2q[icount] = r2; - dxq[3 * icount + 0] = dx[0]; - dxq[3 * icount + 1] = dx[1]; - dxq[3 * icount + 2] = dx[2]; - piq[icount] = pi; - pjq[icount] = pj; - icount += 1; - - /* Flush? */ - if (icount == VEC_SIZE) { - runner_iact_vec_grav(r2q, dxq, piq, pjq); - icount = 0; - } - -#endif - - } /* loop over the parts in cj. */ - - /* Set the new limit. */ - cnj_new = pjd; - - /* Add trailing parts to the multipole. */ - for (pjd = cnj_new; pjd < cnj; pjd++) { - - /* Add the part to the multipole. */ - multipole_addpart(&m, &parts_j[sort_j[pjd].i]); - - } /* add trailing parts to the multipole. */ - - /* Set the new cnj. */ - cnj = cnj_new; - - /* Interact the ith particle with the multipole. */ - multipole_iact_mp(&m, pi, nshift); - - } /* loop over the parts in ci. */ - -#ifdef VECTORIZE - /* Pick up any leftovers. */ - if (icount > 0) - for (k = 0; k < icount; k++) - runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); -#endif - - /* Re-set the multipole. */ - multipole_reset(&m); - - /* Loop over the parts in cj and interact with the multipole in ci. */ - for (pid = count_i - 1, pjd = 0; pjd < count_j; pjd++) { - - /* Get the position of pj along the axis. */ - dj = sort_j[pjd].d - h_max + rshift; - - /* Add any left-over parts in cell_i to the multipole. */ - while (pid >= 0 && sort_i[pid].d < dj) { - - /* Add this particle to the multipole. */ - multipole_addpart(&m, &parts_i[sort_i[pid].i]); - - /* Decrease pid. */ - pid -= 1; - } - - /* Interact pj with the multipole. */ - multipole_iact_mp(&m, &parts_j[sort_j[pjd].i], shift); - - } /* loop over the parts in cj and interact with the multipole. */ - - TIMER_TOC(TIMER_DOPAIR); -} - /** * @brief Compute the recursive upward sweep, i.e. construct the * multipoles in a cell hierarchy. @@ -389,7 +217,7 @@ __attribute__((always_inline)) INLINE static void runner_dograv_pair_pp( * @brief Computes the interaction of all the particles in a cell directly * * @param r The #runner. - * @param ci The first #cell. + * @param c The #cell. * * @todo Use a local cache for the particles. */ -- GitLab From 3283721bdc5599024c67ad0cd281848937b41d99 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 31 May 2016 22:02:19 +0100 Subject: [PATCH 15/72] New function to test whether cells are direct neighours or not --- src/runner_doiact_grav.h | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 5ea19adf5..7e2293ba9 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -54,6 +54,34 @@ void runner_dograv_up(struct runner *r, struct cell *c) { } } +/** + * @brief Checks whether the cells are direct neighbours ot not. Both cells have + * to be of the same size + * + */ +__attribute__((always_inline)) INLINE static +int are_neighbours(const struct cell *restrict ci, const struct cell *restrict cj) { + +#ifdef SANITY_CHECKS + if (ci->h[0] != cj->h[0]) + error(" Cells of different size in distance calculation."); +#endif + + /* Maximum allowed distance */ + const float min_dist = ci->h[0]; + + /* (Manhattan) Distance between the cells */ + for (int k = 0; k < 3; k++) { + const float center_i = ci->loc[k]; + const float center_j = cj->loc[k]; + if (fabsf(center_i - center_j) > min_dist) return 0; + } + + return 1; +} + + + /** * @brief Computes the interaction of all the particles in a cell with the * multipole of another cell. @@ -63,7 +91,7 @@ void runner_dograv_up(struct runner *r, struct cell *c) { * @param cj The #cell with the multipole. */ __attribute__((always_inline)) INLINE static void runner_dograv_pair_pm( - struct runner *r, struct cell *ci, struct cell *cj) { + const struct runner *r, const struct cell *restrict ci, const struct cell *restrict cj) { const struct engine *e = r->e; const int gcount = ci->gcount; -- GitLab From 6b7a9e24fbfc94ff0671627fef72fb660001afff Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 1 Jun 2016 00:00:32 +0100 Subject: [PATCH 16/72] Barnes-Hut tasks now ready --- src/const.h | 2 +- src/engine.c | 66 +++++++++++++++++++- src/runner.c | 6 +- src/runner_doiact_grav.h | 128 +++++++++++++++++++++++++++++++++++---- src/scheduler.c | 6 +- 5 files changed, 190 insertions(+), 18 deletions(-) diff --git a/src/const.h b/src/const.h index e6941f2ca..856043bf2 100644 --- a/src/const.h +++ b/src/const.h @@ -61,6 +61,6 @@ /* Gravity properties */ #define EXTERNAL_POTENTIAL_POINTMASS -#define SANITY_CHECK +#define SANITY_CHECKS #endif /* SWIFT_CONST_H */ diff --git a/src/engine.c b/src/engine.c index dd9f6cc59..562e1aeed 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1066,6 +1066,69 @@ void engine_exchange_strays(struct engine *e, size_t offset_parts, #endif } +void engine_make_gravity_tasks(struct engine *e) { + + struct space *s = e->s; + struct scheduler *sched = &e->sched; + const int nodeID = e->nodeID; + const int *cdim = s->cdim; + struct cell *cells = s->cells; + + message("aa"); + + /* Run through the highest level of cells and add pairs. */ + for (int i = 0; i < cdim[0]; i++) { + for (int j = 0; j < cdim[1]; j++) { + for (int k = 0; k < cdim[2]; k++) { + + /* Get the cell */ + const int cid = cell_getid(cdim, i, j, k); + struct cell *ci = &cells[cid]; + + /* Skip cells without gravity particles */ + if (ci->gcount == 0) continue; + + /* If the cells is local build a self-interaction */ + if (ci->nodeID == nodeID) + scheduler_addtask(sched, task_type_self, task_subtype_grav, 0, 0, ci, + NULL, 0); + + /* Now loop over all the neighbours of this cell */ + for (int ii = -1; ii < 2; ii++) { + int iii = i + ii; + if (!s->periodic && (iii < 0 || iii >= cdim[0])) continue; + iii = (iii + cdim[0]) % cdim[0]; + for (int jj = -1; jj < 2; jj++) { + int jjj = j + jj; + if (!s->periodic && (jjj < 0 || jjj >= cdim[1])) continue; + jjj = (jjj + cdim[1]) % cdim[1]; + for (int kk = -1; kk < 2; kk++) { + int kkk = k + kk; + if (!s->periodic && (kkk < 0 || kkk >= cdim[2])) continue; + kkk = (kkk + cdim[2]) % cdim[2]; + + /* Get the neighbouring cell */ + const int cjd = cell_getid(cdim, iii, jjj, kkk); + struct cell *cj = &cells[cjd]; + + /* Is that neighbour local and does it have particles ? */ + if (cid >= cjd || cj->gcount == 0 || + (ci->nodeID != nodeID && cj->nodeID != nodeID)) + continue; + + /* Construct the pair task */ + const int sid = + sortlistID[(kk + 1) + 3 * ((jj + 1) + 3 * (ii + 1))]; + scheduler_addtask(sched, task_type_pair, task_subtype_grav, sid, + 0, ci, cj, 1); + } + } + } + } + } + } +} + /** * @brief Constructs the top-level pair tasks for the first hydro loop over *neighbours @@ -1435,8 +1498,7 @@ void engine_maketasks(struct engine *e) { engine_make_hydroloop_tasks(e); /* Add the gravity mm tasks. */ - /* if (e->policy & engine_policy_self_gravity) */ - /* engine_make_gravityinteraction_tasks(e); */ + if (e->policy & engine_policy_self_gravity) engine_make_gravity_tasks(e); /* Split the tasks. */ scheduler_splittasks(sched); diff --git a/src/runner.c b/src/runner.c index 5921691fb..1a094297a 100644 --- a/src/runner.c +++ b/src/runner.c @@ -123,7 +123,6 @@ void runner_do_grav_external(struct runner *r, struct cell *c, int timer) { if (g->ti_end <= ti_current) { external_gravity(potential, constants, g); - } } if (timer) TIMER_TOC(timer_dograv_external); @@ -1130,14 +1129,19 @@ void *runner_main(void *data) { runner_doself1_density(r, ci); else if (t->subtype == task_subtype_force) runner_doself2_force(r, ci); + else if (t->subtype == task_subtype_grav) + runner_doself_grav(r, ci); else error("Unknown task subtype."); break; case task_type_pair: + message("bb"); if (t->subtype == task_subtype_density) runner_dopair1_density(r, ci, cj); else if (t->subtype == task_subtype_force) runner_dopair2_force(r, ci, cj); + else if (t->subtype == task_subtype_grav) + runner_dopair_grav(r, ci, cj); else error("Unknown task subtype."); break; diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 7e2293ba9..113019a32 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -57,10 +57,10 @@ void runner_dograv_up(struct runner *r, struct cell *c) { /** * @brief Checks whether the cells are direct neighbours ot not. Both cells have * to be of the same size - * + * */ -__attribute__((always_inline)) INLINE static -int are_neighbours(const struct cell *restrict ci, const struct cell *restrict cj) { +__attribute__((always_inline)) INLINE static int are_neighbours( + const struct cell *restrict ci, const struct cell *restrict cj) { #ifdef SANITY_CHECKS if (ci->h[0] != cj->h[0]) @@ -80,8 +80,6 @@ int are_neighbours(const struct cell *restrict ci, const struct cell *restrict c return 1; } - - /** * @brief Computes the interaction of all the particles in a cell with the * multipole of another cell. @@ -90,8 +88,9 @@ int are_neighbours(const struct cell *restrict ci, const struct cell *restrict c * @param ci The #cell with particles to interct. * @param cj The #cell with the multipole. */ -__attribute__((always_inline)) INLINE static void runner_dograv_pair_pm( - const struct runner *r, const struct cell *restrict ci, const struct cell *restrict cj) { +__attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( + const struct runner *r, const struct cell *restrict ci, + const struct cell *restrict cj) { const struct engine *e = r->e; const int gcount = ci->gcount; @@ -101,7 +100,7 @@ __attribute__((always_inline)) INLINE static void runner_dograv_pair_pm( TIMER_TIC; -#ifdef SANITY_CHECK +#ifdef SANITY_CHECKS if (gcount == 0) error("Empty cell!"); // MATTHIEU sanity check if (multi.mass == 0.0) // MATTHIEU sanity check @@ -180,7 +179,7 @@ __attribute__((always_inline)) INLINE static void runner_dograv_pair_pm( * * @todo Use a local cache for the particles. */ -__attribute__((always_inline)) INLINE static void runner_dograv_pair_pp( +__attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( struct runner *r, struct cell *ci, struct cell *cj) { const struct engine *e = r->e; @@ -192,7 +191,7 @@ __attribute__((always_inline)) INLINE static void runner_dograv_pair_pp( TIMER_TIC; -#ifdef SANITY_CHECK +#ifdef SANITY_CHECKS if (ci->h[0] != cj->h[0]) // MATTHIEU sanity check error("Non matching cell sizes !! h_i=%f h_j=%f\n", ci->h[0], cj->h[0]); #endif @@ -250,7 +249,7 @@ __attribute__((always_inline)) INLINE static void runner_dograv_pair_pp( * @todo Use a local cache for the particles. */ __attribute__((always_inline)) - INLINE static void runner_dograv_self_pp(struct runner *r, struct cell *c) { + INLINE static void runner_doself_grav_pp(struct runner *r, struct cell *c) { const struct engine *e = r->e; const int gcount = c->gcount; @@ -259,7 +258,7 @@ __attribute__((always_inline)) TIMER_TIC; -#ifdef SANITY_CHECK +#ifdef SANITY_CHECKS if (c->gcount == 0) // MATTHIEU sanity check error("Empty cell !"); #endif @@ -308,4 +307,109 @@ __attribute__((always_inline)) TIMER_TOC(TIMER_DOSELF); // MATTHIEU } +/** + * @brief Computes the interaction of all the particles in a cell with all the + * particles of another cell. + * + * @param r The #runner. + * @param ci The first #cell. + * @param cj The other #cell. + * + * @todo Use a local cache for the particles. + */ +static void runner_dopair_grav(struct runner *r, struct cell *ci, + struct cell *cj) { + + const int gcount_i = ci->gcount; + const int gcount_j = cj->gcount; + +#ifdef SANITY_CHECKS + + /* Early abort? */ + if (gcount_i == 0 || gcount_j == 0) error("Empty cell !"); + + /* Bad stuff will happen if cell sizes are different */ + if (ci->h[0] != cj->h[0]) + error("Non matching cell sizes !! h_i=%f h_j=%f\n", ci->h[0], cj->h[0]); + + /* Sanity check */ + if (ci == cj) + error( + "The impossible has happened: pair interaction between a cell and " + "itself."); + + /* Are the cells direct neighbours? */ + if (!are_neighbours(ci, cj)) error("Non-neighbouring cells !"); + +#endif + + /* Are both cells split ? */ + if (ci->split && cj->split) { + + for (int j = 0; j < 8; j++) { + if (ci->progeny[j] != NULL) { + + for (int k = 0; k < 8; k++) { + if (cj->progeny[k] != NULL) { + + if (are_neighbours(ci->progeny[j], cj->progeny[k])) { + + /* Recurse */ + runner_dopair_grav(r, ci->progeny[j], cj->progeny[k]); + + } else { + + /* Ok, here we can go for particle-multipole interactions */ + runner_dopair_grav_pm(r, ci->progeny[j], cj->progeny[k]); + runner_dopair_grav_pm(r, cj->progeny[k], ci->progeny[j]); + } + } + } + } + } + } else {/* Not split */ + + /* Compute the interactions at this level directly. */ + runner_dopair_grav_pp(r, ci, cj); + } +} + +static void runner_doself_grav(struct runner *r, struct cell *c) { + + const int gcount = c->gcount; + +#ifdef SANITY_CHECKS + + /* Early abort? */ + if (gcount == 0) error("Empty cell !"); +#endif + + message("aa"); + + /* If the cell is split, interact each progeny with itself, and with + each of its siblings. */ + if (c->split) { + + for (int j = 0; j < 8; j++) { + if (c->progeny[j] != NULL) { + + runner_doself_grav(r, c->progeny[j]); + + for (int k = j + 1; k < 8; k++) { + if (c->progeny[k] != NULL) { + + runner_dopair_grav(r, c->progeny[j], c->progeny[k]); + } + } + } + } + } + + /* If the cell is not split, then just go for it... */ + else { + + runner_doself_grav_pp(r, c); + } +} + #endif /* SWIFT_RUNNER_DOIACT_GRAV_H */ diff --git a/src/scheduler.c b/src/scheduler.c index 887e8d54f..539b36892 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -172,7 +172,8 @@ void scheduler_splittasks(struct scheduler *s) { if (ci->split) { /* Make a sub? */ - if (scheduler_dosub && ci->count < space_subsize / ci->count) { + if (scheduler_dosub && (ci->count * ci->count < space_subsize || + ci->gcount * ci->gcount < space_subsize)) { /* convert to a self-subtask. */ t->type = task_type_sub; @@ -233,7 +234,8 @@ void scheduler_splittasks(struct scheduler *s) { /* Replace by a single sub-task? */ if (scheduler_dosub && - ci->count * sid_scale[sid] < space_subsize / cj->count && + (ci->count * cj->count * sid_scale[sid] < space_subsize || + ci->gcount * cj->gcount * sid_scale[sid] < space_subsize) && sid != 0 && sid != 2 && sid != 6 && sid != 8) { /* Make this task a sub task. */ -- GitLab From 39df1d976e06ecae59535bd3223bfa1530094ae9 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 1 Jun 2016 12:22:22 +0100 Subject: [PATCH 17/72] Added task dependencies for the self-gravity --- examples/UniformDMBox/makeIC.py | 2 +- src/engine.c | 104 ++++++++++++++++++++++++++++++-- src/runner.c | 1 - src/runner_doiact_grav.h | 17 ++++-- src/tools.c | 1 - 5 files changed, 114 insertions(+), 11 deletions(-) diff --git a/examples/UniformDMBox/makeIC.py b/examples/UniformDMBox/makeIC.py index 449d780fb..2aee89798 100644 --- a/examples/UniformDMBox/makeIC.py +++ b/examples/UniformDMBox/makeIC.py @@ -26,7 +26,7 @@ from numpy import * # with a density of 1 # Parameters -periodic= 1 # 1 For periodic box +periodic= 0 # 1 For periodic box boxSize = 1. rho = 1. L = int(sys.argv[1]) # Number of particles along one axis diff --git a/src/engine.c b/src/engine.c index 562e1aeed..f7e749ab1 100644 --- a/src/engine.c +++ b/src/engine.c @@ -62,6 +62,7 @@ #include "serial_io.h" #include "single_io.h" #include "timers.h" +#include "tools.h" const char *engine_policy_names[13] = { "none", "rand", "steal", "keep", @@ -1271,6 +1272,68 @@ void engine_count_and_link_tasks(struct engine *e) { } } +void engine_make_gravity_dependencies(struct engine *e) { + + struct scheduler *sched = &e->sched; + const int nodeID = e->nodeID; + const int nr_tasks = sched->nr_tasks; + + for (int k = 0; k < nr_tasks; k++) { + + /* Get a pointer to the task. */ + struct task *t = &sched->tasks[k]; + + /* Skip? */ + if (t->skip) continue; + + /* Self-interaction? */ + if (t->type == task_type_self && t->subtype == task_subtype_grav) { + + scheduler_addunlock(sched, t->ci->super->init, t); + scheduler_addunlock(sched, t->ci->super->grav_up, t); + scheduler_addunlock(sched, t, t->ci->super->kick); + + } + + /* Otherwise, pair interaction? */ + else if (t->type == task_type_pair && t->subtype == task_subtype_grav) { + + if (t->ci->nodeID == nodeID) { + + scheduler_addunlock(sched, t->ci->super->init, t); + scheduler_addunlock(sched, t->ci->super->grav_up, t); + scheduler_addunlock(sched, t, t->ci->super->kick); + } + + if (t->cj->nodeID == nodeID && t->ci->super != t->cj->super) { + + scheduler_addunlock(sched, t->cj->super->init, t); + scheduler_addunlock(sched, t->cj->super->grav_up, t); + scheduler_addunlock(sched, t, t->cj->super->kick); + } + + } + + /* Otherwise, sub interaction? */ + else if (t->type == task_type_sub && t->subtype == task_subtype_grav) { + + if (t->ci->nodeID == nodeID) { + + scheduler_addunlock(sched, t->ci->super->init, t); + scheduler_addunlock(sched, t->ci->super->grav_up, t); + scheduler_addunlock(sched, t, t->ci->super->kick); + } + if (t->cj != NULL && t->cj->nodeID == nodeID && + t->ci->super != t->cj->super) { + + scheduler_addunlock(sched, t->cj->super->init, t); + scheduler_addunlock(sched, t->cj->super->grav_up, t); + scheduler_addunlock(sched, t, t->cj->super->kick); + } + } + } +} + /** * @brief Creates the dependency network for the hydro tasks of a given cell. * @@ -1382,10 +1445,6 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { } } - /* /\* Kick tasks should rely on the grav_down tasks of their cell. *\/ */ - /* else if (t->type == task_type_kick && t->ci->grav_down != NULL) */ - /* scheduler_addunlock(sched, t->ci->grav_down, t); */ - /* External gravity tasks should depend on init and unlock the kick */ else if (t->type == task_type_grav_external) { scheduler_addunlock(sched, t->ci->init, t); @@ -1530,6 +1589,10 @@ void engine_maketasks(struct engine *e) { of its super-cell. */ engine_make_extra_hydroloop_tasks(e); + /* Add the dependencies for the self-gravity stuff */ + if (e->policy & engine_policy_self_gravity) + engine_make_gravity_dependencies(e); + #ifdef WITH_MPI /* Add the communication tasks if MPI is being used. */ @@ -2011,6 +2074,10 @@ void engine_init_particles(struct engine *e) { if (e->policy & engine_policy_self_gravity) { mask |= 1 << task_type_grav_up; + mask |= 1 << task_type_self; + mask |= 1 << task_type_pair; + + submask |= 1 << task_subtype_grav; } /* Add the tasks corresponding to external gravity to the masks */ @@ -2192,6 +2259,10 @@ void engine_step(struct engine *e) { if (e->policy & engine_policy_self_gravity) { mask |= 1 << task_type_grav_up; + mask |= 1 << task_type_self; + mask |= 1 << task_type_pair; + + submask |= 1 << task_subtype_grav; } /* Add the tasks corresponding to external gravity to the masks */ @@ -2216,6 +2287,31 @@ void engine_step(struct engine *e) { /* Check that the multipoles are correct */ space_map_cells_pre(s, 1, cell_check_multipole, NULL); + FILE *file = fopen("grav_swift.dat", "w"); + for (size_t k = 0; k < s->nr_gparts; ++k) { + fprintf(file, "%lld %f %f %f %f %f %f\n", s->gparts[k].id, + s->gparts[k].x[0], s->gparts[k].x[1], s->gparts[k].x[2], + s->gparts[k].a_grav[0], s->gparts[k].a_grav[1], + s->gparts[k].a_grav[2]); + } + fclose(file); + + /* Check the gravity accelerations */ + /* struct gpart *temp = malloc(s->nr_gparts * sizeof(struct gpart)); */ + /* memcpy(temp, s->gparts, s->nr_gparts * sizeof(struct gpart)); */ + /* gravity_n2(temp, s->nr_gparts); */ + /* file = fopen("grav_brute.dat", "w"); */ + /* for(size_t k = 0; k < s->nr_gparts; ++k) { */ + /* fprintf(file, "%lld %f %f %f %f %f %f\n", temp[k].id, */ + /* temp[k].x[0], temp[k].x[1], temp[k].x[2], */ + /* temp[k].a_grav[0], temp[k].a_grav[1], temp[k].a_grav[2]); */ + /* } */ + /* fclose(file); */ + + /* free(temp); */ + + error("done"); + clocks_gettime(&time2); e->wallclock_time = (float)clocks_diff(&time1, &time2); diff --git a/src/runner.c b/src/runner.c index 1a094297a..6beb59737 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1135,7 +1135,6 @@ void *runner_main(void *data) { error("Unknown task subtype."); break; case task_type_pair: - message("bb"); if (t->subtype == task_subtype_density) runner_dopair1_density(r, ci, cj); else if (t->subtype == task_subtype_force) diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 113019a32..554c60f65 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -58,6 +58,10 @@ void runner_dograv_up(struct runner *r, struct cell *c) { * @brief Checks whether the cells are direct neighbours ot not. Both cells have * to be of the same size * + * @param ci First #cell. + * @param cj Second #cell. + * + * @todo Deal with periodicity. */ __attribute__((always_inline)) INLINE static int are_neighbours( const struct cell *restrict ci, const struct cell *restrict cj) { @@ -68,12 +72,12 @@ __attribute__((always_inline)) INLINE static int are_neighbours( #endif /* Maximum allowed distance */ - const float min_dist = ci->h[0]; + const double min_dist = 1.2 * ci->h[0]; /* 1.2 accounts for rounding errors */ /* (Manhattan) Distance between the cells */ for (int k = 0; k < 3; k++) { - const float center_i = ci->loc[k]; - const float center_j = cj->loc[k]; + const double center_i = ci->loc[k]; + const double center_j = cj->loc[k]; if (fabsf(center_i - center_j) > min_dist) return 0; } @@ -339,7 +343,12 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, "itself."); /* Are the cells direct neighbours? */ - if (!are_neighbours(ci, cj)) error("Non-neighbouring cells !"); + if (!are_neighbours(ci, cj)) + error( + "Non-neighbouring cells ! ci->x=[%f %f %f] ci->h=%f cj->loc=[%f %f %f] " + "cj->h=%f", + ci->loc[0], ci->loc[1], ci->loc[2], ci->h[0], cj->loc[0], cj->loc[1], + cj->loc[2], cj->h[0]); #endif diff --git a/src/tools.c b/src/tools.c index db7285d91..f298b3494 100644 --- a/src/tools.c +++ b/src/tools.c @@ -507,7 +507,6 @@ void gravity_n2(struct gpart *gparts, const int gcount) { struct gpart *restrict gpi = &gparts[pid]; const float mi = gpi->mass; - /* Loop over every particle in the other cell. */ for (int pjd = pid + 1; pjd < gcount; pjd++) { /* Get a hold of the jth part in ci. */ -- GitLab From b011025c45820cf7ccaaeebcdab982e9aeb3a416 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 1 Jun 2016 13:09:49 +0100 Subject: [PATCH 18/72] Don't forget the subs in the mask ! --- src/engine.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine.c b/src/engine.c index f7e749ab1..523dacfd3 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1075,8 +1075,6 @@ void engine_make_gravity_tasks(struct engine *e) { const int *cdim = s->cdim; struct cell *cells = s->cells; - message("aa"); - /* Run through the highest level of cells and add pairs. */ for (int i = 0; i < cdim[0]; i++) { for (int j = 0; j < cdim[1]; j++) { @@ -2076,6 +2074,7 @@ void engine_init_particles(struct engine *e) { mask |= 1 << task_type_grav_up; mask |= 1 << task_type_self; mask |= 1 << task_type_pair; + mask |= 1 << task_type_sub; submask |= 1 << task_subtype_grav; } @@ -2261,6 +2260,7 @@ void engine_step(struct engine *e) { mask |= 1 << task_type_grav_up; mask |= 1 << task_type_self; mask |= 1 << task_type_pair; + mask |= 1 << task_type_sub; submask |= 1 << task_subtype_grav; } -- GitLab From b53b03835ab1455666561ad4200a2a1f04325a3e Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 1 Jun 2016 15:51:05 +0100 Subject: [PATCH 19/72] Missing interactions between the top pairs. --- src/engine.c | 128 +++++++++++++++++++---------- src/gravity/Default/gravity.h | 2 + src/gravity/Default/gravity_part.h | 2 + src/runner.c | 12 ++- src/runner_doiact_grav.h | 91 +++++++++++++++++--- src/scheduler.c | 4 + 6 files changed, 183 insertions(+), 56 deletions(-) diff --git a/src/engine.c b/src/engine.c index 523dacfd3..f15217733 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1072,60 +1072,96 @@ void engine_make_gravity_tasks(struct engine *e) { struct space *s = e->s; struct scheduler *sched = &e->sched; const int nodeID = e->nodeID; - const int *cdim = s->cdim; struct cell *cells = s->cells; + const int nr_cells = s->nr_cells; - /* Run through the highest level of cells and add pairs. */ - for (int i = 0; i < cdim[0]; i++) { - for (int j = 0; j < cdim[1]; j++) { - for (int k = 0; k < cdim[2]; k++) { + int counter = 0; - /* Get the cell */ - const int cid = cell_getid(cdim, i, j, k); - struct cell *ci = &cells[cid]; + for (int cid = 0; cid < nr_cells; ++cid) { - /* Skip cells without gravity particles */ - if (ci->gcount == 0) continue; + struct cell *ci = &cells[cid]; - /* If the cells is local build a self-interaction */ - if (ci->nodeID == nodeID) - scheduler_addtask(sched, task_type_self, task_subtype_grav, 0, 0, ci, - NULL, 0); + /* Skip cells without gravity particles */ + if (ci->gcount == 0) continue; - /* Now loop over all the neighbours of this cell */ - for (int ii = -1; ii < 2; ii++) { - int iii = i + ii; - if (!s->periodic && (iii < 0 || iii >= cdim[0])) continue; - iii = (iii + cdim[0]) % cdim[0]; - for (int jj = -1; jj < 2; jj++) { - int jjj = j + jj; - if (!s->periodic && (jjj < 0 || jjj >= cdim[1])) continue; - jjj = (jjj + cdim[1]) % cdim[1]; - for (int kk = -1; kk < 2; kk++) { - int kkk = k + kk; - if (!s->periodic && (kkk < 0 || kkk >= cdim[2])) continue; - kkk = (kkk + cdim[2]) % cdim[2]; + /* Is that neighbour local ? */ + if (ci->nodeID != nodeID) continue; - /* Get the neighbouring cell */ - const int cjd = cell_getid(cdim, iii, jjj, kkk); - struct cell *cj = &cells[cjd]; + /* If the cells is local build a self-interaction */ + scheduler_addtask(sched, task_type_self, task_subtype_grav, 0, 0, ci, NULL, + 0); - /* Is that neighbour local and does it have particles ? */ - if (cid >= cjd || cj->gcount == 0 || - (ci->nodeID != nodeID && cj->nodeID != nodeID)) - continue; + for (int cjd = cid + 1; cjd < nr_cells; ++cjd) { - /* Construct the pair task */ - const int sid = - sortlistID[(kk + 1) + 3 * ((jj + 1) + 3 * (ii + 1))]; - scheduler_addtask(sched, task_type_pair, task_subtype_grav, sid, - 0, ci, cj, 1); - } - } - } - } + struct cell *cj = &cells[cjd]; + + /* Skip cells without gravity particles */ + if (cj->gcount == 0) continue; + + /* Is that neighbour local ? */ + if (cj->nodeID != nodeID) continue; + + scheduler_addtask(sched, task_type_pair, task_subtype_grav, 0, 0, ci, cj, + 1); + ++counter; } } + + message("counter= %d nr_cells=%d", counter, nr_cells); + + /* /\* Run through the highest level of cells and add pairs. *\/ */ + /* for (int i = 0; i < cdim[0]; i++) { */ + /* for (int j = 0; j < cdim[1]; j++) { */ + /* for (int k = 0; k < cdim[2]; k++) { */ + + /* /\* Get the cell *\/ */ + /* const int cid = cell_getid(cdim, i, j, k); */ + /* struct cell *ci = &cells[cid]; */ + + /* /\* Skip cells without gravity particles *\/ */ + /* if (ci->gcount == 0) continue; */ + + /* /\* If the cells is local build a self-interaction *\/ */ + /* if (ci->nodeID == nodeID) */ + /* scheduler_addtask(sched, task_type_self, task_subtype_grav, 0, 0, + * ci, */ + /* NULL, 0); */ + + /* /\* Now loop over all the neighbours of this cell *\/ */ + /* for (int ii = -1; ii < 2; ii++) { */ + /* int iii = i + ii; */ + /* if (!s->periodic && (iii < 0 || iii >= cdim[0])) continue; */ + /* iii = (iii + cdim[0]) % cdim[0]; */ + /* for (int jj = -1; jj < 2; jj++) { */ + /* int jjj = j + jj; */ + /* if (!s->periodic && (jjj < 0 || jjj >= cdim[1])) continue; */ + /* jjj = (jjj + cdim[1]) % cdim[1]; */ + /* for (int kk = -1; kk < 2; kk++) { */ + /* int kkk = k + kk; */ + /* if (!s->periodic && (kkk < 0 || kkk >= cdim[2])) continue; */ + /* kkk = (kkk + cdim[2]) % cdim[2]; */ + + /* /\* Get the neighbouring cell *\/ */ + /* const int cjd = cell_getid(cdim, iii, jjj, kkk); */ + /* struct cell *cj = &cells[cjd]; */ + + /* /\* Is that neighbour local and does it have particles ? *\/ */ + /* if (cid >= cjd || cj->gcount == 0 || */ + /* (ci->nodeID != nodeID && cj->nodeID != nodeID)) */ + /* continue; */ + + /* /\* Construct the pair task *\/ */ + /* const int sid = */ + /* sortlistID[(kk + 1) + 3 * ((jj + 1) + 3 * (ii + 1))]; */ + /* scheduler_addtask(sched, task_type_pair, task_subtype_grav, + * sid, */ + /* 0, ci, cj, 1); */ + /* } */ + /* } */ + /* } */ + /* } */ + /* } */ + /* } */ } /** @@ -2049,6 +2085,8 @@ void engine_init_particles(struct engine *e) { engine_marktasks(e); + // error(""); + /* Build the masks corresponding to the policy */ unsigned int mask = 0; unsigned int submask = 0; @@ -2310,6 +2348,10 @@ void engine_step(struct engine *e) { /* free(temp); */ + float mass = 0.f; + for (int i = 0; i < s->nr_cells; ++i) mass += s->cells[i].multipole.mass; + message("Total mass: %f", mass); + error("done"); clocks_gettime(&time2); diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h index 4dd8d5b7c..cd3e0dc80 100644 --- a/src/gravity/Default/gravity.h +++ b/src/gravity/Default/gravity.h @@ -91,6 +91,8 @@ __attribute__((always_inline)) gp->a_grav[0] = 0.f; gp->a_grav[1] = 0.f; gp->a_grav[2] = 0.f; + + gp->mass_interacted = 0.f; } /** diff --git a/src/gravity/Default/gravity_part.h b/src/gravity/Default/gravity_part.h index a54fc1d18..71d8f34aa 100644 --- a/src/gravity/Default/gravity_part.h +++ b/src/gravity/Default/gravity_part.h @@ -47,6 +47,8 @@ struct gpart { /* float tx; */ /* float tv; */ + float mass_interacted; + /* Anonymous union for id/part. */ union { diff --git a/src/runner.c b/src/runner.c index 6beb59737..4d32cfd24 100644 --- a/src/runner.c +++ b/src/runner.c @@ -409,6 +409,10 @@ void runner_do_init(struct runner *r, struct cell *c, int timer) { /* Get ready for a density calculation */ gravity_init_part(gp); + + if (gp->id == -ICHECK) + message("id=%lld a=[%f %f %f]\n", gp->id, gp->a_grav[0], + gp->a_grav[1], gp->a_grav[2]); } } } @@ -754,6 +758,10 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { /* First, finish the force calculation */ gravity_end_force(gp); + if (gp->id == -ICHECK) + message("id=%lld a=[%f %f %f] M=%f\n", gp->id, gp->a_grav[0], + gp->a_grav[1], gp->a_grav[2], gp->mass_interacted); + /* Now we are ready to compute the next time-step size */ int new_dti; @@ -1152,8 +1160,8 @@ void *runner_main(void *data) { runner_dosub1_density(r, ci, cj, t->flags, 1); else if (t->subtype == task_subtype_force) runner_dosub2_force(r, ci, cj, t->flags, 1); - /* else if (t->subtype == task_subtype_grav) */ - /* runner_dosub_grav(r, ci, cj, 1); */ + else if (t->subtype == task_subtype_grav) + runner_dosub_grav(r, ci, cj, 1); else error("Unknown task subtype."); break; diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 554c60f65..8ac9e5b65 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -25,6 +25,8 @@ #include "clocks.h" #include "part.h" +#define ICHECK 4934 + /** * @brief Compute the recursive upward sweep, i.e. construct the * multipoles in a cell hierarchy. @@ -112,7 +114,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( #endif /* Anything to do here? */ - if (ci->ti_end_min > ti_current) return; + // if (ci->ti_end_min > ti_current) return; /* Loop over every particle in leaf. */ for (int pid = 0; pid < gcount; pid++) { @@ -122,6 +124,10 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( if (gp->ti_end > ti_current) continue; + if (gp->id == -ICHECK) + message("id=%lld mass=%f CoM=[%f %f %f]\n", gp->id, multi.mass, + multi.CoM[0], multi.CoM[1], multi.CoM[2]); + /* Compute the pairwise distance. */ const float dx[3] = {multi.CoM[0] - gp->x[0], // x multi.CoM[1] - gp->x[1], // y @@ -165,6 +171,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( gp->a_grav[1] -= C * dx[1] + D2 * qRy; gp->a_grav[2] -= C * dx[2] + D2 * qRz; + gp->mass_interacted += multi.mass; #else #error "Multipoles of order >2 not yet implemented." #endif @@ -201,7 +208,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( #endif /* Anything to do here? */ - if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; + // if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; /* Loop over all particles in ci... */ for (int pid = 0; pid < gcount_i; pid++) { @@ -232,11 +239,13 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( gpi->a_grav[0] -= wdx[0] * mj; gpi->a_grav[1] -= wdx[1] * mj; gpi->a_grav[2] -= wdx[2] * mj; + gpi->mass_interacted += mj; } if (gpj->ti_end <= ti_current) { gpj->a_grav[0] += wdx[0] * mi; gpj->a_grav[1] += wdx[1] * mi; gpj->a_grav[2] += wdx[2] * mi; + gpj->mass_interacted += mi; } } } @@ -268,7 +277,7 @@ __attribute__((always_inline)) #endif /* Anything to do here? */ - if (c->ti_end_min > ti_current) return; + // if (c->ti_end_min > ti_current) return; /* Loop over all particles in ci... */ for (int pid = 0; pid < gcount; pid++) { @@ -299,11 +308,13 @@ __attribute__((always_inline)) gpi->a_grav[0] -= wdx[0] * mj; gpi->a_grav[1] -= wdx[1] * mj; gpi->a_grav[2] -= wdx[2] * mj; + gpi->mass_interacted += mj; } if (gpj->ti_end <= ti_current) { gpj->a_grav[0] += wdx[0] * mi; gpj->a_grav[1] += wdx[1] * mi; gpj->a_grav[2] += wdx[2] * mi; + gpj->mass_interacted += mi; } } } @@ -342,15 +353,41 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, "The impossible has happened: pair interaction between a cell and " "itself."); +#endif + /* Are the cells direct neighbours? */ - if (!are_neighbours(ci, cj)) - error( - "Non-neighbouring cells ! ci->x=[%f %f %f] ci->h=%f cj->loc=[%f %f %f] " - "cj->h=%f", - ci->loc[0], ci->loc[1], ci->loc[2], ci->h[0], cj->loc[0], cj->loc[1], - cj->loc[2], cj->h[0]); + if (!are_neighbours(ci, cj)) { + + /* Ok, here we can go for particle-multipole interactions */ + runner_dopair_grav_pm(r, ci, cj); + runner_dopair_grav_pm(r, cj, ci); + + /* error( */ + /* "Non-neighbouring cells ! ci->x=[%f %f %f] ci->h=%f cj->loc=[%f %f + * %f] " */ + /* "cj->h=%f", */ + /* ci->loc[0], ci->loc[1], ci->loc[2], ci->h[0], cj->loc[0], cj->loc[1], + */ + /* cj->loc[2], cj->h[0]); */ + } -#endif + for (int i = 0; i < gcount_i; i++) { + + struct gpart *const gp = &ci->gparts[i]; + + if (gp->id == -ICHECK) + message("id=%lld a=[%f %f %f]\n", gp->id, gp->a_grav[0], gp->a_grav[1], + gp->a_grav[2]); + } + + for (int i = 0; i < gcount_j; i++) { + + struct gpart *const gp = &cj->gparts[i]; + + if (gp->id == -ICHECK) + message("id=%lld a=[%f %f %f]\n", gp->id, gp->a_grav[0], gp->a_grav[1], + gp->a_grav[2]); + } /* Are both cells split ? */ if (ci->split && cj->split) { @@ -393,7 +430,14 @@ static void runner_doself_grav(struct runner *r, struct cell *c) { if (gcount == 0) error("Empty cell !"); #endif - message("aa"); + for (int i = 0; i < gcount; i++) { + + struct gpart *const gp = &c->gparts[i]; + + if (gp->id == -ICHECK) + message("id=%lld a=[%f %f %f]\n", gp->id, gp->a_grav[0], gp->a_grav[1], + gp->a_grav[2]); + } /* If the cell is split, interact each progeny with itself, and with each of its siblings. */ @@ -421,4 +465,29 @@ static void runner_doself_grav(struct runner *r, struct cell *c) { } } +static void runner_dosub_grav(struct runner *r, struct cell *ci, + struct cell *cj, int timer) { + + /* Is this a single cell? */ + if (cj == NULL) { + + runner_doself_grav(r, ci); + + } else { + + /* if (!are_neighbours(ci, cj)) { */ + + /* /\* Ok, here we can go for particle-multipole interactions *\/ */ + /* runner_dopair_grav_pm(r, ci, cj); */ + /* runner_dopair_grav_pm(r, cj, ci); */ + + /* } */ + /* else { */ + + runner_dopair_grav(r, ci, cj); + + /* } */ + } +} + #endif /* SWIFT_RUNNER_DOIACT_GRAV_H */ diff --git a/src/scheduler.c b/src/scheduler.c index 539b36892..b9aac5a16 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -178,6 +178,8 @@ void scheduler_splittasks(struct scheduler *s) { /* convert to a self-subtask. */ t->type = task_type_sub; + // message("TASK type=%s subtype=%s", taskID_names[t->type], + // subtaskID_names[t->subtype]); } /* Otherwise, make tasks explicitly. */ @@ -186,6 +188,8 @@ void scheduler_splittasks(struct scheduler *s) { /* Take a step back (we're going to recycle the current task)... */ redo = 1; + // message("aa"); + /* Add the self task. */ int first_child = 0; while (ci->progeny[first_child] == NULL) first_child++; -- GitLab From d3a6c775dca5a33a7ae4d2db8c81ad1524260ee4 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 1 Jun 2016 16:50:33 +0100 Subject: [PATCH 20/72] Work in progress --- src/engine.c | 32 ++++++++++---------- src/gravity/Default/gravity_part.h | 2 +- src/runner_doiact_grav.h | 48 ++++++++++++++++++++---------- src/scheduler.c | 8 ++--- 4 files changed, 54 insertions(+), 36 deletions(-) diff --git a/src/engine.c b/src/engine.c index f15217733..b577ae3bf 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2110,11 +2110,11 @@ void engine_init_particles(struct engine *e) { if (e->policy & engine_policy_self_gravity) { mask |= 1 << task_type_grav_up; - mask |= 1 << task_type_self; - mask |= 1 << task_type_pair; - mask |= 1 << task_type_sub; + /* mask |= 1 << task_type_self; */ + /* mask |= 1 << task_type_pair; */ + /* mask |= 1 << task_type_sub; */ - submask |= 1 << task_subtype_grav; + /* submask |= 1 << task_subtype_grav; */ } /* Add the tasks corresponding to external gravity to the masks */ @@ -2335,20 +2335,20 @@ void engine_step(struct engine *e) { fclose(file); /* Check the gravity accelerations */ - /* struct gpart *temp = malloc(s->nr_gparts * sizeof(struct gpart)); */ - /* memcpy(temp, s->gparts, s->nr_gparts * sizeof(struct gpart)); */ - /* gravity_n2(temp, s->nr_gparts); */ - /* file = fopen("grav_brute.dat", "w"); */ - /* for(size_t k = 0; k < s->nr_gparts; ++k) { */ - /* fprintf(file, "%lld %f %f %f %f %f %f\n", temp[k].id, */ - /* temp[k].x[0], temp[k].x[1], temp[k].x[2], */ - /* temp[k].a_grav[0], temp[k].a_grav[1], temp[k].a_grav[2]); */ - /* } */ - /* fclose(file); */ + struct gpart *temp = malloc(s->nr_gparts * sizeof(struct gpart)); + memcpy(temp, s->gparts, s->nr_gparts * sizeof(struct gpart)); + gravity_n2(temp, s->nr_gparts); + file = fopen("grav_brute.dat", "w"); + for(size_t k = 0; k < s->nr_gparts; ++k) { + fprintf(file, "%lld %f %f %f %f %f %f\n", temp[k].id, + temp[k].x[0], temp[k].x[1], temp[k].x[2], + temp[k].a_grav[0], temp[k].a_grav[1], temp[k].a_grav[2]); + } + fclose(file); - /* free(temp); */ + free(temp); - float mass = 0.f; + double mass = 0.f; for (int i = 0; i < s->nr_cells; ++i) mass += s->cells[i].multipole.mass; message("Total mass: %f", mass); diff --git a/src/gravity/Default/gravity_part.h b/src/gravity/Default/gravity_part.h index 71d8f34aa..2d3bc69ba 100644 --- a/src/gravity/Default/gravity_part.h +++ b/src/gravity/Default/gravity_part.h @@ -47,7 +47,7 @@ struct gpart { /* float tx; */ /* float tv; */ - float mass_interacted; + double mass_interacted; /* Anonymous union for id/part. */ union { diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 8ac9e5b65..9ec64f74f 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -25,7 +25,7 @@ #include "clocks.h" #include "part.h" -#define ICHECK 4934 +#define ICHECK 1 /** * @brief Compute the recursive upward sweep, i.e. construct the @@ -125,8 +125,9 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( if (gp->ti_end > ti_current) continue; if (gp->id == -ICHECK) - message("id=%lld mass=%f CoM=[%f %f %f]\n", gp->id, multi.mass, - multi.CoM[0], multi.CoM[1], multi.CoM[2]); + message("id=%lld x=[%f %f %f] mass=%f CoM=[ %f %f %f ] size= %f\n", gp->id, + gp->x[0], gp->x[1], gp->x[2], multi.mass, + multi.CoM[0], multi.CoM[1], multi.CoM[2], cj->h[0]); /* Compute the pairwise distance. */ const float dx[3] = {multi.CoM[0] - gp->x[0], // x @@ -210,6 +211,23 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( /* Anything to do here? */ // if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; + for (int pid = 0; pid < gcount_i; pid++) { + + struct gpart *restrict gp = &gparts_i[pid]; + if (gp->id == -ICHECK) + message("id=%lld size=%f\n", gp->id, cj->h[0]); + + } + + for (int pid = 0; pid < gcount_j; pid++) { + + struct gpart *restrict gp = &gparts_j[pid]; + if (gp->id == -ICHECK) + message("id=%lld size=%f\n", gp->id, ci->h[0]); + + } + + /* Loop over all particles in ci... */ for (int pid = 0; pid < gcount_i; pid++) { @@ -371,23 +389,23 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, /* cj->loc[2], cj->h[0]); */ } - for (int i = 0; i < gcount_i; i++) { + /* for (int i = 0; i < gcount_i; i++) { */ - struct gpart *const gp = &ci->gparts[i]; + /* struct gpart *const gp = &ci->gparts[i]; */ - if (gp->id == -ICHECK) - message("id=%lld a=[%f %f %f]\n", gp->id, gp->a_grav[0], gp->a_grav[1], - gp->a_grav[2]); - } + /* if (gp->id == -ICHECK) */ + /* message("id=%lld a=[%f %f %f]\n", gp->id, gp->a_grav[0], gp->a_grav[1], */ + /* gp->a_grav[2]); */ + /* } */ - for (int i = 0; i < gcount_j; i++) { + /* for (int i = 0; i < gcount_j; i++) { */ - struct gpart *const gp = &cj->gparts[i]; + /* struct gpart *const gp = &cj->gparts[i]; */ - if (gp->id == -ICHECK) - message("id=%lld a=[%f %f %f]\n", gp->id, gp->a_grav[0], gp->a_grav[1], - gp->a_grav[2]); - } + /* if (gp->id == -ICHECK) */ + /* message("id=%lld a=[%f %f %f]\n", gp->id, gp->a_grav[0], gp->a_grav[1], */ + /* gp->a_grav[2]); */ + /* } */ /* Are both cells split ? */ if (ci->split && cj->split) { diff --git a/src/scheduler.c b/src/scheduler.c index b9aac5a16..6271f80ca 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -172,8 +172,8 @@ void scheduler_splittasks(struct scheduler *s) { if (ci->split) { /* Make a sub? */ - if (scheduler_dosub && (ci->count * ci->count < space_subsize || - ci->gcount * ci->gcount < space_subsize)) { + if (scheduler_dosub && (ci->count * ci->count < space_subsize)) { + // ci->gcount * ci->gcount < space_subsize)) { /* convert to a self-subtask. */ t->type = task_type_sub; @@ -238,8 +238,8 @@ void scheduler_splittasks(struct scheduler *s) { /* Replace by a single sub-task? */ if (scheduler_dosub && - (ci->count * cj->count * sid_scale[sid] < space_subsize || - ci->gcount * cj->gcount * sid_scale[sid] < space_subsize) && + (ci->count * cj->count * sid_scale[sid] < space_subsize) &&// || + //ci->gcount * cj->gcount * sid_scale[sid] < space_subsize) && sid != 0 && sid != 2 && sid != 6 && sid != 8) { /* Make this task a sub task. */ -- GitLab From 249f4bc62b159132a3e7bad09dd13b505abaa4fe Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 2 Jun 2016 15:56:06 +0100 Subject: [PATCH 21/72] First correct gravity calculation (BH algorithm) --- src/engine.c | 57 ++++++++- src/runner.c | 8 +- src/runner_doiact_grav.h | 246 ++++++++++++++++++++++++--------------- src/scheduler.c | 183 +++++++---------------------- src/space.c | 2 + src/task.c | 8 +- src/task.h | 2 +- 7 files changed, 256 insertions(+), 250 deletions(-) diff --git a/src/engine.c b/src/engine.c index b577ae3bf..a21b5fe42 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1067,6 +1067,27 @@ void engine_exchange_strays(struct engine *e, size_t offset_parts, #endif } +__attribute__((always_inline)) INLINE static int are_neighbours( + const struct cell *restrict ci, const struct cell *restrict cj) { + +#ifdef SANITY_CHECKS + if (ci->h[0] != cj->h[0]) + error(" Cells of different size in distance calculation."); +#endif + + /* Maximum allowed distance */ + const double min_dist = 1.2 * ci->h[0]; /* 1.2 accounts for rounding errors */ + + /* (Manhattan) Distance between the cells */ + for (int k = 0; k < 3; k++) { + const double center_i = ci->loc[k]; + const double center_j = cj->loc[k]; + if (fabsf(center_i - center_j) > min_dist) return 0; + } + + return 1; +} + void engine_make_gravity_tasks(struct engine *e) { struct space *s = e->s; @@ -1101,8 +1122,20 @@ void engine_make_gravity_tasks(struct engine *e) { /* Is that neighbour local ? */ if (cj->nodeID != nodeID) continue; - scheduler_addtask(sched, task_type_pair, task_subtype_grav, 0, 0, ci, cj, - 1); +#ifdef SANITY_CHECKS + if (ci == cj) { + message("oO"); + continue; + } +#endif + + if (are_neighbours(ci, cj)) + scheduler_addtask(sched, task_type_pair, task_subtype_grav, 0, 0, ci, + cj, 1); + else + scheduler_addtask(sched, task_type_grav_mm, task_subtype_none, 0, 0, ci, + cj, 1); + ++counter; } } @@ -1320,6 +1353,14 @@ void engine_make_gravity_dependencies(struct engine *e) { /* Skip? */ if (t->skip) continue; + /* Long-range interaction */ + if (t->type == task_type_grav_mm) { + + scheduler_addunlock(sched, t->ci->super->init, t); + scheduler_addunlock(sched, t->ci->super->grav_up, t); + scheduler_addunlock(sched, t, t->ci->super->kick); + } + /* Self-interaction? */ if (t->type == task_type_self && t->subtype == task_subtype_grav) { @@ -2296,6 +2337,7 @@ void engine_step(struct engine *e) { if (e->policy & engine_policy_self_gravity) { mask |= 1 << task_type_grav_up; + mask |= 1 << task_type_grav_mm; mask |= 1 << task_type_self; mask |= 1 << task_type_pair; mask |= 1 << task_type_sub; @@ -2331,6 +2373,9 @@ void engine_step(struct engine *e) { s->gparts[k].x[0], s->gparts[k].x[1], s->gparts[k].x[2], s->gparts[k].a_grav[0], s->gparts[k].a_grav[1], s->gparts[k].a_grav[2]); + if (s->gparts[k].id == -1) + message("interacting mass= %f (%f)", s->gparts[k].mass_interacted, + s->gparts[k].mass_interacted + s->gparts[k].mass); } fclose(file); @@ -2339,10 +2384,10 @@ void engine_step(struct engine *e) { memcpy(temp, s->gparts, s->nr_gparts * sizeof(struct gpart)); gravity_n2(temp, s->nr_gparts); file = fopen("grav_brute.dat", "w"); - for(size_t k = 0; k < s->nr_gparts; ++k) { - fprintf(file, "%lld %f %f %f %f %f %f\n", temp[k].id, - temp[k].x[0], temp[k].x[1], temp[k].x[2], - temp[k].a_grav[0], temp[k].a_grav[1], temp[k].a_grav[2]); + for (size_t k = 0; k < s->nr_gparts; ++k) { + fprintf(file, "%lld %f %f %f %f %f %f\n", temp[k].id, temp[k].x[0], + temp[k].x[1], temp[k].x[2], temp[k].a_grav[0], temp[k].a_grav[1], + temp[k].a_grav[2]); } fclose(file); diff --git a/src/runner.c b/src/runner.c index 4d32cfd24..49223b46a 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1188,11 +1188,11 @@ void *runner_main(void *data) { /* else */ /* runner_dopair_grav(r, t->ci, t->cj); */ /* break; */ - /* case task_type_grav_mm: */ - /* runner_dograv_mm(r, t->ci, t->cj); */ - /* break; */ + case task_type_grav_mm: + runner_do_grav_mm(r, t->ci, t->cj); + break; case task_type_grav_up: - runner_dograv_up(r, t->ci); + runner_do_grav_up(r, t->ci); break; /* case task_type_grav_down: */ /* runner_dograv_down(r, t->ci); */ diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 9ec64f74f..2bed71825 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -25,7 +25,7 @@ #include "clocks.h" #include "part.h" -#define ICHECK 1 +#define ICHECK -1 /** * @brief Compute the recursive upward sweep, i.e. construct the @@ -34,13 +34,13 @@ * @param r The #runner. * @param c The top-level #cell. */ -void runner_dograv_up(struct runner *r, struct cell *c) { +void runner_do_grav_up(struct runner *r, struct cell *c) { if (c->split) {/* Regular node */ /* Recurse. */ for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) runner_dograv_up(r, c->progeny[k]); + if (c->progeny[k] != NULL) runner_do_grav_up(r, c->progeny[k]); /* Collect the multipoles from the progeny. */ multipole_reset(&c->multipole); @@ -98,11 +98,11 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( const struct runner *r, const struct cell *restrict ci, const struct cell *restrict cj) { - const struct engine *e = r->e; + // const struct engine *e = r->e; const int gcount = ci->gcount; struct gpart *restrict gparts = ci->gparts; const struct multipole multi = cj->multipole; - const int ti_current = e->ti_current; + // const int ti_current = e->ti_current; TIMER_TIC; @@ -115,6 +115,17 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( /* Anything to do here? */ // if (ci->ti_end_min > ti_current) return; + /* Loop over every particle in leaf. */ + /* for (int pid = 0; pid < gcount; pid++) { */ + + /* /\* Get a hold of the ith part in ci. *\/ */ + /* struct gpart *restrict gp = &gparts[pid]; */ + + /* if (gp->id == -ICHECK) */ + /* message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, + * cj->loc[0], */ + /* cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); */ + /* } */ /* Loop over every particle in leaf. */ for (int pid = 0; pid < gcount; pid++) { @@ -122,12 +133,9 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( /* Get a hold of the ith part in ci. */ struct gpart *restrict gp = &gparts[pid]; - if (gp->ti_end > ti_current) continue; + if (gp->id == -ICHECK) message("id=%lld mass= %f", gp->id, multi.mass); - if (gp->id == -ICHECK) - message("id=%lld x=[%f %f %f] mass=%f CoM=[ %f %f %f ] size= %f\n", gp->id, - gp->x[0], gp->x[1], gp->x[2], multi.mass, - multi.CoM[0], multi.CoM[1], multi.CoM[2], cj->h[0]); + // if (gp->ti_end > ti_current) continue; /* Compute the pairwise distance. */ const float dx[3] = {multi.CoM[0] - gp->x[0], // x @@ -147,7 +155,6 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( gp->a_grav[2] += mrinv3 * dx[2]; #elif multipole_order == 2 - /* Terms up to 2nd order (quadrupole) */ /* Follows the notation in Bonsai */ @@ -194,18 +201,18 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( struct runner *r, struct cell *ci, struct cell *cj) { - const struct engine *e = r->e; + // const struct engine *e = r->e; const int gcount_i = ci->gcount; const int gcount_j = cj->gcount; struct gpart *restrict gparts_i = ci->gparts; struct gpart *restrict gparts_j = cj->gparts; - const int ti_current = e->ti_current; + // const int ti_current = e->ti_current; TIMER_TIC; #ifdef SANITY_CHECKS if (ci->h[0] != cj->h[0]) // MATTHIEU sanity check - error("Non matching cell sizes !! h_i=%f h_j=%f\n", ci->h[0], cj->h[0]); + error("Non matching cell sizes !! h_i=%f h_j=%f", ci->h[0], cj->h[0]); #endif /* Anything to do here? */ @@ -213,21 +220,24 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( for (int pid = 0; pid < gcount_i; pid++) { + /* Get a hold of the ith part in ci. */ struct gpart *restrict gp = &gparts_i[pid]; - if (gp->id == -ICHECK) - message("id=%lld size=%f\n", gp->id, cj->h[0]); + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, cj->loc[0], + cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); } for (int pid = 0; pid < gcount_j; pid++) { + /* Get a hold of the ith part in ci. */ struct gpart *restrict gp = &gparts_j[pid]; - if (gp->id == -ICHECK) - message("id=%lld size=%f\n", gp->id, ci->h[0]); + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count=%d", gp->id, ci->loc[0], + ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); } - /* Loop over all particles in ci... */ for (int pid = 0; pid < gcount_i; pid++) { @@ -253,18 +263,18 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( const float w = ir * ir * ir; const float wdx[3] = {w * dx[0], w * dx[1], w * dx[2]}; - if (gpi->ti_end <= ti_current) { - gpi->a_grav[0] -= wdx[0] * mj; - gpi->a_grav[1] -= wdx[1] * mj; - gpi->a_grav[2] -= wdx[2] * mj; - gpi->mass_interacted += mj; - } - if (gpj->ti_end <= ti_current) { - gpj->a_grav[0] += wdx[0] * mi; - gpj->a_grav[1] += wdx[1] * mi; - gpj->a_grav[2] += wdx[2] * mi; - gpj->mass_interacted += mi; - } + // if (gpi->ti_end <= ti_current) { + gpi->a_grav[0] -= wdx[0] * mj; + gpi->a_grav[1] -= wdx[1] * mj; + gpi->a_grav[2] -= wdx[2] * mj; + gpi->mass_interacted += mj; + //} + // if (gpj->ti_end <= ti_current) { + gpj->a_grav[0] += wdx[0] * mi; + gpj->a_grav[1] += wdx[1] * mi; + gpj->a_grav[2] += wdx[2] * mi; + gpj->mass_interacted += mi; + // } } } @@ -282,10 +292,10 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( __attribute__((always_inline)) INLINE static void runner_doself_grav_pp(struct runner *r, struct cell *c) { - const struct engine *e = r->e; + // const struct engine *e = r->e; const int gcount = c->gcount; struct gpart *restrict gparts = c->gparts; - const int ti_current = e->ti_current; + // const int ti_current = e->ti_current; TIMER_TIC; @@ -297,6 +307,16 @@ __attribute__((always_inline)) /* Anything to do here? */ // if (c->ti_end_min > ti_current) return; + for (int pid = 0; pid < gcount; pid++) { + + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &gparts[pid]; + + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, c->loc[0], + c->loc[1], c->loc[2], c->h[0], c->gcount); + } + /* Loop over all particles in ci... */ for (int pid = 0; pid < gcount; pid++) { @@ -322,18 +342,18 @@ __attribute__((always_inline)) const float w = ir * ir * ir; const float wdx[3] = {w * dx[0], w * dx[1], w * dx[2]}; - if (gpi->ti_end <= ti_current) { - gpi->a_grav[0] -= wdx[0] * mj; - gpi->a_grav[1] -= wdx[1] * mj; - gpi->a_grav[2] -= wdx[2] * mj; - gpi->mass_interacted += mj; - } - if (gpj->ti_end <= ti_current) { - gpj->a_grav[0] += wdx[0] * mi; - gpj->a_grav[1] += wdx[1] * mi; - gpj->a_grav[2] += wdx[2] * mi; - gpj->mass_interacted += mi; - } + // if (gpi->ti_end <= ti_current) { + gpi->a_grav[0] -= wdx[0] * mj; + gpi->a_grav[1] -= wdx[1] * mj; + gpi->a_grav[2] -= wdx[2] * mj; + gpi->mass_interacted += mj; + //} + // if (gpj->ti_end <= ti_current) { + gpj->a_grav[0] += wdx[0] * mi; + gpj->a_grav[1] += wdx[1] * mi; + gpj->a_grav[2] += wdx[2] * mi; + gpj->mass_interacted += mi; + //} } } @@ -363,7 +383,7 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, /* Bad stuff will happen if cell sizes are different */ if (ci->h[0] != cj->h[0]) - error("Non matching cell sizes !! h_i=%f h_j=%f\n", ci->h[0], cj->h[0]); + error("Non matching cell sizes !! h_i=%f h_j=%f", ci->h[0], cj->h[0]); /* Sanity check */ if (ci == cj) @@ -373,68 +393,69 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, #endif - /* Are the cells direct neighbours? */ - if (!are_neighbours(ci, cj)) { + for (int pid = 0; pid < gcount_i; pid++) { - /* Ok, here we can go for particle-multipole interactions */ - runner_dopair_grav_pm(r, ci, cj); - runner_dopair_grav_pm(r, cj, ci); - - /* error( */ - /* "Non-neighbouring cells ! ci->x=[%f %f %f] ci->h=%f cj->loc=[%f %f - * %f] " */ - /* "cj->h=%f", */ - /* ci->loc[0], ci->loc[1], ci->loc[2], ci->h[0], cj->loc[0], cj->loc[1], - */ - /* cj->loc[2], cj->h[0]); */ + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &ci->gparts[pid]; + + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, cj->loc[0], + cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); } - /* for (int i = 0; i < gcount_i; i++) { */ + for (int pid = 0; pid < gcount_j; pid++) { - /* struct gpart *const gp = &ci->gparts[i]; */ + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &cj->gparts[pid]; - /* if (gp->id == -ICHECK) */ - /* message("id=%lld a=[%f %f %f]\n", gp->id, gp->a_grav[0], gp->a_grav[1], */ - /* gp->a_grav[2]); */ - /* } */ + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, ci->loc[0], + ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); + } - /* for (int i = 0; i < gcount_j; i++) { */ + /* Are the cells direct neighbours? */ + if (!are_neighbours(ci, cj)) { - /* struct gpart *const gp = &cj->gparts[i]; */ + /* Ok, here we can go for particle-multipole interactions */ + // runner_dopair_grav_pm(r, ci, cj); + // runner_dopair_grav_pm(r, cj, ci); - /* if (gp->id == -ICHECK) */ - /* message("id=%lld a=[%f %f %f]\n", gp->id, gp->a_grav[0], gp->a_grav[1], */ - /* gp->a_grav[2]); */ - /* } */ + error( + "Non-neighbouring cells ! ci->x=[%f %f %f] ci->h=%f cj->loc=[%f %f %f] " + "cj->h=%f", + ci->loc[0], ci->loc[1], ci->loc[2], ci->h[0], cj->loc[0], cj->loc[1], + cj->loc[2], cj->h[0]); + } else { - /* Are both cells split ? */ - if (ci->split && cj->split) { + /* Are both cells split ? */ + if (ci->split && cj->split) { - for (int j = 0; j < 8; j++) { - if (ci->progeny[j] != NULL) { + for (int j = 0; j < 8; j++) { + if (ci->progeny[j] != NULL) { - for (int k = 0; k < 8; k++) { - if (cj->progeny[k] != NULL) { + for (int k = 0; k < 8; k++) { + if (cj->progeny[k] != NULL) { - if (are_neighbours(ci->progeny[j], cj->progeny[k])) { + if (are_neighbours(ci->progeny[j], cj->progeny[k])) { - /* Recurse */ - runner_dopair_grav(r, ci->progeny[j], cj->progeny[k]); + /* Recurse */ + runner_dopair_grav(r, ci->progeny[j], cj->progeny[k]); - } else { + } else { - /* Ok, here we can go for particle-multipole interactions */ - runner_dopair_grav_pm(r, ci->progeny[j], cj->progeny[k]); - runner_dopair_grav_pm(r, cj->progeny[k], ci->progeny[j]); + /* Ok, here we can go for particle-multipole interactions */ + runner_dopair_grav_pm(r, ci->progeny[j], cj->progeny[k]); + runner_dopair_grav_pm(r, cj->progeny[k], ci->progeny[j]); + } } } } } - } - } else {/* Not split */ + } else {/* Not split */ - /* Compute the interactions at this level directly. */ - runner_dopair_grav_pp(r, ci, cj); + /* Compute the interactions at this level directly. */ + runner_dopair_grav_pp(r, ci, cj); + } } } @@ -448,14 +469,15 @@ static void runner_doself_grav(struct runner *r, struct cell *c) { if (gcount == 0) error("Empty cell !"); #endif - for (int i = 0; i < gcount; i++) { + /* for (int i = 0; i < gcount; i++) { */ - struct gpart *const gp = &c->gparts[i]; + /* struct gpart *const gp = &c->gparts[i]; */ - if (gp->id == -ICHECK) - message("id=%lld a=[%f %f %f]\n", gp->id, gp->a_grav[0], gp->a_grav[1], - gp->a_grav[2]); - } + /* if (gp->id == -ICHECK) */ + /* message("id=%lld a=[%f %f %f]", gp->id, gp->a_grav[0], gp->a_grav[1], + */ + /* gp->a_grav[2]); */ + /* } */ /* If the cell is split, interact each progeny with itself, and with each of its siblings. */ @@ -493,8 +515,10 @@ static void runner_dosub_grav(struct runner *r, struct cell *ci, } else { - /* if (!are_neighbours(ci, cj)) { */ + if (!are_neighbours(ci, cj)) { + error("Non-neighbouring cells in pair task !"); + } /* /\* Ok, here we can go for particle-multipole interactions *\/ */ /* runner_dopair_grav_pm(r, ci, cj); */ /* runner_dopair_grav_pm(r, cj, ci); */ @@ -508,4 +532,36 @@ static void runner_dosub_grav(struct runner *r, struct cell *ci, } } +static void runner_do_grav_mm(struct runner *r, struct cell *ci, + struct cell *cj) { + + for (int pid = 0; pid < ci->gcount; pid++) { + + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &ci->gparts[pid]; + + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, cj->loc[0], + cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); + } + + for (int pid = 0; pid < cj->gcount; pid++) { + + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &cj->gparts[pid]; + + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, ci->loc[0], + ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); + } + + if (are_neighbours(ci, cj)) { + + error("Non-neighbouring cells in mm task !"); + } + + runner_dopair_grav_pm(r, ci, cj); + runner_dopair_grav_pm(r, cj, ci); +} + #endif /* SWIFT_RUNNER_DOIACT_GRAV_H */ diff --git a/src/scheduler.c b/src/scheduler.c index 6271f80ca..44859d4c5 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -172,14 +172,12 @@ void scheduler_splittasks(struct scheduler *s) { if (ci->split) { /* Make a sub? */ - if (scheduler_dosub && (ci->count * ci->count < space_subsize)) { - // ci->gcount * ci->gcount < space_subsize)) { + if (scheduler_dosub && (ci->count * ci->count < space_subsize || //) { + ci->gcount * ci->gcount < space_subsize)) { /* convert to a self-subtask. */ t->type = task_type_sub; - // message("TASK type=%s subtype=%s", taskID_names[t->type], - // subtaskID_names[t->subtype]); } /* Otherwise, make tasks explicitly. */ @@ -188,8 +186,6 @@ void scheduler_splittasks(struct scheduler *s) { /* Take a step back (we're going to recycle the current task)... */ redo = 1; - // message("aa"); - /* Add the self task. */ int first_child = 0; while (ci->progeny[first_child] == NULL) first_child++; @@ -210,9 +206,39 @@ void scheduler_splittasks(struct scheduler *s) { } } + /* /\* Hydro Pair interaction? *\/ */ + /* else if (t->type == task_type_pair && t->subtype == task_subtype_grav) { + */ + + /* /\* Get a handle on the cells involved. *\/ */ + /* struct cell *ci = t->ci; */ + /* struct cell *cj = t->cj; */ + + /* /\* Foreign task? *\/ */ + /* if (ci->nodeID != s->nodeID && cj->nodeID != s->nodeID) { */ + /* t->skip = 1; */ + /* continue; */ + /* } */ + + /* if (ci->split && cj->split ) { */ + + /* /\* Replace by a single sub-task? *\/ */ + /* if (scheduler_dosub && ci->gcount * cj->gcount < space_subsize) { */ + + /* /\* Make this task a sub task. *\/ */ + /* t->type = task_type_sub; */ + /* } */ + + /* else { */ + /* message("oO"); */ + /* } */ - /* Pair interaction? */ - else if (t->type == task_type_pair) { + /* } */ + + /* } */ + + /* Hydro Pair interaction? */ + else if (t->type == task_type_pair && t->subtype != task_subtype_grav) { /* Get a handle on the cells involved. */ struct cell *ci = t->ci; @@ -238,8 +264,7 @@ void scheduler_splittasks(struct scheduler *s) { /* Replace by a single sub-task? */ if (scheduler_dosub && - (ci->count * cj->count * sid_scale[sid] < space_subsize) &&// || - //ci->gcount * cj->gcount * sid_scale[sid] < space_subsize) && + ci->count * cj->count * sid_scale[sid] < space_subsize && sid != 0 && sid != 2 && sid != 6 && sid != 8) { /* Make this task a sub task. */ @@ -523,139 +548,17 @@ void scheduler_splittasks(struct scheduler *s) { } /* pair interaction? */ - /* Gravity interaction? */ - /* else if (t->type == task_type_grav_mm) { */ + /* Long-range gravity interaction ? */ + else if (t->type == task_type_grav_mm) { - /* /\* Get a handle on the cells involved. *\/ */ - /* struct cell *ci = t->ci; */ - /* struct cell *cj = t->cj; */ - - /* /\* Self-interaction? *\/ */ - /* if (cj == NULL) { */ - - /* /\* Ignore this task if the cell has no gparts. *\/ */ - /* if (ci->gcount == 0) t->type = task_type_none; */ - - /* /\* If the cell is split, recurse. *\/ */ - /* else if (ci->split) { */ - - /* /\* Make a single sub-task? *\/ */ - /* if (scheduler_dosub && ci->gcount < space_subsize / ci->gcount) { - */ - - /* t->type = task_type_sub; */ - /* t->subtype = task_subtype_grav; */ - - /* } */ - - /* /\* Otherwise, just split the task. *\/ */ - /* else { */ - - /* /\* Split this task into tasks on its progeny. *\/ */ - /* t->type = task_type_none; */ - /* for (int j = 0; j < 8; j++) */ - /* if (ci->progeny[j] != NULL && ci->progeny[j]->gcount > 0) { */ - /* if (t->type == task_type_none) { */ - /* t->type = task_type_grav_mm; */ - /* t->ci = ci->progeny[j]; */ - /* t->cj = NULL; */ - /* } else */ - /* t = scheduler_addtask(s, task_type_grav_mm, - * task_subtype_none, */ - /* 0, 0, ci->progeny[j], NULL, 0); */ - /* for (int k = j + 1; k < 8; k++) */ - /* if (ci->progeny[k] != NULL && ci->progeny[k]->gcount > 0) { - */ - /* if (t->type == task_type_none) { */ - /* t->type = task_type_grav_mm; */ - /* t->ci = ci->progeny[j]; */ - /* t->cj = ci->progeny[k]; */ - /* } else */ - /* t = scheduler_addtask(s, task_type_grav_mm, */ - /* task_subtype_none, 0, 0, */ - /* ci->progeny[j], ci->progeny[k], - * 0); */ - /* } */ - /* } */ - /* redo = (t->type != task_type_none); */ - /* } */ - - /* } */ - - /* /\* Otherwise, just make a pp task out of it. *\/ */ - /* else */ - /* t->type = task_type_grav_pp; */ + /* Get a handle on the cells involved. */ + struct cell *ci = t->ci; + struct cell *cj = t->cj; - /* } */ + /* Safety thing */ + if (ci->gcount == 0 || cj->gcount == 0) t->type = task_type_none; - /* /\* Nope, pair. *\/ */ - /* else { */ - - /* /\* Make a sub-task? *\/ */ - /* if (scheduler_dosub && ci->gcount < space_subsize / cj->gcount) { */ - - /* t->type = task_type_sub; */ - /* t->subtype = task_subtype_grav; */ - - /* } */ - - /* /\* Otherwise, split the task. *\/ */ - /* else { */ - - /* /\* Get the opening angle theta. *\/ */ - /* float dx[3], theta; */ - /* for (int k = 0; k < 3; k++) { */ - /* dx[k] = fabs(ci->loc[k] - cj->loc[k]); */ - /* if (s->space->periodic && dx[k] > 0.5 * s->space->dim[k]) */ - /* dx[k] = -dx[k] + s->space->dim[k]; */ - /* if (dx[k] > 0.0f) dx[k] -= ci->h[k]; */ - /* } */ - /* theta = */ - /* (dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */ - /* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * - * ci->h[2]); */ - - /* /\* Ignore this task if the cell has no gparts. *\/ */ - /* if (ci->gcount == 0 || cj->gcount == 0) t->type = task_type_none; - */ - - /* /\* Split the interaction? *\/ */ - /* else if (theta < const_theta_max * const_theta_max) { */ - - /* /\* Are both ci and cj split? *\/ */ - /* if (ci->split && cj->split) { */ - - /* /\* Split this task into tasks on its progeny. *\/ */ - /* t->type = task_type_none; */ - /* for (int j = 0; j < 8; j++) */ - /* if (ci->progeny[j] != NULL && ci->progeny[j]->gcount > 0) { - */ - /* for (int k = 0; k < 8; k++) */ - /* if (cj->progeny[k] != NULL && cj->progeny[k]->gcount > 0) - * { */ - /* if (t->type == task_type_none) { */ - /* t->type = task_type_grav_mm; */ - /* t->ci = ci->progeny[j]; */ - /* t->cj = cj->progeny[k]; */ - /* } else */ - /* t = scheduler_addtask( */ - /* s, task_type_grav_mm, task_subtype_none, 0, 0, */ - /* ci->progeny[j], cj->progeny[k], 0); */ - /* } */ - /* } */ - /* redo = (t->type != task_type_none); */ - - /* } */ - - /* /\* Otherwise, make a pp task out of it. *\/ */ - /* else */ - /* t->type = task_type_grav_pp; */ - /* } */ - /* } */ - - /* } /\* gravity pair interaction? *\/ */ - - /* } /\* gravity interaction? *\/ */ + } /* gravity interaction? */ } /* loop over all tasks. */ } diff --git a/src/space.c b/src/space.c index d87107a80..c4b81646f 100644 --- a/src/space.c +++ b/src/space.c @@ -180,6 +180,8 @@ void space_regrid(struct space *s, double cell_max, int verbose) { } } + message("h_max: %f", s->h_max); + /* If we are running in parallel, make sure everybody agrees on how large the largest cell should be. */ #ifdef WITH_MPI diff --git a/src/task.c b/src/task.c index 77503d220..4069ac520 100644 --- a/src/task.c +++ b/src/task.c @@ -47,10 +47,10 @@ /* Task type names. */ const char *taskID_names[task_type_count] = { - "none", "sort", "self", "pair", "sub", - "init", "ghost", "drift", "kick", "send", - "recv", "grav_up", "grav_external", "part_sort", "gpart_sort", - "split_cell", "rewait"}; + "none", "sort", "self", "pair", "sub", + "init", "ghost", "drift", "kick", "send", + "recv", "grav_mm", "grav_up", "grav_external", "part_sort", + "gpart_sort", "split_cell", "rewait"}; const char *subtaskID_names[task_type_count] = {"none", "density", "force", "grav"}; diff --git a/src/task.h b/src/task.h index 4956860c9..b159fe0e5 100644 --- a/src/task.h +++ b/src/task.h @@ -45,7 +45,7 @@ enum task_types { task_type_send, task_type_recv, /* task_type_grav_pp, */ - /* task_type_grav_mm, */ + task_type_grav_mm, task_type_grav_up, /* task_type_grav_down, */ task_type_grav_external, -- GitLab From aea085eee7e85b5aa278be5e14f796f758ab9e3c Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 2 Jun 2016 16:20:32 +0100 Subject: [PATCH 22/72] Clean-up --- src/engine.c | 141 ++++++------------------------------------------ src/scheduler.c | 33 +----------- src/space.c | 2 - 3 files changed, 16 insertions(+), 160 deletions(-) diff --git a/src/engine.c b/src/engine.c index a21b5fe42..3a261be2a 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1088,6 +1088,13 @@ __attribute__((always_inline)) INLINE static int are_neighbours( return 1; } +/** + * @brief Constructs the top-level pair tasks for the gravity M-M interactions + * + * Correct implementation is still lacking here. + * + * @param e The #engine. + */ void engine_make_gravity_tasks(struct engine *e) { struct space *s = e->s; @@ -1096,8 +1103,6 @@ void engine_make_gravity_tasks(struct engine *e) { struct cell *cells = s->cells; const int nr_cells = s->nr_cells; - int counter = 0; - for (int cid = 0; cid < nr_cells; ++cid) { struct cell *ci = &cells[cid]; @@ -1122,79 +1127,14 @@ void engine_make_gravity_tasks(struct engine *e) { /* Is that neighbour local ? */ if (cj->nodeID != nodeID) continue; -#ifdef SANITY_CHECKS - if (ci == cj) { - message("oO"); - continue; - } -#endif - if (are_neighbours(ci, cj)) scheduler_addtask(sched, task_type_pair, task_subtype_grav, 0, 0, ci, cj, 1); else scheduler_addtask(sched, task_type_grav_mm, task_subtype_none, 0, 0, ci, cj, 1); - - ++counter; } } - - message("counter= %d nr_cells=%d", counter, nr_cells); - - /* /\* Run through the highest level of cells and add pairs. *\/ */ - /* for (int i = 0; i < cdim[0]; i++) { */ - /* for (int j = 0; j < cdim[1]; j++) { */ - /* for (int k = 0; k < cdim[2]; k++) { */ - - /* /\* Get the cell *\/ */ - /* const int cid = cell_getid(cdim, i, j, k); */ - /* struct cell *ci = &cells[cid]; */ - - /* /\* Skip cells without gravity particles *\/ */ - /* if (ci->gcount == 0) continue; */ - - /* /\* If the cells is local build a self-interaction *\/ */ - /* if (ci->nodeID == nodeID) */ - /* scheduler_addtask(sched, task_type_self, task_subtype_grav, 0, 0, - * ci, */ - /* NULL, 0); */ - - /* /\* Now loop over all the neighbours of this cell *\/ */ - /* for (int ii = -1; ii < 2; ii++) { */ - /* int iii = i + ii; */ - /* if (!s->periodic && (iii < 0 || iii >= cdim[0])) continue; */ - /* iii = (iii + cdim[0]) % cdim[0]; */ - /* for (int jj = -1; jj < 2; jj++) { */ - /* int jjj = j + jj; */ - /* if (!s->periodic && (jjj < 0 || jjj >= cdim[1])) continue; */ - /* jjj = (jjj + cdim[1]) % cdim[1]; */ - /* for (int kk = -1; kk < 2; kk++) { */ - /* int kkk = k + kk; */ - /* if (!s->periodic && (kkk < 0 || kkk >= cdim[2])) continue; */ - /* kkk = (kkk + cdim[2]) % cdim[2]; */ - - /* /\* Get the neighbouring cell *\/ */ - /* const int cjd = cell_getid(cdim, iii, jjj, kkk); */ - /* struct cell *cj = &cells[cjd]; */ - - /* /\* Is that neighbour local and does it have particles ? *\/ */ - /* if (cid >= cjd || cj->gcount == 0 || */ - /* (ci->nodeID != nodeID && cj->nodeID != nodeID)) */ - /* continue; */ - - /* /\* Construct the pair task *\/ */ - /* const int sid = */ - /* sortlistID[(kk + 1) + 3 * ((jj + 1) + 3 * (ii + 1))]; */ - /* scheduler_addtask(sched, task_type_pair, task_subtype_grav, - * sid, */ - /* 0, ci, cj, 1); */ - /* } */ - /* } */ - /* } */ - /* } */ - /* } */ - /* } */ } /** @@ -1324,18 +1264,6 @@ void engine_count_and_link_tasks(struct engine *e) { } } } - - /* /\* Link gravity multipole tasks to the up/down tasks. *\/ */ - /* if (t->type == task_type_grav_mm || */ - /* (t->type == task_type_sub && t->subtype == task_subtype_grav)) { */ - /* atomic_inc(&t->ci->nr_tasks); */ - /* scheduler_addunlock(sched, t->ci->grav_up, t); */ - /* scheduler_addunlock(sched, t, t->ci->grav_down); */ - /* if (t->cj != NULL && t->ci->grav_up != t->cj->grav_up) { */ - /* scheduler_addunlock(sched, t->cj->grav_up, t); */ - /* scheduler_addunlock(sched, t, t->cj->grav_down); */ - /* } */ - /* } */ } } @@ -1528,44 +1456,6 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { } } -/** - * @brief Constructs the top-level pair tasks for the gravity M-M interactions - * - * Correct implementation is still lacking here. - * - * @param e The #engine. - */ -void engine_make_gravityinteraction_tasks(struct engine *e) { - - struct space *s = e->s; - /* struct scheduler *sched = &e->sched; */ - const int nr_cells = s->nr_cells; - /* struct cell *cells = s->cells; */ - - /* Loop over all cells. */ - for (int i = 0; i < nr_cells; i++) { - - /* /\* If it has gravity particles, add a self-task *\/ */ - /* if (cells[i].gcount > 0) { */ - /* scheduler_addtask(sched, task_type_grav_mm, task_subtype_none, -1, 0, - */ - /* &cells[i], NULL, 0); */ - - /* /\* Loop over all remainding cells *\/ */ - /* for (int j = i + 1; j < nr_cells; j++) { */ - - /* /\* If that other cell has gravity parts, add a pair interaction *\/ - */ - /* if (cells[j].gcount > 0) { */ - /* scheduler_addtask(sched, task_type_grav_mm, task_subtype_none, -1, - * 0, */ - /* &cells[i], &cells[j], 0); */ - /* } */ - /* } */ - /* } */ - } -} - /** * @brief Constructs the gravity tasks building the multipoles and propagating *them to the children @@ -1629,7 +1519,7 @@ void engine_maketasks(struct engine *e) { } /* Construct the firt hydro loop over neighbours */ - engine_make_hydroloop_tasks(e); + if (e->policy & engine_policy_hydro) engine_make_hydroloop_tasks(e); /* Add the gravity mm tasks. */ if (e->policy & engine_policy_self_gravity) engine_make_gravity_tasks(e); @@ -1653,7 +1543,7 @@ void engine_maketasks(struct engine *e) { /* Count the number of tasks associated with each cell and store the density tasks in each cell, and make each sort depend on the sorts of its progeny. */ - engine_count_and_link_tasks(e); + if (e->policy & engine_policy_hydro) engine_count_and_link_tasks(e); /* Append hierarchical tasks to each cells */ for (int k = 0; k < nr_cells; k++) @@ -1662,7 +1552,7 @@ void engine_maketasks(struct engine *e) { /* Run through the tasks and make force tasks for each density task. Each force task depends on the cell ghosts and unlocks the kick task of its super-cell. */ - engine_make_extra_hydroloop_tasks(e); + if (e->policy & engine_policy_hydro) engine_make_extra_hydroloop_tasks(e); /* Add the dependencies for the self-gravity stuff */ if (e->policy & engine_policy_self_gravity) @@ -2126,8 +2016,6 @@ void engine_init_particles(struct engine *e) { engine_marktasks(e); - // error(""); - /* Build the masks corresponding to the policy */ unsigned int mask = 0; unsigned int submask = 0; @@ -2151,11 +2039,12 @@ void engine_init_particles(struct engine *e) { if (e->policy & engine_policy_self_gravity) { mask |= 1 << task_type_grav_up; - /* mask |= 1 << task_type_self; */ - /* mask |= 1 << task_type_pair; */ - /* mask |= 1 << task_type_sub; */ + mask |= 1 << task_type_grav_mm; + mask |= 1 << task_type_self; + mask |= 1 << task_type_pair; + mask |= 1 << task_type_sub; - /* submask |= 1 << task_subtype_grav; */ + submask |= 1 << task_subtype_grav; } /* Add the tasks corresponding to external gravity to the masks */ diff --git a/src/scheduler.c b/src/scheduler.c index 44859d4c5..59efb08fe 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -172,7 +172,7 @@ void scheduler_splittasks(struct scheduler *s) { if (ci->split) { /* Make a sub? */ - if (scheduler_dosub && (ci->count * ci->count < space_subsize || //) { + if (scheduler_dosub && (ci->count * ci->count < space_subsize || ci->gcount * ci->gcount < space_subsize)) { /* convert to a self-subtask. */ @@ -204,38 +204,7 @@ void scheduler_splittasks(struct scheduler *s) { ci->progeny[j], ci->progeny[k], 0); } } - } - /* /\* Hydro Pair interaction? *\/ */ - /* else if (t->type == task_type_pair && t->subtype == task_subtype_grav) { - */ - - /* /\* Get a handle on the cells involved. *\/ */ - /* struct cell *ci = t->ci; */ - /* struct cell *cj = t->cj; */ - - /* /\* Foreign task? *\/ */ - /* if (ci->nodeID != s->nodeID && cj->nodeID != s->nodeID) { */ - /* t->skip = 1; */ - /* continue; */ - /* } */ - - /* if (ci->split && cj->split ) { */ - - /* /\* Replace by a single sub-task? *\/ */ - /* if (scheduler_dosub && ci->gcount * cj->gcount < space_subsize) { */ - - /* /\* Make this task a sub task. *\/ */ - /* t->type = task_type_sub; */ - /* } */ - - /* else { */ - /* message("oO"); */ - /* } */ - - /* } */ - - /* } */ /* Hydro Pair interaction? */ else if (t->type == task_type_pair && t->subtype != task_subtype_grav) { diff --git a/src/space.c b/src/space.c index c4b81646f..d87107a80 100644 --- a/src/space.c +++ b/src/space.c @@ -180,8 +180,6 @@ void space_regrid(struct space *s, double cell_max, int verbose) { } } - message("h_max: %f", s->h_max); - /* If we are running in parallel, make sure everybody agrees on how large the largest cell should be. */ #ifdef WITH_MPI -- GitLab From 9b46e5fa23cb53f3dc952a0d99498e4f78de68f2 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 2 Jun 2016 17:11:23 +0100 Subject: [PATCH 23/72] Missing dependencies --- src/engine.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/engine.c b/src/engine.c index 3a261be2a..5b7bef412 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1287,6 +1287,10 @@ void engine_make_gravity_dependencies(struct engine *e) { scheduler_addunlock(sched, t->ci->super->init, t); scheduler_addunlock(sched, t->ci->super->grav_up, t); scheduler_addunlock(sched, t, t->ci->super->kick); + + scheduler_addunlock(sched, t->cj->super->init, t); + scheduler_addunlock(sched, t->cj->super->grav_up, t); + scheduler_addunlock(sched, t, t->cj->super->kick); } /* Self-interaction? */ -- GitLab From e9c61c1d52f8b332dccfae08446d5d8196060700 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 2 Jun 2016 17:36:31 +0100 Subject: [PATCH 24/72] Removed debugging info --- src/const.h | 2 +- src/runner_doiact_grav.h | 141 +++++++++++++++++---------------------- 2 files changed, 62 insertions(+), 81 deletions(-) diff --git a/src/const.h b/src/const.h index 856043bf2..6b9a4d2f7 100644 --- a/src/const.h +++ b/src/const.h @@ -61,6 +61,6 @@ /* Gravity properties */ #define EXTERNAL_POTENTIAL_POINTMASS -#define SANITY_CHECKS +//#define SANITY_CHECKS #endif /* SWIFT_CONST_H */ diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 2bed71825..f6c7769a7 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -218,25 +218,27 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( /* Anything to do here? */ // if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; - for (int pid = 0; pid < gcount_i; pid++) { + /* for (int pid = 0; pid < gcount_i; pid++) { */ - /* Get a hold of the ith part in ci. */ - struct gpart *restrict gp = &gparts_i[pid]; + /* /\* Get a hold of the ith part in ci. *\/ */ + /* struct gpart *restrict gp = &gparts_i[pid]; */ - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, cj->loc[0], - cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); - } + /* if (gp->id == -ICHECK) */ + /* message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, + * cj->loc[0], */ + /* cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); */ + /* } */ - for (int pid = 0; pid < gcount_j; pid++) { + /* for (int pid = 0; pid < gcount_j; pid++) { */ - /* Get a hold of the ith part in ci. */ - struct gpart *restrict gp = &gparts_j[pid]; + /* /\* Get a hold of the ith part in ci. *\/ */ + /* struct gpart *restrict gp = &gparts_j[pid]; */ - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count=%d", gp->id, ci->loc[0], - ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); - } + /* if (gp->id == -ICHECK) */ + /* message("id=%lld loc=[ %f %f %f ] size= %f count=%d", gp->id, + * ci->loc[0], */ + /* ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); */ + /* } */ /* Loop over all particles in ci... */ for (int pid = 0; pid < gcount_i; pid++) { @@ -307,15 +309,16 @@ __attribute__((always_inline)) /* Anything to do here? */ // if (c->ti_end_min > ti_current) return; - for (int pid = 0; pid < gcount; pid++) { + /* for (int pid = 0; pid < gcount; pid++) { */ - /* Get a hold of the ith part in ci. */ - struct gpart *restrict gp = &gparts[pid]; + /* /\* Get a hold of the ith part in ci. *\/ */ + /* struct gpart *restrict gp = &gparts[pid]; */ - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, c->loc[0], - c->loc[1], c->loc[2], c->h[0], c->gcount); - } + /* if (gp->id == -ICHECK) */ + /* message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, + * c->loc[0], */ + /* c->loc[1], c->loc[2], c->h[0], c->gcount); */ + /* } */ /* Loop over all particles in ci... */ for (int pid = 0; pid < gcount; pid++) { @@ -373,11 +376,11 @@ __attribute__((always_inline)) static void runner_dopair_grav(struct runner *r, struct cell *ci, struct cell *cj) { +#ifdef SANITY_CHECKS + const int gcount_i = ci->gcount; const int gcount_j = cj->gcount; -#ifdef SANITY_CHECKS - /* Early abort? */ if (gcount_i == 0 || gcount_j == 0) error("Empty cell !"); @@ -393,38 +396,37 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, #endif - for (int pid = 0; pid < gcount_i; pid++) { + /* for (int pid = 0; pid < gcount_i; pid++) { */ - /* Get a hold of the ith part in ci. */ - struct gpart *restrict gp = &ci->gparts[pid]; + /* /\* Get a hold of the ith part in ci. *\/ */ + /* struct gpart *restrict gp = &ci->gparts[pid]; */ - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, cj->loc[0], - cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); - } + /* if (gp->id == -ICHECK) */ + /* message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, + * cj->loc[0], */ + /* cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); */ + /* } */ - for (int pid = 0; pid < gcount_j; pid++) { + /* for (int pid = 0; pid < gcount_j; pid++) { */ - /* Get a hold of the ith part in ci. */ - struct gpart *restrict gp = &cj->gparts[pid]; + /* /\* Get a hold of the ith part in ci. *\/ */ + /* struct gpart *restrict gp = &cj->gparts[pid]; */ - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, ci->loc[0], - ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); - } + /* if (gp->id == -ICHECK) */ + /* message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, + * ci->loc[0], */ + /* ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); */ + /* } */ /* Are the cells direct neighbours? */ if (!are_neighbours(ci, cj)) { - /* Ok, here we can go for particle-multipole interactions */ - // runner_dopair_grav_pm(r, ci, cj); - // runner_dopair_grav_pm(r, cj, ci); - error( "Non-neighbouring cells ! ci->x=[%f %f %f] ci->h=%f cj->loc=[%f %f %f] " "cj->h=%f", ci->loc[0], ci->loc[1], ci->loc[2], ci->h[0], cj->loc[0], cj->loc[1], cj->loc[2], cj->h[0]); + } else { /* Are both cells split ? */ @@ -461,24 +463,12 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, static void runner_doself_grav(struct runner *r, struct cell *c) { - const int gcount = c->gcount; - #ifdef SANITY_CHECKS /* Early abort? */ - if (gcount == 0) error("Empty cell !"); + if (c->gcount == 0) error("Empty cell !"); #endif - /* for (int i = 0; i < gcount; i++) { */ - - /* struct gpart *const gp = &c->gparts[i]; */ - - /* if (gp->id == -ICHECK) */ - /* message("id=%lld a=[%f %f %f]", gp->id, gp->a_grav[0], gp->a_grav[1], - */ - /* gp->a_grav[2]); */ - /* } */ - /* If the cell is split, interact each progeny with itself, and with each of its siblings. */ if (c->split) { @@ -515,45 +505,36 @@ static void runner_dosub_grav(struct runner *r, struct cell *ci, } else { - if (!are_neighbours(ci, cj)) { - - error("Non-neighbouring cells in pair task !"); - } - /* /\* Ok, here we can go for particle-multipole interactions *\/ */ - /* runner_dopair_grav_pm(r, ci, cj); */ - /* runner_dopair_grav_pm(r, cj, ci); */ - - /* } */ - /* else { */ + if (!are_neighbours(ci, cj)) error("Non-neighbouring cells in pair task !"); runner_dopair_grav(r, ci, cj); - - /* } */ } } static void runner_do_grav_mm(struct runner *r, struct cell *ci, struct cell *cj) { - for (int pid = 0; pid < ci->gcount; pid++) { + /* for (int pid = 0; pid < ci->gcount; pid++) { */ - /* Get a hold of the ith part in ci. */ - struct gpart *restrict gp = &ci->gparts[pid]; + /* /\* Get a hold of the ith part in ci. *\/ */ + /* struct gpart *restrict gp = &ci->gparts[pid]; */ - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, cj->loc[0], - cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); - } + /* if (gp->id == -ICHECK) */ + /* message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, + * cj->loc[0], */ + /* cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); */ + /* } */ - for (int pid = 0; pid < cj->gcount; pid++) { + /* for (int pid = 0; pid < cj->gcount; pid++) { */ - /* Get a hold of the ith part in ci. */ - struct gpart *restrict gp = &cj->gparts[pid]; + /* /\* Get a hold of the ith part in ci. *\/ */ + /* struct gpart *restrict gp = &cj->gparts[pid]; */ - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, ci->loc[0], - ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); - } + /* if (gp->id == -ICHECK) */ + /* message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, + * ci->loc[0], */ + /* ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); */ + /* } */ if (are_neighbours(ci, cj)) { -- GitLab From 904ad2c4d5e66e3bcefc790076981643dd114996 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 2 Jun 2016 17:42:11 +0100 Subject: [PATCH 25/72] Simplified logic --- src/runner_doiact_grav.h | 54 +++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index f6c7769a7..0373c27cd 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -394,6 +394,14 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, "The impossible has happened: pair interaction between a cell and " "itself."); + /* Are the cells direct neighbours? */ + if (!are_neighbours(ci, cj)) + error( + "Non-neighbouring cells ! ci->x=[%f %f %f] ci->h=%f cj->loc=[%f %f %f] " + "cj->h=%f", + ci->loc[0], ci->loc[1], ci->loc[2], ci->h[0], cj->loc[0], cj->loc[1], + cj->loc[2], cj->h[0]); + #endif /* for (int pid = 0; pid < gcount_i; pid++) { */ @@ -418,46 +426,34 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, /* ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); */ /* } */ - /* Are the cells direct neighbours? */ - if (!are_neighbours(ci, cj)) { - - error( - "Non-neighbouring cells ! ci->x=[%f %f %f] ci->h=%f cj->loc=[%f %f %f] " - "cj->h=%f", - ci->loc[0], ci->loc[1], ci->loc[2], ci->h[0], cj->loc[0], cj->loc[1], - cj->loc[2], cj->h[0]); - - } else { - - /* Are both cells split ? */ - if (ci->split && cj->split) { + /* Are both cells split ? */ + if (ci->split && cj->split) { - for (int j = 0; j < 8; j++) { - if (ci->progeny[j] != NULL) { + for (int j = 0; j < 8; j++) { + if (ci->progeny[j] != NULL) { - for (int k = 0; k < 8; k++) { - if (cj->progeny[k] != NULL) { + for (int k = 0; k < 8; k++) { + if (cj->progeny[k] != NULL) { - if (are_neighbours(ci->progeny[j], cj->progeny[k])) { + if (are_neighbours(ci->progeny[j], cj->progeny[k])) { - /* Recurse */ - runner_dopair_grav(r, ci->progeny[j], cj->progeny[k]); + /* Recurse */ + runner_dopair_grav(r, ci->progeny[j], cj->progeny[k]); - } else { + } else { - /* Ok, here we can go for particle-multipole interactions */ - runner_dopair_grav_pm(r, ci->progeny[j], cj->progeny[k]); - runner_dopair_grav_pm(r, cj->progeny[k], ci->progeny[j]); - } + /* Ok, here we can go for particle-multipole interactions */ + runner_dopair_grav_pm(r, ci->progeny[j], cj->progeny[k]); + runner_dopair_grav_pm(r, cj->progeny[k], ci->progeny[j]); } } } } - } else {/* Not split */ - - /* Compute the interactions at this level directly. */ - runner_dopair_grav_pp(r, ci, cj); } + } else {/* Not split */ + + /* Compute the interactions at this level directly. */ + runner_dopair_grav_pp(r, ci, cj); } } -- GitLab From 0e904f5a3ca386e350b45f8e04541fd68846dfea Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Fri, 3 Jun 2016 16:03:46 +0100 Subject: [PATCH 26/72] Multiply the accelerations by G, add a softening length to the particles and compute time-step --- src/const.h | 4 +- src/engine.c | 6 +-- src/gravity/Default/gravity.h | 19 +++++-- src/gravity/Default/gravity_iact.h | 80 +----------------------------- src/gravity/Default/gravity_part.h | 9 ++-- src/hydro/Gadget2/hydro_io.h | 4 +- src/kernel_gravity.c | 4 +- src/kernel_gravity.h | 1 + src/runner.c | 5 +- src/tools.c | 11 +++- src/tools.h | 6 ++- 11 files changed, 47 insertions(+), 102 deletions(-) diff --git a/src/const.h b/src/const.h index 6b9a4d2f7..c004e4e2e 100644 --- a/src/const.h +++ b/src/const.h @@ -41,9 +41,7 @@ /* Gravity stuff. */ #define multipole_order 2 -#define const_theta_max 0.57735f -#define const_G 6.672e-8f /* Gravitational constant. */ -#define const_epsilon 0.0014f /* Gravity blending distance. */ +#define const_gravity_eta 0.025f /* Kernel function to use */ #define CUBIC_SPLINE_KERNEL diff --git a/src/engine.c b/src/engine.c index 5b7bef412..de78f1ba3 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2262,7 +2262,7 @@ void engine_step(struct engine *e) { FILE *file = fopen("grav_swift.dat", "w"); for (size_t k = 0; k < s->nr_gparts; ++k) { - fprintf(file, "%lld %f %f %f %f %f %f\n", s->gparts[k].id, + fprintf(file, "%lld %f %f %f %e %e %e\n", s->gparts[k].id, s->gparts[k].x[0], s->gparts[k].x[1], s->gparts[k].x[2], s->gparts[k].a_grav[0], s->gparts[k].a_grav[1], s->gparts[k].a_grav[2]); @@ -2275,10 +2275,10 @@ void engine_step(struct engine *e) { /* Check the gravity accelerations */ struct gpart *temp = malloc(s->nr_gparts * sizeof(struct gpart)); memcpy(temp, s->gparts, s->nr_gparts * sizeof(struct gpart)); - gravity_n2(temp, s->nr_gparts); + gravity_n2(temp, s->nr_gparts, e->physical_constants); file = fopen("grav_brute.dat", "w"); for (size_t k = 0; k < s->nr_gparts; ++k) { - fprintf(file, "%lld %f %f %f %f %f %f\n", temp[k].id, temp[k].x[0], + fprintf(file, "%lld %f %f %f %e %e %e\n", temp[k].id, temp[k].x[0], temp[k].x[1], temp[k].x[2], temp[k].a_grav[0], temp[k].a_grav[1], temp[k].a_grav[2]); } diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h index cd3e0dc80..e5e40def1 100644 --- a/src/gravity/Default/gravity.h +++ b/src/gravity/Default/gravity.h @@ -50,8 +50,6 @@ __attribute__((always_inline)) /** * @brief Computes the gravity time-step of a given particle due to self-gravity * - * This function only branches towards the potential chosen by the user. - * * @param phys_const The physical constants in internal units. * @param gp Pointer to the g-particle data. */ @@ -60,7 +58,13 @@ __attribute__((always_inline)) const struct phys_const* const phys_const, const struct gpart* const gp) { - float dt = FLT_MAX; + const float ac2 = gp->a_grav[0] * gp->a_grav[0] + + gp->a_grav[1] * gp->a_grav[1] + + gp->a_grav[2] * gp->a_grav[2]; + + const float ac = ac2 > 0. ? sqrtf(ac) : FLT_MIN; + + const float dt = sqrt(2.f * const_gravity_eta * gp->epsilon / ac); return dt; } @@ -101,9 +105,16 @@ __attribute__((always_inline)) * Multiplies the forces and accelerations by the appropiate constants * * @param gp The particle to act upon + * @param const_G Newton's constant */ __attribute__((always_inline)) - INLINE static void gravity_end_force(struct gpart* gp) {} +INLINE static void gravity_end_force(struct gpart* gp, double const_G) { + + /* Let's get physical... */ + gp->a_grav[0] *= const_G; + gp->a_grav[1] *= const_G; + gp->a_grav[2] *= const_G; +} /** * @brief Computes the gravitational acceleration induced by external potentials diff --git a/src/gravity/Default/gravity_iact.h b/src/gravity/Default/gravity_iact.h index 62023345f..6d8aa3261 100644 --- a/src/gravity/Default/gravity_iact.h +++ b/src/gravity/Default/gravity_iact.h @@ -29,88 +29,12 @@ * @brief Gravity potential */ __attribute__((always_inline)) INLINE static void runner_iact_grav( - float r2, float *dx, struct gpart *pi, struct gpart *pj) { - - float ir, r; - float w, acc; - float mi = pi->mass, mj = pj->mass; - int k; - - /* Get the absolute distance. */ - ir = 1.0f / sqrtf(r2); - r = r2 * ir; - - /* Evaluate the gravity kernel. */ - kernel_grav_eval(r, &acc); - - /* Scale the acceleration. */ - acc *= const_G * ir * ir * ir; - - /* Aggregate the accelerations. */ - for (k = 0; k < 3; k++) { - w = acc * dx[k]; - pi->a_grav[k] -= w * mj; - pj->a_grav[k] += w * mi; - } -} + float r2, float *dx, struct gpart *pi, struct gpart *pj) {} /** * @brief Gravity potential (Vectorized version) */ __attribute__((always_inline)) INLINE static void runner_iact_vec_grav( - float *R2, float *Dx, struct gpart **pi, struct gpart **pj) { - -#ifdef VECTORIZE - - vector ir, r, r2, dx[3]; - vector w, acc, ai, aj; - vector mi, mj; - int j, k; - -#if VEC_SIZE == 8 - mi.v = vec_set(pi[0]->mass, pi[1]->mass, pi[2]->mass, pi[3]->mass, - pi[4]->mass, pi[5]->mass, pi[6]->mass, pi[7]->mass); - mj.v = vec_set(pj[0]->mass, pj[1]->mass, pj[2]->mass, pj[3]->mass, - pj[4]->mass, pj[5]->mass, pj[6]->mass, pj[7]->mass); - for (k = 0; k < 3; k++) - dx[k].v = vec_set(Dx[0 + k], Dx[3 + k], Dx[6 + k], Dx[9 + k], Dx[12 + k], - Dx[15 + k], Dx[18 + k], Dx[21 + k]); -#elif VEC_SIZE == 4 - mi.v = vec_set(pi[0]->mass, pi[1]->mass, pi[2]->mass, pi[3]->mass); - mj.v = vec_set(pj[0]->mass, pj[1]->mass, pj[2]->mass, pj[3]->mass); - for (k = 0; k < 3; k++) - dx[k].v = vec_set(Dx[0 + k], Dx[3 + k], Dx[6 + k], Dx[9 + k]); -#endif - - /* Get the radius and inverse radius. */ - r2.v = vec_load(R2); - ir.v = vec_rsqrt(r2.v); - ir.v = ir.v - vec_set1(0.5f) * ir.v * (r2.v * ir.v * ir.v - vec_set1(1.0f)); - r.v = r2.v * ir.v; - - /* Evaluate the gravity kernel. */ - blender_eval_vec(&r, &acc); - - /* Scale the acceleration. */ - acc.v *= vec_set1(const_G) * ir.v * ir.v * ir.v; - - /* Aggregate the accelerations. */ - for (k = 0; k < 3; k++) { - w.v = acc.v * dx[k].v; - ai.v = w.v * mj.v; - aj.v = w.v * mi.v; - for (j = 0; j < VEC_SIZE; j++) { - pi[j]->a_grav[k] -= ai.f[j]; - pj[j]->a_grav[k] += aj.f[j]; - } - } - -#else - - for (int k = 0; k < VEC_SIZE; k++) - runner_iact_grav(R2[k], &Dx[3 * k], pi[k], pj[k]); - -#endif -} + float *R2, float *Dx, struct gpart **pi, struct gpart **pj) {} #endif /* SWIFT_RUNNER_IACT_GRAV_H */ diff --git a/src/gravity/Default/gravity_part.h b/src/gravity/Default/gravity_part.h index 2d3bc69ba..6eadcd503 100644 --- a/src/gravity/Default/gravity_part.h +++ b/src/gravity/Default/gravity_part.h @@ -37,18 +37,17 @@ struct gpart { /* Particle mass. */ float mass; + /* Softening length */ + float epsilon; + /* Particle time of beginning of time-step. */ int ti_begin; /* Particle time of end of time-step. */ int ti_end; - /* /\* current time of x, and of v_full *\/ */ - /* float tx; */ - /* float tv; */ - double mass_interacted; - + /* Anonymous union for id/part. */ union { diff --git a/src/hydro/Gadget2/hydro_io.h b/src/hydro/Gadget2/hydro_io.h index 41f3348db..eccfef645 100644 --- a/src/hydro/Gadget2/hydro_io.h +++ b/src/hydro/Gadget2/hydro_io.h @@ -83,8 +83,8 @@ __attribute__((always_inline)) INLINE static void hydro_write_particles( writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "SmoothingLength", FLOAT, N, 1, parts, N_total, mpi_rank, offset, h, us, UNIT_CONV_LENGTH); - writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "Entropy", - FLOAT, N, 1, parts, N_total, mpi_rank, offset, entropy, us, + writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "Entropy", FLOAT, N, + 1, parts, N_total, mpi_rank, offset, entropy, us, UNIT_CONV_ENTROPY_PER_UNIT_MASS); writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "ParticleIDs", ULONGLONG, N, 1, parts, N_total, mpi_rank, offset, id, us, diff --git a/src/kernel_gravity.c b/src/kernel_gravity.c index 639a964c8..4a5df7a87 100644 --- a/src/kernel_gravity.c +++ b/src/kernel_gravity.c @@ -42,7 +42,7 @@ float gadget(float r) { (21.333333333333 - 48.0 * u + 38.4 * u * u - 10.666666666667 * u * u * u - 0.066666666667 / (u * u * u)); } - return const_G * fac; + return fac; } /** @@ -66,7 +66,7 @@ void gravity_kernel_dump(float r_max, int N) { x4[1] = x4[0]; x4[0] = x; kernel_grav_eval(x, &w); - w *= const_G / (x * x * x); + w *= 1.f / (x * x * x); // blender_deval_vec( (vector *)x4 , (vector *)w4 , (vector *)dw_dx4 ); printf(" %.16e %.16e %.16e %.16e %.16e %.16e %.16e\n", x, w * x, w4[0], w4[1], w4[2], w4[3], gadget(x) * x); diff --git a/src/kernel_gravity.h b/src/kernel_gravity.h index cca449efa..e976c6108 100644 --- a/src/kernel_gravity.h +++ b/src/kernel_gravity.h @@ -25,6 +25,7 @@ #include "inline.h" #include "vector.h" +#define const_epsilon 1. #define const_iepsilon (1. / const_epsilon) #define const_iepsilon2 (const_iepsilon *const_iepsilon) #define const_iepsilon3 (const_iepsilon2 *const_iepsilon) diff --git a/src/runner.c b/src/runner.c index 49223b46a..76f512d9d 100644 --- a/src/runner.c +++ b/src/runner.c @@ -725,6 +725,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { const struct external_potential *potential = r->e->external_potential; const struct hydro_props *hydro_properties = r->e->hydro_properties; const struct phys_const *constants = r->e->physical_constants; + const double const_G = constants->const_newton_G; const float ln_max_h_change = hydro_properties->log_max_h_change; const int is_fixdt = (r->e->policy & engine_policy_fixdt) == engine_policy_fixdt; @@ -756,7 +757,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { if (is_fixdt || gp->ti_end <= ti_current) { /* First, finish the force calculation */ - gravity_end_force(gp); + gravity_end_force(gp, const_G); if (gp->id == -ICHECK) message("id=%lld a=[%f %f %f] M=%f\n", gp->id, gp->a_grav[0], @@ -853,7 +854,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { /* And do the same of the extra variable */ hydro_end_force(p); - if (p->gpart != NULL) gravity_end_force(p->gpart); + if (p->gpart != NULL) gravity_end_force(p->gpart, const_G); /* Now we are ready to compute the next time-step size */ int new_dti; diff --git a/src/tools.c b/src/tools.c index f298b3494..a178a2d7d 100644 --- a/src/tools.c +++ b/src/tools.c @@ -490,7 +490,7 @@ void shuffle_particles(struct part *parts, const int count) { * @brief gparts The array of particles. * @brief gcount The number of particles. */ -void gravity_n2(struct gpart *gparts, const int gcount) { +void gravity_n2(struct gpart *gparts, const int gcount, const struct phys_const *constants) { /* Reset everything */ for (int pid = 0; pid < gcount; pid++) { @@ -533,4 +533,13 @@ void gravity_n2(struct gpart *gparts, const int gcount) { gpj->a_grav[2] += wdx[2] * mi; } } + + /* Multiply by Newton's constant */ + const double const_G = constants->const_newton_G; + for (int pid = 0; pid < gcount; pid++) { + struct gpart *restrict gpi = &gparts[pid]; + gpi->a_grav[0] *= const_G; + gpi->a_grav[1] *= const_G; + gpi->a_grav[2] *= const_G; + } } diff --git a/src/tools.h b/src/tools.h index 90bc4da01..4f587b2ab 100644 --- a/src/tools.h +++ b/src/tools.h @@ -22,8 +22,9 @@ #ifndef SWIFT_TOOL_H #define SWIFT_TOOL_H -#include "runner.h" #include "cell.h" +#include "physical_constants.h" +#include "runner.h" void factor(int value, int *f1, int *f2); void density_dump(int N); @@ -40,6 +41,7 @@ void pairs_n2(double *dim, struct part *__restrict__ parts, int N, double random_uniform(double a, double b); void shuffle_particles(struct part *parts, const int count); -void gravity_n2(struct gpart *gparts, const int gcount); +void gravity_n2(struct gpart *gparts, const int gcount, + const struct phys_const *constants); #endif /* SWIFT_TOOL_H */ -- GitLab From f4d59002363d7f9633296718f79de8bc9aff0a8b Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Fri, 3 Jun 2016 16:07:24 +0100 Subject: [PATCH 27/72] External potential does now compute accelerations / G. --- src/potentials.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/potentials.h b/src/potentials.h index 50a890309..bbf1ae0dd 100644 --- a/src/potentials.h +++ b/src/potentials.h @@ -89,6 +89,8 @@ __attribute__((always_inline)) * @brief Computes the gravitational acceleration of a particle due to a point * mass * + * Note that the accelerations are multiplied by Newton's G constant later on. + * * @param potential The proerties of the external potential. * @param phys_const The physical constants in internal units. * @param g Pointer to the g-particle data. @@ -97,18 +99,15 @@ __attribute__((always_inline)) INLINE static void external_gravity_pointmass( const struct external_potential* potential, const struct phys_const* const phys_const, struct gpart* g) { - const float G_newton = phys_const->const_newton_G; const float dx = g->x[0] - potential->point_mass.x; const float dy = g->x[1] - potential->point_mass.y; const float dz = g->x[2] - potential->point_mass.z; const float rinv = 1.f / sqrtf(dx * dx + dy * dy + dz * dz); + const float rinv3 = rinv * rinv * rinv; - g->a_grav[0] += - -G_newton * potential->point_mass.mass * dx * rinv * rinv * rinv; - g->a_grav[1] += - -G_newton * potential->point_mass.mass * dy * rinv * rinv * rinv; - g->a_grav[2] += - -G_newton * potential->point_mass.mass * dz * rinv * rinv * rinv; + g->a_grav[0] += -potential->point_mass.mass * dx * rinv3; + g->a_grav[1] += -potential->point_mass.mass * dy * rinv3; + g->a_grav[2] += -potential->point_mass.mass * dz * rinv3; } #endif /* EXTERNAL_POTENTIAL_POINTMASS */ -- GitLab From a9b488bff6d2f61b06acb1e3a286d07bfd99a0fb Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Fri, 3 Jun 2016 16:14:45 +0100 Subject: [PATCH 28/72] Cleaned-up the const.h file --- src/const.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/const.h b/src/const.h index c004e4e2e..f7cf61133 100644 --- a/src/const.h +++ b/src/const.h @@ -39,10 +39,6 @@ /* Time integration constants. */ #define const_max_u_change 0.1f -/* Gravity stuff. */ -#define multipole_order 2 -#define const_gravity_eta 0.025f - /* Kernel function to use */ #define CUBIC_SPLINE_KERNEL //#define QUARTIC_SPLINE_KERNEL @@ -56,7 +52,11 @@ #define GADGET2_SPH //#define DEFAULT_SPH -/* Gravity properties */ +/* Self gravity stuff. */ +#define multipole_order 2 +#define const_gravity_eta 0.025f + +/* External gravity properties */ #define EXTERNAL_POTENTIAL_POINTMASS //#define SANITY_CHECKS -- GitLab From 417728d0868a12e642270abb4292100af4adacd8 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sat, 4 Jun 2016 16:31:35 +0200 Subject: [PATCH 29/72] Initial work on the gravity kernel functions --- src/kernel_gravity.h | 59 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/src/kernel_gravity.h b/src/kernel_gravity.h index e976c6108..eef898575 100644 --- a/src/kernel_gravity.h +++ b/src/kernel_gravity.h @@ -25,13 +25,13 @@ #include "inline.h" #include "vector.h" -#define const_epsilon 1. -#define const_iepsilon (1. / const_epsilon) -#define const_iepsilon2 (const_iepsilon *const_iepsilon) -#define const_iepsilon3 (const_iepsilon2 *const_iepsilon) -#define const_iepsilon4 (const_iepsilon2 *const_iepsilon2) -#define const_iepsilon5 (const_iepsilon3 *const_iepsilon2) -#define const_iepsilon6 (const_iepsilon3 *const_iepsilon3) +/* #define const_epsilon 1. */ +/* #define const_iepsilon (1. / const_epsilon) */ +/* #define const_iepsilon2 (const_iepsilon *const_iepsilon) */ +/* #define const_iepsilon3 (const_iepsilon2 *const_iepsilon) */ +/* #define const_iepsilon4 (const_iepsilon2 *const_iepsilon2) */ +/* #define const_iepsilon5 (const_iepsilon3 *const_iepsilon2) */ +/* #define const_iepsilon6 (const_iepsilon3 *const_iepsilon3) */ /* The gravity kernel is defined as a degree 6 polynomial in the distance r. The resulting value should be post-multiplied with r^-3, resulting @@ -39,6 +39,50 @@ sufficient to model both the direct potential as well as the splines near the origin. */ + +/* Coefficients for the kernel. */ +#define kernel_grav_name "Gadget-2 softening kernel" +#define kernel_grav_degree 6 /* Degree of the polynomial */ +#define kernel_grav_ivals 2 /* Number of branches */ +static const float kernel_grav_coeffs[(kernel_grav_degree + 1) * (kernel_grav_ivals + 1)] + __attribute__((aligned(16))) = { + 32.f, -38.4f, 0.f, 10.66666667f, 0.f, 0.f, 0.f,/* 0 < u < 0.5 */ + -10.66666667f, 38.4f, -48.f, 21.3333333, 0.f, 0.f, 0.66666667f, /* 0.5 < u < 1 */ + 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; /* 1 < u */ + + +/** + * @brief Computes the kernel function. + * + * @param u The ratio of the distance to the smoothing length $u = x/h$. + * @param W (return) The value of the kernel function $W(x,h)$. + */ +__attribute__((always_inline)) INLINE static void kernel_grav_eval(float u, + float *const W) { + /* Go to the range [0,1[ from [0,H[ */ + const float x = u * (float)kernel_grav_igamma; + + /* Pick the correct branch of the kernel */ + const int ind = (int)fminf(x * (float)kernel_grav_ivals, kernel_grav_ivals); + const float *const coeffs = &kernel_grav_coeffs[ind * (kernel_grav_degree + 1)]; + + /* First two terms of the polynomial ... */ + float w = coeffs[0] * x + coeffs[1]; + + /* ... and the rest of them */ + for (int k = 2; k <= kernel_grav_degree; k++) w = x * w + coeffs[k]; + + /* Return everything */ + *W = w * (float)kernel_grav_igamma3; +} + + + + + +#if 0 + + /* Coefficients for the gravity kernel. */ #define kernel_grav_degree 6 #define kernel_grav_ivals 2 @@ -206,6 +250,7 @@ __attribute__((always_inline)) } } +#endif #endif void gravity_kernel_dump(float r_max, int N); -- GitLab From f647b6fac5d1f0e5986f588f8eeb8b4c5097f402 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sat, 4 Jun 2016 16:35:51 +0200 Subject: [PATCH 30/72] Compiling but wrong softening --- src/kernel_gravity.c | 3 +++ src/kernel_gravity.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/kernel_gravity.c b/src/kernel_gravity.c index 4a5df7a87..7bab7cf55 100644 --- a/src/kernel_gravity.c +++ b/src/kernel_gravity.c @@ -23,6 +23,9 @@ #include "kernel_gravity.h" +#define const_epsilon 1. +#define const_iepsilon3 1. + /** * @brief The Gadget-2 gravity kernel function * diff --git a/src/kernel_gravity.h b/src/kernel_gravity.h index eef898575..f5600a3a7 100644 --- a/src/kernel_gravity.h +++ b/src/kernel_gravity.h @@ -51,6 +51,9 @@ static const float kernel_grav_coeffs[(kernel_grav_degree + 1) * (kernel_grav_iv 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; /* 1 < u */ +#define kernel_grav_igamma 1. +#define kernel_grav_igamma3 1. + /** * @brief Computes the kernel function. * -- GitLab From 09f3bcc2236deb3946f144bcfb58df88576ad793 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sat, 4 Jun 2016 17:05:21 +0200 Subject: [PATCH 31/72] Post-merge fixes --- src/engine.c | 3 ++- src/gravity/Default/gravity.h | 2 +- src/runner.c | 14 ++++++++++---- src/task.c | 13 ++++++------- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/engine.c b/src/engine.c index a0de03d44..3cbb38c79 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2256,7 +2256,8 @@ void engine_init_particles(struct engine *e) { void engine_step(struct engine *e) { double snapshot_drift_time = 0.; - + struct space *s = e->s; + TIMER_TIC2; struct clocks_time time1, time2; diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h index e5e40def1..1aff1f0ef 100644 --- a/src/gravity/Default/gravity.h +++ b/src/gravity/Default/gravity.h @@ -62,7 +62,7 @@ __attribute__((always_inline)) gp->a_grav[1] * gp->a_grav[1] + gp->a_grav[2] * gp->a_grav[2]; - const float ac = ac2 > 0. ? sqrtf(ac) : FLT_MIN; + const float ac = (ac2 > 0.f) ? sqrtf(ac2) : FLT_MIN; const float dt = sqrt(2.f * const_gravity_eta * gp->epsilon / ac); diff --git a/src/runner.c b/src/runner.c index e28c0e032..bb813e893 100644 --- a/src/runner.c +++ b/src/runner.c @@ -736,13 +736,12 @@ void runner_do_kick_fixdt(struct runner *r, struct cell *c, int timer) { const double global_dt = r->e->dt_max; const double timeBase = r->e->timeBase; - const double timeBase_inv = 1.0 / r->e->timeBase; const int count = c->count; const int gcount = c->gcount; struct part *const parts = c->parts; struct xpart *const xparts = c->xparts; struct gpart *const gparts = c->gparts; - const double const_G = constants->const_newton_G; + const double const_G = r->e->physical_constants->const_newton_G; int updated = 0, g_updated = 0; int ti_end_min = max_nr_timesteps, ti_end_max = 0; @@ -858,6 +857,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { struct part *const parts = c->parts; struct xpart *const xparts = c->xparts; struct gpart *const gparts = c->gparts; + const double const_G = r->e->physical_constants->const_newton_G; int updated = 0, g_updated = 0; int ti_end_min = max_nr_timesteps, ti_end_max = 0; @@ -883,7 +883,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { if (gp->ti_end <= ti_current) { /* First, finish the force calculation */ - gravity_end_force(gp); + gravity_end_force(gp, const_G); /* Compute the next timestep */ const int new_dti = get_gpart_timestep(gp, e); @@ -918,7 +918,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { /* And do the same of the extra variable */ hydro_end_force(p); - if (p->gpart != NULL) gravity_end_force(p->gpart); + if (p->gpart != NULL) gravity_end_force(p->gpart, const_G); /* Compute the next timestep (hydro condition) */ const int new_dti = get_part_timestep(p, xp, e); @@ -1058,6 +1058,8 @@ void *runner_main(void *data) { runner_doself1_density(r, ci); else if (t->subtype == task_subtype_force) runner_doself2_force(r, ci); + else if (t->subtype == task_subtype_grav) + runner_doself_grav(r, ci); else error("Unknown task subtype."); break; @@ -1066,6 +1068,8 @@ void *runner_main(void *data) { runner_dopair1_density(r, ci, cj); else if (t->subtype == task_subtype_force) runner_dopair2_force(r, ci, cj); + else if (t->subtype == task_subtype_grav) + runner_dopair_grav(r, ci, cj); else error("Unknown task subtype."); break; @@ -1079,6 +1083,8 @@ void *runner_main(void *data) { runner_dosub2_force(r, ci, cj, t->flags, 1); else if (t->subtype == task_subtype_grav) runner_dosub_grav(r, ci, cj, 1); + else if (t->subtype == task_subtype_grav) + runner_dosub_grav(r, ci, cj, 1); else error("Unknown task subtype."); break; diff --git a/src/task.c b/src/task.c index 31e33ebca..d10271230 100644 --- a/src/task.c +++ b/src/task.c @@ -49,9 +49,8 @@ const char *taskID_names[task_type_count] = { "none", "sort", "self", "pair", "sub", "init", "ghost", "drift", "kick", "kick_fixdt", - "send", "recv", "grav_pp", "grav_mm", "grav_up", - "grav_down", "grav_external", "part_sort", "gpart_sort", "split_cell", - "rewait"}; + "send", "recv", "grav_mm", "grav_up", "grav_external", + "part_sort", "gpart_sort", "split_cell", "rewait"}; const char *subtaskID_names[task_type_count] = {"none", "density", "force", "grav"}; @@ -125,9 +124,9 @@ void task_unlock(struct task *t) { cell_unlocktree(t->ci); if (t->cj != NULL) cell_unlocktree(t->cj); break; - case task_type_grav_pp: + //case task_type_grav_pp: case task_type_grav_mm: - case task_type_grav_down: + //case task_type_grav_down: cell_gunlocktree(t->ci); if (t->cj != NULL) cell_gunlocktree(t->cj); break; @@ -185,8 +184,8 @@ int task_lock(struct task *t) { } /* Gravity tasks? */ - else if (type == task_type_grav_mm || type == task_type_grav_pp || - type == task_type_grav_down) { + else if (type == task_type_grav_mm) { + //|| type == task_type_grav_pp || type == task_type_grav_down) { if (ci->ghold || (cj != NULL && cj->ghold)) return 0; if (cell_glocktree(ci) != 0) return 0; if (cj != NULL && cell_glocktree(cj) != 0) { -- GitLab From 716001d8680be8090865f4e98332c756489de5a0 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sat, 4 Jun 2016 21:23:18 +0200 Subject: [PATCH 32/72] New formatting style --- examples/main.c | 5 +- src/cell.c | 2 +- src/common_io.h | 5 +- src/cycle.h | 4 +- src/debug.c | 2 +- src/drift.h | 8 +- src/engine.c | 24 ++++-- src/engine.h | 8 +- src/gravity/Default/gravity.h | 28 +++---- src/gravity/Default/gravity_debug.h | 4 +- src/gravity/Default/gravity_part.h | 2 +- src/hydro.h | 11 ++- src/hydro/Default/hydro.h | 25 +++--- src/hydro/Default/hydro_debug.h | 4 +- src/hydro/Default/hydro_iact.h | 8 +- src/hydro/Gadget2/hydro.h | 25 +++--- src/hydro/Gadget2/hydro_debug.h | 4 +- src/hydro/Gadget2/hydro_io.h | 1 - src/hydro/Gizmo/hydro.h | 45 +++++----- src/hydro/Gizmo/hydro_debug.h | 4 +- src/hydro/Gizmo/hydro_iact.h | 24 ++---- src/hydro/Minimal/hydro.h | 24 +++--- src/hydro/Minimal/hydro_debug.h | 4 +- src/hydro/Minimal/hydro_iact.h | 8 +- src/hydro_properties.c | 2 +- src/intrinsics.h | 8 +- src/kernel_gravity.h | 25 +++--- src/kernel_hydro.h | 22 ++--- src/map.c | 2 +- src/map.h | 2 +- src/parser.c | 8 +- src/partition.c | 17 ++-- src/potentials.h | 11 ++- src/proxy.c | 14 ++-- src/riemann.h | 4 +- src/riemann/riemann_exact.h | 6 +- src/riemann/riemann_hllc.h | 10 ++- src/runner.c | 123 +++++++++++++++++----------- src/runner_doiact_grav.h | 10 +-- src/runner_doiact_grav_old.h | 4 +- src/scheduler.c | 21 +++-- src/single_io.c | 2 +- src/space.c | 2 +- src/task.c | 16 ++-- src/tools.c | 9 +- src/tools.h | 2 +- tests/test27cells.c | 2 +- tests/testKernel.c | 2 +- tests/testPair.c | 2 +- tests/testParser.c | 6 +- tests/testReading.c | 2 +- tests/testSingle.c | 12 +-- 52 files changed, 323 insertions(+), 302 deletions(-) diff --git a/examples/main.c b/examples/main.c index d7f0f2aa7..9f371d64d 100644 --- a/examples/main.c +++ b/examples/main.c @@ -27,10 +27,10 @@ /* Some standard headers. */ #include -#include #include #include #include +#include /* MPI headers. */ #ifdef WITH_MPI @@ -125,8 +125,7 @@ int main(int argc, char *argv[]) { /* Let's pin the main thread */ #if defined(HAVE_SETAFFINITY) && defined(HAVE_LIBNUMA) && defined(_GNU_SOURCE) - if (((ENGINE_POLICY) & engine_policy_setaffinity) == - engine_policy_setaffinity) + if (((ENGINE_POLICY)&engine_policy_setaffinity) == engine_policy_setaffinity) engine_pin(); #endif diff --git a/src/cell.c b/src/cell.c index b7b1e8fb9..f301e9dc5 100644 --- a/src/cell.c +++ b/src/cell.c @@ -50,8 +50,8 @@ #include "atomic.h" #include "error.h" #include "gravity.h" -#include "hydro_properties.h" #include "hydro.h" +#include "hydro_properties.h" #include "space.h" #include "timers.h" diff --git a/src/common_io.h b/src/common_io.h index 6dbb83e74..ed1c96801 100644 --- a/src/common_io.h +++ b/src/common_io.h @@ -52,10 +52,7 @@ enum DATA_TYPE { *start a run or optional. * */ -enum DATA_IMPORTANCE { - COMPULSORY = 1, - OPTIONAL = 0 -}; +enum DATA_IMPORTANCE { COMPULSORY = 1, OPTIONAL = 0 }; /** * @brief The different particle types present in a GADGET IC file diff --git a/src/cycle.h b/src/cycle.h index 1278c83e8..4925808f5 100644 --- a/src/cycle.h +++ b/src/cycle.h @@ -334,7 +334,7 @@ typedef unsigned __int64 ticks; extern "C" #endif ticks - __getReg(int whichReg); + __getReg(int whichReg); #pragma intrinsic(__getReg) static __inline ticks getticks(void) { @@ -481,9 +481,9 @@ INLINE_ELAPSED(inline) /* MIPS ZBus */ #if HAVE_MIPS_ZBUS_TIMER #if defined(__mips__) && !defined(HAVE_TICK_COUNTER) +#include #include #include -#include typedef uint64_t ticks; diff --git a/src/debug.c b/src/debug.c index a962e2a4c..a3647915d 100644 --- a/src/debug.c +++ b/src/debug.c @@ -24,8 +24,8 @@ #include "config.h" #include "const.h" -#include "part.h" #include "debug.h" +#include "part.h" /* Import the right hydro definition */ #if defined(MINIMAL_SPH) diff --git a/src/drift.h b/src/drift.h index 48edab9f9..031214aa5 100644 --- a/src/drift.h +++ b/src/drift.h @@ -25,6 +25,8 @@ /* Local headers. */ #include "const.h" #include "debug.h" +#include "hydro.h" +#include "part.h" /** * @brief Perform the 'drift' operation on a #gpart @@ -58,9 +60,9 @@ __attribute__((always_inline)) INLINE static void drift_gpart( * @param ti_old Integer start of time-step * @param ti_current Integer end of time-step */ -__attribute__((always_inline)) - INLINE static void drift_part(struct part* p, struct xpart* xp, float dt, - double timeBase, int ti_old, int ti_current) { +__attribute__((always_inline)) INLINE static void drift_part( + struct part* p, struct xpart* xp, float dt, double timeBase, int ti_old, + int ti_current) { /* Useful quantity */ const float h_inv = 1.0f / p->h; diff --git a/src/engine.c b/src/engine.c index 3cbb38c79..df8aeabd2 100644 --- a/src/engine.c +++ b/src/engine.c @@ -29,11 +29,11 @@ #include #include #include +#include #include #include #include #include -#include /* MPI headers. */ #ifdef WITH_MPI @@ -56,19 +56,27 @@ #include "error.h" #include "hydro.h" #include "minmax.h" +#include "parallel_io.h" #include "part.h" #include "partition.h" -#include "parallel_io.h" #include "serial_io.h" #include "single_io.h" #include "timers.h" #include "tools.h" -const char *engine_policy_names[13] = { - "none", "rand", "steal", "keep", - "block", "fix_dt", "cpu_tight", "mpi", - "numa_affinity", "hydro", "self_gravity", "external_gravity", - "cosmology_integration"}; +const char *engine_policy_names[13] = {"none", + "rand", + "steal", + "keep", + "block", + "fix_dt", + "cpu_tight", + "mpi", + "numa_affinity", + "hydro", + "self_gravity", + "external_gravity", + "cosmology_integration"}; /** The rank of the engine as a global variable (for messages). */ int engine_rank; @@ -2257,7 +2265,7 @@ void engine_step(struct engine *e) { double snapshot_drift_time = 0.; struct space *s = e->s; - + TIMER_TIC2; struct clocks_time time1, time2; diff --git a/src/engine.h b/src/engine.h index 06343d76c..6c17de54b 100644 --- a/src/engine.h +++ b/src/engine.h @@ -39,15 +39,15 @@ /* Includes. */ #include "hydro_properties.h" #include "lock.h" +#include "parser.h" +#include "partition.h" +#include "physical_constants.h" +#include "potentials.h" #include "proxy.h" #include "runner.h" #include "scheduler.h" #include "space.h" #include "task.h" -#include "parser.h" -#include "partition.h" -#include "physical_constants.h" -#include "potentials.h" #include "units.h" /* Some constants. */ diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h index 1aff1f0ef..f8365e54d 100644 --- a/src/gravity/Default/gravity.h +++ b/src/gravity/Default/gravity.h @@ -31,11 +31,10 @@ * @param phys_const The physical constants in internal units. * @param gp Pointer to the g-particle data. */ -__attribute__((always_inline)) - INLINE static float gravity_compute_timestep_external( - const struct external_potential* potential, - const struct phys_const* const phys_const, - const struct gpart* const gp) { +__attribute__((always_inline)) INLINE static float +gravity_compute_timestep_external(const struct external_potential* potential, + const struct phys_const* const phys_const, + const struct gpart* const gp) { float dt = FLT_MAX; @@ -53,10 +52,9 @@ __attribute__((always_inline)) * @param phys_const The physical constants in internal units. * @param gp Pointer to the g-particle data. */ -__attribute__((always_inline)) - INLINE static float gravity_compute_timestep_self( - const struct phys_const* const phys_const, - const struct gpart* const gp) { +__attribute__((always_inline)) INLINE static float +gravity_compute_timestep_self(const struct phys_const* const phys_const, + const struct gpart* const gp) { const float ac2 = gp->a_grav[0] * gp->a_grav[0] + gp->a_grav[1] * gp->a_grav[1] + @@ -77,8 +75,8 @@ __attribute__((always_inline)) * * @param gp The particle to act upon */ -__attribute__((always_inline)) - INLINE static void gravity_first_init_gpart(struct gpart* gp) {} +__attribute__((always_inline)) INLINE static void gravity_first_init_gpart( + struct gpart* gp) {} /** * @brief Prepares a g-particle for the gravity calculation @@ -88,8 +86,8 @@ __attribute__((always_inline)) * * @param gp The particle to act upon */ -__attribute__((always_inline)) - INLINE static void gravity_init_part(struct gpart* gp) { +__attribute__((always_inline)) INLINE static void gravity_init_part( + struct gpart* gp) { /* Zero the acceleration */ gp->a_grav[0] = 0.f; @@ -107,8 +105,8 @@ __attribute__((always_inline)) * @param gp The particle to act upon * @param const_G Newton's constant */ -__attribute__((always_inline)) -INLINE static void gravity_end_force(struct gpart* gp, double const_G) { +__attribute__((always_inline)) INLINE static void gravity_end_force( + struct gpart* gp, double const_G) { /* Let's get physical... */ gp->a_grav[0] *= const_G; diff --git a/src/gravity/Default/gravity_debug.h b/src/gravity/Default/gravity_debug.h index 72ae5fd55..21d775d70 100644 --- a/src/gravity/Default/gravity_debug.h +++ b/src/gravity/Default/gravity_debug.h @@ -17,8 +17,8 @@ * ******************************************************************************/ -__attribute__((always_inline)) - INLINE static void gravity_debug_particle(struct gpart* p) { +__attribute__((always_inline)) INLINE static void gravity_debug_particle( + struct gpart* p) { printf( "x=[%.3e,%.3e,%.3e], " "v_full=[%.3e,%.3e,%.3e] \n a=[%.3e,%.3e,%.3e],\n " diff --git a/src/gravity/Default/gravity_part.h b/src/gravity/Default/gravity_part.h index 6eadcd503..afa207f9e 100644 --- a/src/gravity/Default/gravity_part.h +++ b/src/gravity/Default/gravity_part.h @@ -39,7 +39,7 @@ struct gpart { /* Softening length */ float epsilon; - + /* Particle time of beginning of time-step. */ int ti_begin; diff --git a/src/hydro.h b/src/hydro.h index aacbb6ac1..cf12a512a 100644 --- a/src/hydro.h +++ b/src/hydro.h @@ -19,20 +19,23 @@ #ifndef SWIFT_HYDRO_H #define SWIFT_HYDRO_H -#include "./const.h" +#include "const.h" +#include "hydro_properties.h" +#include "kernel_hydro.h" +#include "part.h" /* Import the right functions */ #if defined(MINIMAL_SPH) -#include "./hydro/Minimal/hydro_iact.h" #include "./hydro/Minimal/hydro.h" +#include "./hydro/Minimal/hydro_iact.h" #define SPH_IMPLEMENTATION "Minimal version of SPH (e.g. Price 2010)" #elif defined(GADGET2_SPH) -#include "./hydro/Gadget2/hydro_iact.h" #include "./hydro/Gadget2/hydro.h" +#include "./hydro/Gadget2/hydro_iact.h" #define SPH_IMPLEMENTATION "Gadget-2 version of SPH (Springel 2005)" #elif defined(DEFAULT_SPH) -#include "./hydro/Default/hydro_iact.h" #include "./hydro/Default/hydro.h" +#include "./hydro/Default/hydro_iact.h" #define SPH_IMPLEMENTATION "Default version of SPH" #else #error "Invalid choice of SPH variant" diff --git a/src/hydro/Default/hydro.h b/src/hydro/Default/hydro.h index e7e5e0f5c..4a6b19003 100644 --- a/src/hydro/Default/hydro.h +++ b/src/hydro/Default/hydro.h @@ -53,9 +53,8 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( * @param p The particle to act upon * @param xp The extended particle data to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_first_init_part(struct part* p, struct xpart* xp) { -} +__attribute__((always_inline)) INLINE static void hydro_first_init_part( + struct part* p, struct xpart* xp) {} /** * @brief Prepares a particle for the density calculation. @@ -65,8 +64,8 @@ __attribute__((always_inline)) * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_init_part(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_init_part( + struct part* p) { p->density.wcount = 0.f; p->density.wcount_dh = 0.f; p->rho = 0.f; @@ -86,8 +85,8 @@ __attribute__((always_inline)) * @param p The particle to act upon * @param time The current time */ -__attribute__((always_inline)) - INLINE static void hydro_end_density(struct part* p, float time) { +__attribute__((always_inline)) INLINE static void hydro_end_density( + struct part* p, float time) { /* Some smoothing length multiples. */ const float h = p->h; @@ -171,8 +170,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_reset_acceleration(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_reset_acceleration( + struct part* p) { /* Reset the acceleration. */ p->a_hydro[0] = 0.0f; @@ -218,8 +217,8 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_end_force(struct part* p) {} +__attribute__((always_inline)) INLINE static void hydro_end_force( + struct part* p) {} /** * @brief Kick the additional variables @@ -239,8 +238,8 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_convert_quantities(struct part* p) {} +__attribute__((always_inline)) INLINE static void hydro_convert_quantities( + struct part* p) {} /** * @brief Returns the internal energy of a particle diff --git a/src/hydro/Default/hydro_debug.h b/src/hydro/Default/hydro_debug.h index 2e7c3d683..79ee392d4 100644 --- a/src/hydro/Default/hydro_debug.h +++ b/src/hydro/Default/hydro_debug.h @@ -17,8 +17,8 @@ * ******************************************************************************/ -__attribute__((always_inline)) - INLINE static void hydro_debug_particle(struct part* p, struct xpart* xp) { +__attribute__((always_inline)) INLINE static void hydro_debug_particle( + struct part* p, struct xpart* xp) { printf( "x=[%.3e,%.3e,%.3e], " "v=[%.3e,%.3e,%.3e],v_full=[%.3e,%.3e,%.3e] \n a=[%.3e,%.3e,%.3e],\n " diff --git a/src/hydro/Default/hydro_iact.h b/src/hydro/Default/hydro_iact.h index 4f85299b9..4d651b61b 100644 --- a/src/hydro/Default/hydro_iact.h +++ b/src/hydro/Default/hydro_iact.h @@ -268,11 +268,9 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_density( * @brief Density loop (non-symmetric vectorized version) */ -__attribute__((always_inline)) - INLINE static void runner_iact_nonsym_vec_density(float *R2, float *Dx, - float *Hi, float *Hj, - struct part **pi, - struct part **pj) { +__attribute__((always_inline)) INLINE static void +runner_iact_nonsym_vec_density(float *R2, float *Dx, float *Hi, float *Hj, + struct part **pi, struct part **pj) { #ifdef VECTORIZE diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index 55652338a..0973acb0f 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -46,9 +46,8 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( * @param p The particle to act upon * @param xp The extended particle data to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_first_init_part(struct part* p, struct xpart* xp) { -} +__attribute__((always_inline)) INLINE static void hydro_first_init_part( + struct part* p, struct xpart* xp) {} /** * @brief Prepares a particle for the density calculation. @@ -58,8 +57,8 @@ __attribute__((always_inline)) * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_init_part(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_init_part( + struct part* p) { p->density.wcount = 0.f; p->density.wcount_dh = 0.f; p->rho = 0.f; @@ -79,8 +78,8 @@ __attribute__((always_inline)) * @param p The particle to act upon * @param ti_current The current time (on the integer timeline) */ -__attribute__((always_inline)) - INLINE static void hydro_end_density(struct part* p, int ti_current) { +__attribute__((always_inline)) INLINE static void hydro_end_density( + struct part* p, int ti_current) { /* Some smoothing length multiples. */ const float h = p->h; @@ -148,8 +147,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_reset_acceleration(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_reset_acceleration( + struct part* p) { /* Reset the acceleration. */ p->a_hydro[0] = 0.0f; @@ -193,8 +192,8 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_end_force(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_end_force( + struct part* p) { p->entropy_dt *= (const_hydro_gamma - 1.f) * powf(p->rho, -(const_hydro_gamma - 1.f)); @@ -230,8 +229,8 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_convert_quantities(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_convert_quantities( + struct part* p) { p->entropy = (const_hydro_gamma - 1.f) * p->entropy * powf(p->rho, -(const_hydro_gamma - 1.f)); diff --git a/src/hydro/Gadget2/hydro_debug.h b/src/hydro/Gadget2/hydro_debug.h index 4f00d8e02..31e89d438 100644 --- a/src/hydro/Gadget2/hydro_debug.h +++ b/src/hydro/Gadget2/hydro_debug.h @@ -17,8 +17,8 @@ * ******************************************************************************/ -__attribute__((always_inline)) - INLINE static void hydro_debug_particle(struct part* p, struct xpart* xp) { +__attribute__((always_inline)) INLINE static void hydro_debug_particle( + struct part* p, struct xpart* xp) { printf( "x=[%.3e,%.3e,%.3e], " "v=[%.3e,%.3e,%.3e],v_full=[%.3e,%.3e,%.3e] \n a=[%.3e,%.3e,%.3e],\n " diff --git a/src/hydro/Gadget2/hydro_io.h b/src/hydro/Gadget2/hydro_io.h index d15ef65cf..b977f2538 100644 --- a/src/hydro/Gadget2/hydro_io.h +++ b/src/hydro/Gadget2/hydro_io.h @@ -112,5 +112,4 @@ void writeSPHflavour(hid_t h_grpsph) { "Legacy Gadget-2 as in Springel (2005)"); writeAttribute_f(h_grpsph, "Viscosity alpha", const_viscosity_alpha); writeAttribute_f(h_grpsph, "Viscosity beta", 3.f); - } diff --git a/src/hydro/Gizmo/hydro.h b/src/hydro/Gizmo/hydro.h index f3553a009..f69dc3f17 100644 --- a/src/hydro/Gizmo/hydro.h +++ b/src/hydro/Gizmo/hydro.h @@ -39,17 +39,16 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( * @param p The particle to act upon * @param xp The extended particle data to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_first_init_part(struct part* p, struct xpart* xp) { -} +__attribute__((always_inline)) INLINE static void hydro_first_init_part( + struct part* p, struct xpart* xp) {} /** * @brief Prepares a particle for the volume calculation. * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_init_part(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_init_part( + struct part* p) { #ifdef SPH_GRADIENTS /* use the old volumes to estimate new primitive variables to be used for the @@ -127,8 +126,8 @@ __attribute__((always_inline)) * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_end_volume(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_end_volume( + struct part* p) { /* Some smoothing length multiples. */ const float h = p->h; @@ -387,8 +386,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_gradient( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_end_gradient(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_end_gradient( + struct part* p) { #ifndef SPH_GRADIENTS float h, ih, ih2, ih3; @@ -531,8 +530,8 @@ __attribute__((always_inline)) * @param p The particle to act upon * @param xp The extended particle data to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_prepare_fluxes(struct part* p, struct xpart* xp) { +__attribute__((always_inline)) INLINE static void hydro_prepare_fluxes( + struct part* p, struct xpart* xp) { /* initialize variables used for timestep calculation */ p->timestepvars.vmax = 0.0f; @@ -546,8 +545,8 @@ __attribute__((always_inline)) * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_reset_acceleration(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_reset_acceleration( + struct part* p) { /* figure out what to put here */ } @@ -559,8 +558,8 @@ __attribute__((always_inline)) * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_end_fluxes(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_end_fluxes( + struct part* p) { /* do nothing */ } @@ -572,8 +571,8 @@ __attribute__((always_inline)) * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_convert_quantities(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_convert_quantities( + struct part* p) { float volume; GFLOAT m; @@ -605,17 +604,17 @@ __attribute__((always_inline)) } // MATTHIEU -__attribute__((always_inline)) - INLINE static void hydro_end_density(struct part* p, float time) {} +__attribute__((always_inline)) INLINE static void hydro_end_density( + struct part* p, float time) {} __attribute__((always_inline)) INLINE static void hydro_prepare_force( struct part* p, struct xpart* xp, int ti_current, double timeBase) {} __attribute__((always_inline)) INLINE static void hydro_predict_extra( struct part* p, struct xpart* xp, int t0, int t1, double timeBase) {} -__attribute__((always_inline)) - INLINE static void hydro_end_force(struct part* p) {} +__attribute__((always_inline)) INLINE static void hydro_end_force( + struct part* p) {} __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part* p, struct xpart* xp, float dt, float half_dt) {} -__attribute__((always_inline)) - INLINE static float hydro_get_internal_energy(struct part* p) { +__attribute__((always_inline)) INLINE static float hydro_get_internal_energy( + struct part* p) { return 0.f; } diff --git a/src/hydro/Gizmo/hydro_debug.h b/src/hydro/Gizmo/hydro_debug.h index 2cc957ed8..365d85a2f 100644 --- a/src/hydro/Gizmo/hydro_debug.h +++ b/src/hydro/Gizmo/hydro_debug.h @@ -17,8 +17,8 @@ * ******************************************************************************/ -__attribute__((always_inline)) - INLINE static void hydro_debug_particle(struct part* p, struct xpart* xp) { +__attribute__((always_inline)) INLINE static void hydro_debug_particle( + struct part* p, struct xpart* xp) { printf( "x=[%.16e,%.16e,%.16e], " "v=[%.3e,%.3e,%.3e], a=[%.3e,%.3e,%.3e], volume=%.3e\n", diff --git a/src/hydro/Gizmo/hydro_iact.h b/src/hydro/Gizmo/hydro_iact.h index 4fe875d3d..30a8d6cbe 100644 --- a/src/hydro/Gizmo/hydro_iact.h +++ b/src/hydro/Gizmo/hydro_iact.h @@ -194,11 +194,9 @@ __attribute__((always_inline)) INLINE static void runner_iact_hydro_loop1( } /* this corresponds to task_subtype_hydro_loop1 */ -__attribute__((always_inline)) - INLINE static void runner_iact_nonsym_hydro_loop1(float r2, float *dx, - float hi, float hj, - struct part *pi, - struct part *pj) { +__attribute__((always_inline)) INLINE static void +runner_iact_nonsym_hydro_loop1(float r2, float *dx, float hi, float hj, + struct part *pi, struct part *pj) { float r; float xi; @@ -487,11 +485,9 @@ __attribute__((always_inline)) INLINE static void runner_iact_hydro_loop2( #endif } -__attribute__((always_inline)) - INLINE static void runner_iact_nonsym_hydro_loop2(float r2, float *dx, - float hi, float hj, - struct part *pi, - struct part *pj) { +__attribute__((always_inline)) INLINE static void +runner_iact_nonsym_hydro_loop2(float r2, float *dx, float hi, float hj, + struct part *pi, struct part *pj) { #ifndef SPH_GRADIENTS @@ -1025,11 +1021,9 @@ __attribute__((always_inline)) INLINE static void runner_iact_hydro_loop3( } /* this corresponds to task_subtype_fluxes */ -__attribute__((always_inline)) - INLINE static void runner_iact_nonsym_hydro_loop3(float r2, float *dx, - float hi, float hj, - struct part *pi, - struct part *pj) { +__attribute__((always_inline)) INLINE static void +runner_iact_nonsym_hydro_loop3(float r2, float *dx, float hi, float hj, + struct part *pi, struct part *pj) { runner_iact_fluxes_common(r2, dx, hi, hj, pi, pj, 0); } diff --git a/src/hydro/Minimal/hydro.h b/src/hydro/Minimal/hydro.h index c86b4c0ab..4222daafe 100644 --- a/src/hydro/Minimal/hydro.h +++ b/src/hydro/Minimal/hydro.h @@ -53,8 +53,8 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( * @param p The particle to act upon * @param xp The extended particle data to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_first_init_part(struct part* p, struct xpart* xp) { +__attribute__((always_inline)) INLINE static void hydro_first_init_part( + struct part* p, struct xpart* xp) { xp->u_full = p->u; } @@ -68,8 +68,8 @@ __attribute__((always_inline)) * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_init_part(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_init_part( + struct part* p) { p->density.wcount = 0.f; p->density.wcount_dh = 0.f; p->rho = 0.f; @@ -88,8 +88,8 @@ __attribute__((always_inline)) * @param p The particle to act upon * @param time The current time */ -__attribute__((always_inline)) - INLINE static void hydro_end_density(struct part* p, float time) { +__attribute__((always_inline)) INLINE static void hydro_end_density( + struct part* p, float time) { /* Some smoothing length multiples. */ const float h = p->h; @@ -143,8 +143,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_reset_acceleration(struct part* p) { +__attribute__((always_inline)) INLINE static void hydro_reset_acceleration( + struct part* p) { /* Reset the acceleration. */ p->a_hydro[0] = 0.0f; @@ -187,8 +187,8 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_end_force(struct part* p) {} +__attribute__((always_inline)) INLINE static void hydro_end_force( + struct part* p) {} /** * @brief Kick the additional variables @@ -221,8 +221,8 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( * * @param p The particle to act upon */ -__attribute__((always_inline)) - INLINE static void hydro_convert_quantities(struct part* p) {} +__attribute__((always_inline)) INLINE static void hydro_convert_quantities( + struct part* p) {} /** * @brief Returns the internal energy of a particle diff --git a/src/hydro/Minimal/hydro_debug.h b/src/hydro/Minimal/hydro_debug.h index 85fdbac0a..127ba75e9 100644 --- a/src/hydro/Minimal/hydro_debug.h +++ b/src/hydro/Minimal/hydro_debug.h @@ -17,8 +17,8 @@ * ******************************************************************************/ -__attribute__((always_inline)) - INLINE static void hydro_debug_particle(struct part* p, struct xpart* xp) { +__attribute__((always_inline)) INLINE static void hydro_debug_particle( + struct part* p, struct xpart* xp) { printf( "x=[%.3e,%.3e,%.3e], " "v=[%.3e,%.3e,%.3e],v_full=[%.3e,%.3e,%.3e] \n a=[%.3e,%.3e,%.3e], " diff --git a/src/hydro/Minimal/hydro_iact.h b/src/hydro/Minimal/hydro_iact.h index b05691c2d..f453d8fa1 100644 --- a/src/hydro/Minimal/hydro_iact.h +++ b/src/hydro/Minimal/hydro_iact.h @@ -131,10 +131,9 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( const float P_over_rho_j = pressurej / (rhoj * rhoj) * pj->rho_dh; /* Compute dv dot r. */ - const float dvdr = (pi->v[0] - pj->v[0]) * dx[0] - + (pi->v[1] - pj->v[1]) * dx[1] - + (pi->v[2] - pj->v[2]) * dx[2]; - + const float dvdr = (pi->v[0] - pj->v[0]) * dx[0] + + (pi->v[1] - pj->v[1]) * dx[1] + + (pi->v[2] - pj->v[2]) * dx[2]; /* Compute sound speeds */ const float ci = sqrtf(const_hydro_gamma * pressurei / rhoi); @@ -209,7 +208,6 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( (pi->v[1] - pj->v[1]) * dx[1] + (pi->v[2] - pj->v[2]) * dx[2]; - /* Compute sound speeds */ const float ci = sqrtf(const_hydro_gamma * pressurei / rhoi); const float cj = sqrtf(const_hydro_gamma * pressurej / rhoj); diff --git a/src/hydro_properties.c b/src/hydro_properties.c index b96eb1cc7..b4e37d672 100644 --- a/src/hydro_properties.c +++ b/src/hydro_properties.c @@ -26,8 +26,8 @@ /* Local headers. */ #include "error.h" -#include "kernel_hydro.h" #include "hydro.h" +#include "kernel_hydro.h" void hydro_props_init(struct hydro_props *p, const struct swift_params *params) { diff --git a/src/intrinsics.h b/src/intrinsics.h index 21b8c8e68..27e0bcc72 100644 --- a/src/intrinsics.h +++ b/src/intrinsics.h @@ -26,8 +26,8 @@ * This is a wrapper for the GCC intrinsics with an implementation (from * Hacker's Delight) if the compiler intrinsics are not available. */ -__attribute__((always_inline)) - INLINE static int intrinsics_clz(unsigned int x) { +__attribute__((always_inline)) INLINE static int intrinsics_clz( + unsigned int x) { #ifdef __GNUC__ /* Use GCC intrinsics if possible */ @@ -66,8 +66,8 @@ __attribute__((always_inline)) * This is a wrapper for the GCC intrinsics with an implementation (from * Hacker's Delight) if the compiler intrinsics are not available. */ -__attribute__((always_inline)) - INLINE static int intrinsics_popcount(unsigned int x) { +__attribute__((always_inline)) INLINE static int intrinsics_popcount( + unsigned int x) { #ifdef __GNUC__ /* Use GCC intrinsics if possible */ diff --git a/src/kernel_gravity.h b/src/kernel_gravity.h index f5600a3a7..c642f800e 100644 --- a/src/kernel_gravity.h +++ b/src/kernel_gravity.h @@ -39,17 +39,19 @@ sufficient to model both the direct potential as well as the splines near the origin. */ - /* Coefficients for the kernel. */ #define kernel_grav_name "Gadget-2 softening kernel" #define kernel_grav_degree 6 /* Degree of the polynomial */ #define kernel_grav_ivals 2 /* Number of branches */ -static const float kernel_grav_coeffs[(kernel_grav_degree + 1) * (kernel_grav_ivals + 1)] +static const float + kernel_grav_coeffs[(kernel_grav_degree + 1) * (kernel_grav_ivals + 1)] __attribute__((aligned(16))) = { - 32.f, -38.4f, 0.f, 10.66666667f, 0.f, 0.f, 0.f,/* 0 < u < 0.5 */ - -10.66666667f, 38.4f, -48.f, 21.3333333, 0.f, 0.f, 0.66666667f, /* 0.5 < u < 1 */ - 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; /* 1 < u */ - + 32.f, -38.4f, 0.f, 10.66666667f, + 0.f, 0.f, 0.f, /* 0 < u < 0.5 */ + -10.66666667f, 38.4f, -48.f, 21.3333333, + 0.f, 0.f, 0.66666667f, /* 0.5 < u < 1 */ + 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f}; /* 1 < u */ #define kernel_grav_igamma 1. #define kernel_grav_igamma3 1. @@ -60,14 +62,15 @@ static const float kernel_grav_coeffs[(kernel_grav_degree + 1) * (kernel_grav_iv * @param u The ratio of the distance to the smoothing length $u = x/h$. * @param W (return) The value of the kernel function $W(x,h)$. */ -__attribute__((always_inline)) INLINE static void kernel_grav_eval(float u, - float *const W) { +__attribute__((always_inline)) INLINE static void kernel_grav_eval( + float u, float *const W) { /* Go to the range [0,1[ from [0,H[ */ const float x = u * (float)kernel_grav_igamma; /* Pick the correct branch of the kernel */ const int ind = (int)fminf(x * (float)kernel_grav_ivals, kernel_grav_ivals); - const float *const coeffs = &kernel_grav_coeffs[ind * (kernel_grav_degree + 1)]; + const float *const coeffs = + &kernel_grav_coeffs[ind * (kernel_grav_degree + 1)]; /* First two terms of the polynomial ... */ float w = coeffs[0] * x + coeffs[1]; @@ -79,10 +82,6 @@ __attribute__((always_inline)) INLINE static void kernel_grav_eval(float u, *W = w * (float)kernel_grav_igamma3; } - - - - #if 0 diff --git a/src/kernel_hydro.h b/src/kernel_hydro.h index 06f950b0e..b1774d8f3 100644 --- a/src/kernel_hydro.h +++ b/src/kernel_hydro.h @@ -137,22 +137,22 @@ static const float kernel_coeffs[(kernel_degree + 1) * (kernel_ivals + 1)] /* Ok, now comes the real deal. */ /* First some powers of gamma = H/h */ -#define kernel_gamma2 ((float)(kernel_gamma *kernel_gamma)) -#define kernel_gamma3 ((float)(kernel_gamma *kernel_gamma *kernel_gamma)) +#define kernel_gamma2 ((float)(kernel_gamma * kernel_gamma)) +#define kernel_gamma3 ((float)(kernel_gamma * kernel_gamma * kernel_gamma)) #define kernel_gamma4 \ - ((float)(kernel_gamma *kernel_gamma *kernel_gamma *kernel_gamma)) + ((float)(kernel_gamma * kernel_gamma * kernel_gamma * kernel_gamma)) #define kernel_igamma ((float)(1. / kernel_gamma)) -#define kernel_igamma2 ((float)(kernel_igamma *kernel_igamma)) -#define kernel_igamma3 ((float)(kernel_igamma *kernel_igamma *kernel_igamma)) +#define kernel_igamma2 ((float)(kernel_igamma * kernel_igamma)) +#define kernel_igamma3 ((float)(kernel_igamma * kernel_igamma * kernel_igamma)) #define kernel_igamma4 \ - ((float)(kernel_igamma *kernel_igamma *kernel_igamma *kernel_igamma)) + ((float)(kernel_igamma * kernel_igamma * kernel_igamma * kernel_igamma)) /* The number of branches */ #define kernel_ivals_f ((float)(kernel_ivals)) /* Kernel self contribution (i.e. W(0,h)) */ #define kernel_root \ - ((float)(kernel_coeffs[kernel_degree]) * kernel_constant *kernel_igamma3) + ((float)(kernel_coeffs[kernel_degree]) * kernel_constant * kernel_igamma3) /** * @brief Computes the kernel function and its derivative. @@ -200,8 +200,8 @@ __attribute__((always_inline)) INLINE static void kernel_deval( * @param u The ratio of the distance to the smoothing length $u = x/h$. * @param W (return) The value of the kernel function $W(x,h)$. */ -__attribute__((always_inline)) - INLINE static void kernel_eval(float u, float *restrict W) { +__attribute__((always_inline)) INLINE static void kernel_eval( + float u, float *restrict W) { /* Go to the range [0,1[ from [0,H[ */ const float x = u * kernel_igamma; @@ -246,8 +246,8 @@ static const vector kernel_igamma4_vec = FILL_VEC((float)kernel_igamma4); * @param w (return) The value of the kernel function $W(x,h)$. * @param dw_dx (return) The norm of the gradient of $|\\nabla W(x,h)|$. */ -__attribute__((always_inline)) - INLINE static void kernel_deval_vec(vector *u, vector *w, vector *dw_dx) { +__attribute__((always_inline)) INLINE static void kernel_deval_vec( + vector *u, vector *w, vector *dw_dx) { /* Go to the range [0,1[ from [0,H[ */ vector x; diff --git a/src/map.c b/src/map.c index da13fbfb4..fbe57fde7 100644 --- a/src/map.c +++ b/src/map.c @@ -18,10 +18,10 @@ * ******************************************************************************/ +#include "map.h" #include #include #include "error.h" -#include "map.h" /** * @brief Mapping function to draw a specific cell (gnuplot). diff --git a/src/map.h b/src/map.h index 0753c2641..950a5fd96 100644 --- a/src/map.h +++ b/src/map.h @@ -22,8 +22,8 @@ #ifndef SWIFT_MAP_H #define SWIFT_MAP_H -#include "part.h" #include "cell.h" +#include "part.h" void map_cells_plot(struct cell *c, void *data); void map_check(struct part *p, struct cell *c, void *data); diff --git a/src/parser.c b/src/parser.c index 28acb4f75..74c277f03 100644 --- a/src/parser.c +++ b/src/parser.c @@ -22,16 +22,16 @@ /* Some standard headers. */ /* Needs to be included so that strtok returns char * instead of a int *. */ -#include -#include #include +#include +#include /* This object's header. */ #include "parser.h" /* Local headers. */ -#include "error.h" #include "common_io.h" +#include "error.h" #define PARSER_COMMENT_STRING "#" #define PARSER_COMMENT_CHAR '#' @@ -256,7 +256,7 @@ static void parse_value(char *line, struct swift_params *params) { /* Check that it is a parameter inside a section.*/ if (*line == ' ' || *line == '\t') { parse_section_param(line, &isFirstParam, section, params); - } else {/*Else it is the start of a new section or standalone parameter. */ + } else { /*Else it is the start of a new section or standalone parameter. */ /* Take first token as the parameter name. */ token = strtok(line, " :\t"); strcpy(tmpStr, token); diff --git a/src/partition.c b/src/partition.c index 70249a679..432943f05 100644 --- a/src/partition.c +++ b/src/partition.c @@ -31,11 +31,11 @@ #include "../config.h" /* Standard headers. */ +#include #include #include #include #include -#include /* MPI headers. */ #ifdef WITH_MPI @@ -59,13 +59,12 @@ /* Simple descriptions of initial partition types for reports. */ const char *initial_partition_name[] = { - "gridded cells", "vectorized point associated cells", + "gridded cells", "vectorized point associated cells", "METIS particle weighted cells", "METIS unweighted cells"}; /* Simple descriptions of repartition types for reports. */ const char *repartition_name[] = { - "no", - "METIS edge and vertex time weighted cells", + "no", "METIS edge and vertex time weighted cells", "METIS particle count vertex weighted cells", "METIS time edge weighted cells", "METIS particle count vertex and time edge cells"}; @@ -782,8 +781,9 @@ void partition_initial_partition(struct partition *initial_partition, struct cell *c; /* If we've got the wrong number of nodes, fail. */ - if (nr_nodes != initial_partition->grid[0] * initial_partition->grid[1] * - initial_partition->grid[2]) + if (nr_nodes != + initial_partition->grid[0] * initial_partition->grid[1] * + initial_partition->grid[2]) error("Grid size does not match number of nodes."); /* Run through the cells and set their nodeID. */ @@ -792,8 +792,9 @@ void partition_initial_partition(struct partition *initial_partition, c = &s->cells[k]; for (j = 0; j < 3; j++) ind[j] = c->loc[j] / s->dim[j] * initial_partition->grid[j]; - c->nodeID = ind[0] + initial_partition->grid[0] * - (ind[1] + initial_partition->grid[1] * ind[2]); + c->nodeID = ind[0] + + initial_partition->grid[0] * + (ind[1] + initial_partition->grid[1] * ind[2]); // message("cell at [%e,%e,%e]: ind = [%i,%i,%i], nodeID = %i", c->loc[0], // c->loc[1], c->loc[2], ind[0], ind[1], ind[2], c->nodeID); } diff --git a/src/potentials.h b/src/potentials.h index bbf1ae0dd..24e7da99d 100644 --- a/src/potentials.h +++ b/src/potentials.h @@ -30,8 +30,8 @@ /* Local includes. */ #include "const.h" #include "error.h" -#include "part.h" #include "parser.h" +#include "part.h" #include "physical_constants.h" #include "units.h" @@ -58,11 +58,10 @@ struct external_potential { * @param phys_const The physical constants in internal units. * @param g Pointer to the g-particle data. */ -__attribute__((always_inline)) - INLINE static float external_gravity_pointmass_timestep( - const struct external_potential* potential, - const struct phys_const* const phys_const, - const struct gpart* const g) { +__attribute__((always_inline)) INLINE static float +external_gravity_pointmass_timestep(const struct external_potential* potential, + const struct phys_const* const phys_const, + const struct gpart* const g) { const float G_newton = phys_const->const_newton_G; const float dx = g->x[0] - potential->point_mass.x; diff --git a/src/proxy.c b/src/proxy.c index 02263a565..efe3a3eec 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -249,8 +249,8 @@ void proxy_parts_exch2(struct proxy *p) { } while (p->nr_parts_in > p->size_parts_in); free(p->parts_in); free(p->xparts_in); - if ((p->parts_in = (struct part *)malloc( - sizeof(struct part) *p->size_parts_in)) == NULL || + if ((p->parts_in = (struct part *)malloc(sizeof(struct part) * + p->size_parts_in)) == NULL || (p->xparts_in = (struct xpart *)malloc(sizeof(struct xpart) * p->size_parts_in)) == NULL) error("Failed to re-allocate parts_in buffers."); @@ -310,7 +310,7 @@ void proxy_parts_load(struct proxy *p, const struct part *parts, } while (p->nr_parts_out + N > p->size_parts_out); struct part *tp; struct xpart *txp; - if ((tp = (struct part *)malloc(sizeof(struct part) *p->size_parts_out)) == + if ((tp = (struct part *)malloc(sizeof(struct part) * p->size_parts_out)) == NULL || (txp = (struct xpart *)malloc(sizeof(struct xpart) * p->size_parts_out)) == NULL) @@ -395,8 +395,8 @@ void proxy_init(struct proxy *p, int mynodeID, int nodeID) { /* Allocate the part send and receive buffers, if needed. */ if (p->parts_in == NULL) { p->size_parts_in = proxy_buffinit; - if ((p->parts_in = (struct part *)malloc( - sizeof(struct part) *p->size_parts_in)) == NULL || + if ((p->parts_in = (struct part *)malloc(sizeof(struct part) * + p->size_parts_in)) == NULL || (p->xparts_in = (struct xpart *)malloc(sizeof(struct xpart) * p->size_parts_in)) == NULL) error("Failed to allocate parts_in buffers."); @@ -404,8 +404,8 @@ void proxy_init(struct proxy *p, int mynodeID, int nodeID) { p->nr_parts_in = 0; if (p->parts_out == NULL) { p->size_parts_out = proxy_buffinit; - if ((p->parts_out = (struct part *)malloc( - sizeof(struct part) *p->size_parts_out)) == NULL || + if ((p->parts_out = (struct part *)malloc(sizeof(struct part) * + p->size_parts_out)) == NULL || (p->xparts_out = (struct xpart *)malloc(sizeof(struct xpart) * p->size_parts_out)) == NULL) error("Failed to allocate parts_out buffers."); diff --git a/src/riemann.h b/src/riemann.h index ad37490d7..d647b0211 100644 --- a/src/riemann.h +++ b/src/riemann.h @@ -21,11 +21,11 @@ /* gives us const_hydro_gamma and tells us which floating point type to use */ #include "const.h" +#include "error.h" +#include "float.h" #include "math.h" #include "stdio.h" -#include "float.h" #include "stdlib.h" -#include "error.h" #define HLLC_SOLVER diff --git a/src/riemann/riemann_exact.h b/src/riemann/riemann_exact.h index b768cde5f..a2f3c30fb 100644 --- a/src/riemann/riemann_exact.h +++ b/src/riemann/riemann_exact.h @@ -78,9 +78,9 @@ __attribute__((always_inline)) INLINE static GFLOAT riemann_fb(GFLOAT p, * @param aL The left sound speed * @param aR The right sound speed */ -__attribute__((always_inline)) - INLINE static GFLOAT riemann_f(GFLOAT p, GFLOAT* WL, GFLOAT* WR, GFLOAT vL, - GFLOAT vR, GFLOAT aL, GFLOAT aR) { +__attribute__((always_inline)) INLINE static GFLOAT riemann_f( + GFLOAT p, GFLOAT* WL, GFLOAT* WR, GFLOAT vL, GFLOAT vR, GFLOAT aL, + GFLOAT aR) { return riemann_fb(p, WL, aL) + riemann_fb(p, WR, aR) + (vR - vL); } diff --git a/src/riemann/riemann_hllc.h b/src/riemann/riemann_hllc.h index 3fcc8b534..6c583f641 100644 --- a/src/riemann/riemann_hllc.h +++ b/src/riemann/riemann_hllc.h @@ -63,13 +63,15 @@ __attribute__((always_inline)) INLINE static void riemann_solve_for_flux( all these speeds are along the interface normal, since uL and uR are */ qL = 1.; if (pstar > WL[4]) { - qL = sqrtf(1. + 0.5 * (const_hydro_gamma + 1.) / const_hydro_gamma * - (pstar / WL[4] - 1.)); + qL = sqrtf(1. + + 0.5 * (const_hydro_gamma + 1.) / const_hydro_gamma * + (pstar / WL[4] - 1.)); } qR = 1.; if (pstar > WR[4]) { - qR = sqrtf(1. + 0.5 * (const_hydro_gamma + 1.) / const_hydro_gamma * - (pstar / WR[4] - 1.)); + qR = sqrtf(1. + + 0.5 * (const_hydro_gamma + 1.) / const_hydro_gamma * + (pstar / WR[4] - 1.)); } SL = uL - aL * qL; SR = uR + aR * qR; diff --git a/src/runner.c b/src/runner.c index bb813e893..5bdf3a443 100644 --- a/src/runner.c +++ b/src/runner.c @@ -42,12 +42,12 @@ #include "atomic.h" #include "const.h" #include "debug.h" +#include "drift.h" #include "engine.h" #include "error.h" #include "gravity.h" -#include "hydro_properties.h" #include "hydro.h" -#include "drift.h" +#include "hydro_properties.h" #include "kick.h" #include "minmax.h" #include "scheduler.h" @@ -58,19 +58,46 @@ /* Orientation of the cell pairs */ const float runner_shift[13 * 3] = { - 5.773502691896258e-01, 5.773502691896258e-01, 5.773502691896258e-01, - 7.071067811865475e-01, 7.071067811865475e-01, 0.0, - 5.773502691896258e-01, 5.773502691896258e-01, -5.773502691896258e-01, - 7.071067811865475e-01, 0.0, 7.071067811865475e-01, - 1.0, 0.0, 0.0, - 7.071067811865475e-01, 0.0, -7.071067811865475e-01, - 5.773502691896258e-01, -5.773502691896258e-01, 5.773502691896258e-01, - 7.071067811865475e-01, -7.071067811865475e-01, 0.0, - 5.773502691896258e-01, -5.773502691896258e-01, -5.773502691896258e-01, - 0.0, 7.071067811865475e-01, 7.071067811865475e-01, - 0.0, 1.0, 0.0, - 0.0, 7.071067811865475e-01, -7.071067811865475e-01, - 0.0, 0.0, 1.0, }; + 5.773502691896258e-01, + 5.773502691896258e-01, + 5.773502691896258e-01, + 7.071067811865475e-01, + 7.071067811865475e-01, + 0.0, + 5.773502691896258e-01, + 5.773502691896258e-01, + -5.773502691896258e-01, + 7.071067811865475e-01, + 0.0, + 7.071067811865475e-01, + 1.0, + 0.0, + 0.0, + 7.071067811865475e-01, + 0.0, + -7.071067811865475e-01, + 5.773502691896258e-01, + -5.773502691896258e-01, + 5.773502691896258e-01, + 7.071067811865475e-01, + -7.071067811865475e-01, + 0.0, + 5.773502691896258e-01, + -5.773502691896258e-01, + -5.773502691896258e-01, + 0.0, + 7.071067811865475e-01, + 7.071067811865475e-01, + 0.0, + 1.0, + 0.0, + 0.0, + 7.071067811865475e-01, + -7.071067811865475e-01, + 0.0, + 0.0, + 1.0, +}; /* Does the axis need flipping ? */ const char runner_flip[27] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, @@ -97,8 +124,8 @@ const char runner_flip[27] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, */ void runner_do_grav_external(struct runner *r, struct cell *c, int timer) { - struct gpart *g, *gparts = c->gparts; - int i, k, gcount = c->gcount; + struct gpart *restrict gparts = c->gparts; + const int gcount = c->gcount; const int ti_current = r->e->ti_current; const struct external_potential *potential = r->e->external_potential; const struct phys_const *constants = r->e->physical_constants; @@ -107,7 +134,7 @@ void runner_do_grav_external(struct runner *r, struct cell *c, int timer) { /* Recurse? */ if (c->split) { - for (k = 0; k < 8; k++) + for (int k = 0; k < 8; k++) if (c->progeny[k] != NULL) runner_do_grav_external(r, c->progeny[k], 0); return; } @@ -117,10 +144,10 @@ void runner_do_grav_external(struct runner *r, struct cell *c, int timer) { #endif /* Loop over the gparts in this cell. */ - for (i = 0; i < gcount; i++) { + for (int i = 0; i < gcount; i++) { /* Get a direct pointer on the part. */ - g = &gparts[i]; + struct gpart *restrict g = &gparts[i]; /* Is this part within the time step? */ if (g->ti_end <= ti_current) { @@ -128,6 +155,7 @@ void runner_do_grav_external(struct runner *r, struct cell *c, int timer) { external_gravity(potential, constants, g); } } + if (timer) TIMER_TOC(timer_dograv_external); } @@ -374,8 +402,8 @@ void runner_do_sort(struct runner *r, struct cell *c, int flags, int clock) { */ void runner_do_init(struct runner *r, struct cell *c, int timer) { - struct part *const parts = c->parts; - struct gpart *const gparts = c->gparts; + struct part *restrict parts = c->parts; + struct gpart *restrict gparts = c->gparts; const int count = c->count; const int gcount = c->gcount; const int ti_current = r->e->ti_current; @@ -432,12 +460,9 @@ void runner_do_init(struct runner *r, struct cell *c, int timer) { void runner_do_ghost(struct runner *r, struct cell *c) { - struct part *p, *parts = c->parts; - struct xpart *xp, *xparts = c->xparts; - struct cell *finger; + struct part *restrict parts = c->parts; + struct xpart *restrict xparts = c->xparts; int redo, count = c->count; - int *pid; - float h_corr; const int ti_current = r->e->ti_current; const double timeBase = r->e->timeBase; const float target_wcount = r->e->hydro_properties->target_neighbours; @@ -458,6 +483,7 @@ void runner_do_ghost(struct runner *r, struct cell *c) { } /* Init the IDs that have to be updated. */ + int *pid; if ((pid = (int *)alloca(sizeof(int) * count)) == NULL) error("Call to alloca failed."); for (int k = 0; k < count; k++) pid[k] = k; @@ -473,8 +499,8 @@ void runner_do_ghost(struct runner *r, struct cell *c) { for (int i = 0; i < count; i++) { /* Get a direct pointer on the part. */ - p = &parts[pid[i]]; - xp = &xparts[pid[i]]; + struct part *const p = &parts[pid[i]]; + struct xpart *const xp = &xparts[pid[i]]; /* Is this part within the timestep? */ if (p->ti_end <= ti_current) { @@ -482,6 +508,8 @@ void runner_do_ghost(struct runner *r, struct cell *c) { /* Finish the density calculation */ hydro_end_density(p, ti_current); + float h_corr = 0.f; + /* If no derivative, double the smoothing length. */ if (p->density.wcount_dh == 0.0f) h_corr = p->h; @@ -534,7 +562,7 @@ void runner_do_ghost(struct runner *r, struct cell *c) { if (count > 0) { /* Climb up the cell hierarchy. */ - for (finger = c; finger != NULL; finger = finger->parent) { + for (struct cell *finger = c; finger != NULL; finger = finger->parent) { /* Run through this cell's density interactions. */ for (struct link *l = finger->density; l != NULL; l = l->next) { @@ -591,9 +619,9 @@ void runner_do_drift(struct runner *r, struct cell *c, int timer) { const double dt = (r->e->ti_current - r->e->ti_old) * timeBase; const int ti_old = r->e->ti_old; const int ti_current = r->e->ti_current; - struct part *const parts = c->parts; - struct xpart *const xparts = c->xparts; - struct gpart *const gparts = c->gparts; + struct part *restrict parts = c->parts; + struct xpart *restrict xparts = c->xparts; + struct gpart *restrict gparts = c->gparts; float dx_max = 0.f, dx2_max = 0.f, h_max = 0.f; double e_kin = 0.0, e_int = 0.0, e_pot = 0.0, mass = 0.0; @@ -634,7 +662,6 @@ void runner_do_drift(struct runner *r, struct cell *c, int timer) { struct part *const p = &parts[k]; struct xpart *const xp = &xparts[k]; - /* Drift... */ drift_part(p, xp, dt, timeBase, ti_old, ti_current); @@ -738,9 +765,9 @@ void runner_do_kick_fixdt(struct runner *r, struct cell *c, int timer) { const double timeBase = r->e->timeBase; const int count = c->count; const int gcount = c->gcount; - struct part *const parts = c->parts; - struct xpart *const xparts = c->xparts; - struct gpart *const gparts = c->gparts; + struct part *restrict parts = c->parts; + struct xpart *restrict xparts = c->xparts; + struct gpart *restrict gparts = c->gparts; const double const_G = r->e->physical_constants->const_newton_G; int updated = 0, g_updated = 0; @@ -854,9 +881,9 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { const int ti_current = r->e->ti_current; const int count = c->count; const int gcount = c->gcount; - struct part *const parts = c->parts; - struct xpart *const xparts = c->xparts; - struct gpart *const gparts = c->gparts; + struct part *restrict parts = c->parts; + struct xpart *restrict xparts = c->xparts; + struct gpart *restrict gparts = c->gparts; const double const_G = r->e->physical_constants->const_newton_G; int updated = 0, g_updated = 0; @@ -974,8 +1001,8 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { */ void runner_do_recv_cell(struct runner *r, struct cell *c, int timer) { - const struct part *const parts = c->parts; - const struct gpart *const gparts = c->gparts; + const struct part *restrict parts = c->parts; + const struct gpart *restrict gparts = c->gparts; const size_t nr_parts = c->count; const size_t nr_gparts = c->gcount; // const int ti_current = r->e->ti_current; @@ -1058,8 +1085,8 @@ void *runner_main(void *data) { runner_doself1_density(r, ci); else if (t->subtype == task_subtype_force) runner_doself2_force(r, ci); - else if (t->subtype == task_subtype_grav) - runner_doself_grav(r, ci); + else if (t->subtype == task_subtype_grav) + runner_doself_grav(r, ci); else error("Unknown task subtype."); break; @@ -1068,8 +1095,8 @@ void *runner_main(void *data) { runner_dopair1_density(r, ci, cj); else if (t->subtype == task_subtype_force) runner_dopair2_force(r, ci, cj); - else if (t->subtype == task_subtype_grav) - runner_dopair_grav(r, ci, cj); + else if (t->subtype == task_subtype_grav) + runner_dopair_grav(r, ci, cj); else error("Unknown task subtype."); break; @@ -1083,8 +1110,8 @@ void *runner_main(void *data) { runner_dosub2_force(r, ci, cj, t->flags, 1); else if (t->subtype == task_subtype_grav) runner_dosub_grav(r, ci, cj, 1); - else if (t->subtype == task_subtype_grav) - runner_dosub_grav(r, ci, cj, 1); + else if (t->subtype == task_subtype_grav) + runner_dosub_grav(r, ci, cj, 1); else error("Unknown task subtype."); break; diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 0373c27cd..0b17d6e2b 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -36,7 +36,7 @@ */ void runner_do_grav_up(struct runner *r, struct cell *c) { - if (c->split) {/* Regular node */ + if (c->split) { /* Regular node */ /* Recurse. */ for (int k = 0; k < 8; k++) @@ -49,7 +49,7 @@ void runner_do_grav_up(struct runner *r, struct cell *c) { multipole_add(&c->multipole, &c->progeny[k]->multipole); } - } else {/* Leaf node. */ + } else { /* Leaf node. */ /* Just construct the multipole from the gparts. */ multipole_init(&c->multipole, c->gparts, c->gcount); @@ -291,8 +291,8 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( * * @todo Use a local cache for the particles. */ -__attribute__((always_inline)) - INLINE static void runner_doself_grav_pp(struct runner *r, struct cell *c) { +__attribute__((always_inline)) INLINE static void runner_doself_grav_pp( + struct runner *r, struct cell *c) { // const struct engine *e = r->e; const int gcount = c->gcount; @@ -450,7 +450,7 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, } } } - } else {/* Not split */ + } else { /* Not split */ /* Compute the interactions at this level directly. */ runner_dopair_grav_pp(r, ci, cj); diff --git a/src/runner_doiact_grav_old.h b/src/runner_doiact_grav_old.h index 31aac5682..8a22024ca 100644 --- a/src/runner_doiact_grav_old.h +++ b/src/runner_doiact_grav_old.h @@ -212,7 +212,7 @@ void runner_dograv_up(struct runner *r, struct cell *c) { - if (c->split) {/* Regular node */ + if (c->split) { /* Regular node */ /* Recurse. */ for (int k = 0; k < 8; k++) @@ -225,7 +225,7 @@ void runner_dograv_up(struct runner *r, struct cell *c) { multipole_add(&c->multipole, &c->progeny[k]->multipole); } - } else {/* Leaf node. */ + } else { /* Leaf node. */ /* Just construct the multipole from the gparts. */ multipole_init(&c->multipole, c->gparts, c->gcount); diff --git a/src/scheduler.c b/src/scheduler.c index 4b7d38d8c..621601e61 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -66,8 +66,8 @@ void scheduler_addunlock(struct scheduler *s, struct task *ta, struct task **unlocks_new; int *unlock_ind_new; s->size_unlocks *= 2; - if ((unlocks_new = (struct task **)malloc( - sizeof(struct task *) *s->size_unlocks)) == NULL || + if ((unlocks_new = (struct task **)malloc(sizeof(struct task *) * + s->size_unlocks)) == NULL || (unlock_ind_new = (int *)malloc(sizeof(int) * s->size_unlocks)) == NULL) error("Failed to re-allocate unlocks."); memcpy(unlocks_new, s->unlocks, sizeof(struct task *) * s->nr_unlocks); @@ -95,13 +95,11 @@ void scheduler_addunlock(struct scheduler *s, struct task *ta, void scheduler_splittasks(struct scheduler *s) { - const int pts[7][8] = {{-1, 12, 10, 9, 4, 3, 1, 0}, - {-1, -1, 11, 10, 5, 4, 2, 1}, - {-1, -1, -1, 12, 7, 6, 4, 3}, - {-1, -1, -1, -1, 8, 7, 5, 4}, - {-1, -1, -1, -1, -1, 12, 10, 9}, - {-1, -1, -1, -1, -1, -1, 11, 10}, - {-1, -1, -1, -1, -1, -1, -1, 12}}; + const int pts[7][8] = { + {-1, 12, 10, 9, 4, 3, 1, 0}, {-1, -1, 11, 10, 5, 4, 2, 1}, + {-1, -1, -1, 12, 7, 6, 4, 3}, {-1, -1, -1, -1, 8, 7, 5, 4}, + {-1, -1, -1, -1, -1, 12, 10, 9}, {-1, -1, -1, -1, -1, -1, 11, 10}, + {-1, -1, -1, -1, -1, -1, -1, 12}}; const float sid_scale[13] = {0.1897, 0.4025, 0.1897, 0.4025, 0.5788, 0.4025, 0.1897, 0.4025, 0.1897, 0.4025, 0.5788, 0.4025, 0.5788}; @@ -719,7 +717,8 @@ void scheduler_reset(struct scheduler *s, int size) { if (s->tasks_ind != NULL) free(s->tasks_ind); /* Allocate the new lists. */ - if ((s->tasks = (struct task *)malloc(sizeof(struct task) *size)) == NULL || + if ((s->tasks = (struct task *)malloc(sizeof(struct task) * size)) == + NULL || (s->tasks_ind = (int *)malloc(sizeof(int) * size)) == NULL) error("Failed to allocate task lists."); } @@ -1224,7 +1223,7 @@ void scheduler_init(struct scheduler *s, struct space *space, int nr_tasks, /* Init the unlocks. */ if ((s->unlocks = (struct task **)malloc( - sizeof(struct task *) *scheduler_init_nr_unlocks)) == NULL || + sizeof(struct task *) * scheduler_init_nr_unlocks)) == NULL || (s->unlock_ind = (int *)malloc(sizeof(int) * scheduler_init_nr_unlocks)) == NULL) error("Failed to allocate unlocks."); diff --git a/src/single_io.c b/src/single_io.c index 14f7209dd..fb3bf4368 100644 --- a/src/single_io.c +++ b/src/single_io.c @@ -35,8 +35,8 @@ #include "single_io.h" /* Local includes. */ -#include "const.h" #include "common_io.h" +#include "const.h" #include "error.h" /*----------------------------------------------------------------------------- diff --git a/src/space.c b/src/space.c index d87107a80..ffb39dcf5 100644 --- a/src/space.c +++ b/src/space.c @@ -28,8 +28,8 @@ #include #include #include -#include #include +#include /* MPI headers. */ #ifdef WITH_MPI diff --git a/src/task.c b/src/task.c index d10271230..07218d903 100644 --- a/src/task.c +++ b/src/task.c @@ -47,13 +47,13 @@ /* Task type names. */ const char *taskID_names[task_type_count] = { - "none", "sort", "self", "pair", "sub", - "init", "ghost", "drift", "kick", "kick_fixdt", - "send", "recv", "grav_mm", "grav_up", "grav_external", - "part_sort", "gpart_sort", "split_cell", "rewait"}; + "none", "sort", "self", "pair", "sub", + "init", "ghost", "drift", "kick", "kick_fixdt", + "send", "recv", "grav_mm", "grav_up", "grav_external", + "part_sort", "gpart_sort", "split_cell", "rewait"}; -const char *subtaskID_names[task_type_count] = {"none", "density", - "force", "grav"}; +const char *subtaskID_names[task_type_count] = {"none", "density", "force", + "grav"}; /** * @brief Computes the overlap between the parts array of two given cells. @@ -124,9 +124,9 @@ void task_unlock(struct task *t) { cell_unlocktree(t->ci); if (t->cj != NULL) cell_unlocktree(t->cj); break; - //case task_type_grav_pp: + // case task_type_grav_pp: case task_type_grav_mm: - //case task_type_grav_down: + // case task_type_grav_down: cell_gunlocktree(t->ci); if (t->cj != NULL) cell_gunlocktree(t->cj); break; diff --git a/src/tools.c b/src/tools.c index a178a2d7d..e4a4f4426 100644 --- a/src/tools.c +++ b/src/tools.c @@ -20,15 +20,15 @@ ******************************************************************************/ #include -#include #include #include +#include +#include "cell.h" #include "error.h" #include "part.h" -#include "cell.h" -#include "tools.h" #include "swift.h" +#include "tools.h" /** * Factorize a given integer, attempts to keep larger pair of factors. @@ -490,7 +490,8 @@ void shuffle_particles(struct part *parts, const int count) { * @brief gparts The array of particles. * @brief gcount The number of particles. */ -void gravity_n2(struct gpart *gparts, const int gcount, const struct phys_const *constants) { +void gravity_n2(struct gpart *gparts, const int gcount, + const struct phys_const *constants) { /* Reset everything */ for (int pid = 0; pid < gcount; pid++) { diff --git a/src/tools.h b/src/tools.h index 4f587b2ab..0e6098020 100644 --- a/src/tools.h +++ b/src/tools.h @@ -42,6 +42,6 @@ void pairs_n2(double *dim, struct part *__restrict__ parts, int N, double random_uniform(double a, double b); void shuffle_particles(struct part *parts, const int count); void gravity_n2(struct gpart *gparts, const int gcount, - const struct phys_const *constants); + const struct phys_const *constants); #endif /* SWIFT_TOOL_H */ diff --git a/tests/test27cells.c b/tests/test27cells.c index 35e11fab0..3e2f11c7a 100644 --- a/tests/test27cells.c +++ b/tests/test27cells.c @@ -18,9 +18,9 @@ ******************************************************************************/ #include +#include #include #include -#include #include #include "swift.h" diff --git a/tests/testKernel.c b/tests/testKernel.c index d74fe1ec5..182bae533 100644 --- a/tests/testKernel.c +++ b/tests/testKernel.c @@ -19,8 +19,8 @@ ******************************************************************************/ #define NO__AVX__ -#include "vector.h" #include "kernel_hydro.h" +#include "vector.h" #include #include diff --git a/tests/testPair.c b/tests/testPair.c index a70cb381f..f9539fc1a 100644 --- a/tests/testPair.c +++ b/tests/testPair.c @@ -18,9 +18,9 @@ ******************************************************************************/ #include +#include #include #include -#include #include #include "swift.h" diff --git a/tests/testParser.c b/tests/testParser.c index 0b08d20c9..31979a0a5 100644 --- a/tests/testParser.c +++ b/tests/testParser.c @@ -17,11 +17,11 @@ * ******************************************************************************/ -#include "parser.h" #include -#include -#include #include +#include +#include +#include "parser.h" int main(int argc, char *argv[]) { const char *input_file = argv[1]; diff --git a/tests/testReading.c b/tests/testReading.c index 33aeb5095..7d38140d9 100644 --- a/tests/testReading.c +++ b/tests/testReading.c @@ -17,8 +17,8 @@ * ******************************************************************************/ -#include "swift.h" #include +#include "swift.h" int main() { diff --git a/tests/testSingle.c b/tests/testSingle.c index eb49a570b..d37f20908 100644 --- a/tests/testSingle.c +++ b/tests/testSingle.c @@ -22,15 +22,15 @@ #include "../config.h" /* Some standard headers. */ +#include +#include +#include +#include +#include #include #include -#include #include -#include -#include -#include -#include -#include +#include /* Conditional headers. */ #ifdef HAVE_LIBZ -- GitLab From 1310ca75fa2132bfda3cefe0240cf2d02941f61d Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sat, 4 Jun 2016 21:36:48 +0200 Subject: [PATCH 33/72] New formatting style --- src/runner.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/runner.c b/src/runner.c index 5bdf3a443..e88f4ec1e 100644 --- a/src/runner.c +++ b/src/runner.c @@ -508,8 +508,8 @@ void runner_do_ghost(struct runner *r, struct cell *c) { /* Finish the density calculation */ hydro_end_density(p, ti_current); - float h_corr = 0.f; - + float h_corr = 0.f; + /* If no derivative, double the smoothing length. */ if (p->density.wcount_dh == 0.0f) h_corr = p->h; -- GitLab From 4f4227c4288bff8f33c616c462918a78d42146a3 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 7 Jun 2016 14:28:46 +0200 Subject: [PATCH 34/72] Post-merge fixes --- src/engine.c | 26 +++++++++++++------------- src/kernel_gravity.h | 12 ++++++------ src/tools.h | 1 - tests/testKernel.c | 6 +++++- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/engine.c b/src/engine.c index ae1413be7..c0ba9444d 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1586,23 +1586,23 @@ void engine_maketasks(struct engine *e) { /* Add the communication tasks if MPI is being used. */ if (e->policy & engine_policy_mpi) { - /* Loop over the proxies. */ - for (int pid = 0; pid < e->nr_proxies; pid++) { + /* Loop over the proxies. */ + for (int pid = 0; pid < e->nr_proxies; pid++) { - /* Get a handle on the proxy. */ - struct proxy *p = &e->proxies[pid]; + /* Get a handle on the proxy. */ + struct proxy *p = &e->proxies[pid]; - /* Loop through the proxy's incoming cells and add the - recv tasks. */ - for (int k = 0; k < p->nr_cells_in; k++) - engine_addtasks_recv(e, p->cells_in[k], NULL, NULL); + /* Loop through the proxy's incoming cells and add the + recv tasks. */ + for (int k = 0; k < p->nr_cells_in; k++) + engine_addtasks_recv(e, p->cells_in[k], NULL, NULL); - /* Loop through the proxy's outgoing cells and add the - send tasks. */ - for (int k = 0; k < p->nr_cells_out; k++) - engine_addtasks_send(e, p->cells_out[k], p->cells_in[0]); + /* Loop through the proxy's outgoing cells and add the + send tasks. */ + for (int k = 0; k < p->nr_cells_out; k++) + engine_addtasks_send(e, p->cells_out[k], p->cells_in[0]); + } } -} #endif /* Set the unlocks per task. */ diff --git a/src/kernel_gravity.h b/src/kernel_gravity.h index 352ba4870..6a1e238f8 100644 --- a/src/kernel_gravity.h +++ b/src/kernel_gravity.h @@ -25,12 +25,12 @@ #include "inline.h" #include "vector.h" -#define const_iepsilon (1. / const_epsilon) -#define const_iepsilon2 (const_iepsilon *const_iepsilon) -#define const_iepsilon3 (const_iepsilon2 *const_iepsilon) -#define const_iepsilon4 (const_iepsilon2 *const_iepsilon2) -#define const_iepsilon5 (const_iepsilon3 *const_iepsilon2) -#define const_iepsilon6 (const_iepsilon3 *const_iepsilon3) +/* #define const_iepsilon (1. / const_epsilon) */ +/* #define const_iepsilon2 (const_iepsilon *const_iepsilon) */ +/* #define const_iepsilon3 (const_iepsilon2 *const_iepsilon) */ +/* #define const_iepsilon4 (const_iepsilon2 *const_iepsilon2) */ +/* #define const_iepsilon5 (const_iepsilon3 *const_iepsilon2) */ +/* #define const_iepsilon6 (const_iepsilon3 *const_iepsilon3) */ /* The gravity kernel is defined as a degree 6 polynomial in the distance r. The resulting value should be post-multiplied with r^-3, resulting diff --git a/src/tools.h b/src/tools.h index e05c93bde..0e6098020 100644 --- a/src/tools.h +++ b/src/tools.h @@ -25,7 +25,6 @@ #include "cell.h" #include "physical_constants.h" #include "runner.h" -#include "cell.h" void factor(int value, int *f1, int *f2); void density_dump(int N); diff --git a/tests/testKernel.c b/tests/testKernel.c index 182bae533..700352ccb 100644 --- a/tests/testKernel.c +++ b/tests/testKernel.c @@ -17,7 +17,7 @@ * along with this program. If not, see . * ******************************************************************************/ - +#ifdef __AVX__ #define NO__AVX__ #include "kernel_hydro.h" #include "vector.h" @@ -86,3 +86,7 @@ int main() { printf("\nAll values are consistent\n"); return 0; } + +#else +int main() { return 0; } +#endif -- GitLab From 9e28ec1eb4700a360b83da62eff0ae55d5edbb77 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 8 Jun 2016 17:01:29 +0200 Subject: [PATCH 35/72] Upated the kernel functions for gravity. Added a unit test to test it against the Gadget-2 kernel --- .gitignore | 1 + src/Makefile.am | 2 +- src/kernel_gravity.c | 77 -------------- src/kernel_gravity.h | 225 +++++------------------------------------ tests/Makefile.am | 6 +- tests/testKernelGrav.c | 85 ++++++++++++++++ 6 files changed, 118 insertions(+), 278 deletions(-) delete mode 100644 src/kernel_gravity.c create mode 100644 tests/testKernelGrav.c diff --git a/.gitignore b/.gitignore index 9a5684311..06e97d6b5 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,7 @@ tests/testSingle tests/testTimeIntegration tests/testSPHStep tests/testKernel +tests/testKernelGrav tests/testParser tests/parser_output.yml diff --git a/src/Makefile.am b/src/Makefile.am index 26eb7f636..cd5a47ea8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,7 +42,7 @@ include_HEADERS = space.h runner.h queue.h task.h lock.h cell.h part.h const.h \ 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_hydro.c kernel_gravity.c tools.c part.c partition.c clocks.c parser.c \ + kernel_hydro.c tools.c part.c partition.c clocks.c parser.c \ physical_constants.c potentials.c hydro_properties.c # Include files for distribution, not installation. diff --git a/src/kernel_gravity.c b/src/kernel_gravity.c deleted file mode 100644 index 7bab7cf55..000000000 --- a/src/kernel_gravity.c +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * This file is part of SWIFT. - * Copyright (c) 2015 Pedro Gonnet (pedro.gonnet@durham.ac.uk), - * Matthieu Schaller (matthieu.schaller@durham.ac.uk) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - ******************************************************************************/ - -#include -#include - -#include "kernel_gravity.h" - -#define const_epsilon 1. -#define const_iepsilon3 1. - -/** - * @brief The Gadget-2 gravity kernel function - * - * @param r The distance between particles - */ -float gadget(float r) { - float fac, h_inv, u, r2 = r * r; - if (r >= const_epsilon) - fac = 1.0f / (r2 * r); - else { - h_inv = 1. / const_epsilon; - u = r * h_inv; - if (u < 0.5) - fac = const_iepsilon3 * (10.666666666667 + u * u * (32.0 * u - 38.4)); - else - fac = const_iepsilon3 * - (21.333333333333 - 48.0 * u + 38.4 * u * u - - 10.666666666667 * u * u * u - 0.066666666667 / (u * u * u)); - } - return fac; -} - -/** - * @brief Test the gravity kernel function by dumping it in the interval [0,1]. - * - * @param r_max The radius up to which the kernel is dumped. - * @param N number of intervals in [0,1]. - */ -void gravity_kernel_dump(float r_max, int N) { - - int k; - float x, w; - float x4[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - float w4[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - // float dw_dx4[4] __attribute__ ((aligned (16))); - - for (k = 1; k <= N; k++) { - x = (r_max * k) / N; - x4[3] = x4[2]; - x4[2] = x4[1]; - x4[1] = x4[0]; - x4[0] = x; - kernel_grav_eval(x, &w); - w *= 1.f / (x * x * x); - // blender_deval_vec( (vector *)x4 , (vector *)w4 , (vector *)dw_dx4 ); - printf(" %.16e %.16e %.16e %.16e %.16e %.16e %.16e\n", x, w * x, w4[0], - w4[1], w4[2], w4[3], gadget(x) * x); - } -} diff --git a/src/kernel_gravity.h b/src/kernel_gravity.h index 6a1e238f8..bef650347 100644 --- a/src/kernel_gravity.h +++ b/src/kernel_gravity.h @@ -20,18 +20,13 @@ #ifndef SWIFT_KERNEL_GRAVITY_H #define SWIFT_KERNEL_GRAVITY_H +#include + /* Includes. */ #include "const.h" #include "inline.h" #include "vector.h" -/* #define const_iepsilon (1. / const_epsilon) */ -/* #define const_iepsilon2 (const_iepsilon *const_iepsilon) */ -/* #define const_iepsilon3 (const_iepsilon2 *const_iepsilon) */ -/* #define const_iepsilon4 (const_iepsilon2 *const_iepsilon2) */ -/* #define const_iepsilon5 (const_iepsilon3 *const_iepsilon2) */ -/* #define const_iepsilon6 (const_iepsilon3 *const_iepsilon3) */ - /* The gravity kernel is defined as a degree 6 polynomial in the distance r. The resulting value should be post-multiplied with r^-3, resulting in a polynomial with terms ranging from r^-3 to r^3, which are @@ -44,16 +39,27 @@ #define kernel_grav_ivals 2 /* Number of branches */ static const float kernel_grav_coeffs[(kernel_grav_degree + 1) * (kernel_grav_ivals + 1)] - __attribute__((aligned(16))) = { - 32.f, -38.4f, 0.f, 10.66666667f, - 0.f, 0.f, 0.f, /* 0 < u < 0.5 */ - -10.66666667f, 38.4f, -48.f, 21.3333333, - 0.f, 0.f, 0.66666667f, /* 0.5 < u < 1 */ - 0.f, 0.f, 0.f, 0.f, - 0.f, 0.f, 0.f}; /* 1 < u */ - -#define kernel_grav_igamma 1. -#define kernel_grav_igamma3 1. + __attribute__((aligned(16))) = {32.f, + -38.4f, + 0.f, + 10.66666667f, + 0.f, + 0.f, + 0.f, /* 0 < u < 0.5 */ + -10.66666667f, + 38.4f, + -48.f, + 21.3333333, + 0.f, + 0.f, + -0.066666667f, /* 0.5 < u < 1 */ + 0.f, + 0.f, + 0.f, + 0.f, + 0.f, + 0.f, + 0.f}; /* 1 < u */ /** * @brief Computes the kernel function. @@ -63,197 +69,20 @@ static const float */ __attribute__((always_inline)) INLINE static void kernel_grav_eval( float u, float *const W) { - /* Go to the range [0,1[ from [0,H[ */ - const float x = u * (float)kernel_grav_igamma; /* Pick the correct branch of the kernel */ - const int ind = (int)fminf(x * (float)kernel_grav_ivals, kernel_grav_ivals); + const int ind = (int)fminf(u * (float)kernel_grav_ivals, kernel_grav_ivals); const float *const coeffs = &kernel_grav_coeffs[ind * (kernel_grav_degree + 1)]; /* First two terms of the polynomial ... */ - float w = coeffs[0] * x + coeffs[1]; + float w = coeffs[0] * u + coeffs[1]; /* ... and the rest of them */ - for (int k = 2; k <= kernel_grav_degree; k++) w = x * w + coeffs[k]; + for (int k = 2; k <= kernel_grav_degree; k++) w = u * w + coeffs[k]; /* Return everything */ - *W = w * (float)kernel_grav_igamma3; -} - -#if 0 - - -/* Coefficients for the gravity kernel. */ -#define kernel_grav_degree 6 -#define kernel_grav_ivals 2 -#define kernel_grav_scale (2 * const_iepsilon) -static float kernel_grav_coeffs - [(kernel_grav_degree + 1) * (kernel_grav_ivals + 1)] = { - 32.0f * const_iepsilon6, -192.0f / 5.0f * const_iepsilon5, - 0.0f, 32.0f / 3.0f * const_iepsilon3, - 0.0f, 0.0f, - 0.0f, -32.0f / 3.0f * const_iepsilon6, - 192.0f / 5.0f * const_iepsilon5, -48.0f * const_iepsilon4, - 64.0f / 3.0f * const_iepsilon3, 0.0f, - 0.0f, -1.0f / 15.0f, - 0.0f, 0.0f, - 0.0f, 0.0f, - 0.0f, 0.0f, - 1.0f}; - -/** - * @brief Computes the gravity cubic spline for a given distance x. - */ - -__attribute__((always_inline)) INLINE static void kernel_grav_eval(float x, - float *W) { - int ind = fmin(x * kernel_grav_scale, kernel_grav_ivals); - float *coeffs = &kernel_grav_coeffs[ind * (kernel_grav_degree + 1)]; - float w = coeffs[0] * x + coeffs[1]; - for (int k = 2; k <= kernel_grav_degree; k++) w = x * w + coeffs[k]; - *W = w; -} - -#ifdef VECTORIZE - -/** - * @brief Computes the gravity cubic spline for a given distance x (Vectorized - * version). - */ - -__attribute__((always_inline)) - INLINE static void kernel_grav_eval_vec(vector *x, vector *w) { - - vector ind, c[kernel_grav_degree + 1]; - int j, k; - - /* Load x and get the interval id. */ - ind.m = vec_ftoi(vec_fmin(x->v * vec_set1(kernel_grav_scale), - vec_set1((float)kernel_grav_ivals))); - - /* load the coefficients. */ - for (k = 0; k < VEC_SIZE; k++) - for (j = 0; j < kernel_grav_degree + 1; j++) - c[j].f[k] = kernel_grav_coeffs[ind.i[k] * (kernel_grav_degree + 1) + j]; - - /* Init the iteration for Horner's scheme. */ - w->v = (c[0].v * x->v) + c[1].v; - - /* And we're off! */ - for (int k = 2; k <= kernel_grav_degree; k++) w->v = (x->v * w->v) + c[k].v; + *W = w / (u * u * u); } -#endif - -/* Blending function stuff - * -------------------------------------------------------------------------------------------- - */ - -/* Coefficients for the blending function. */ -#define blender_degree 3 -#define blender_ivals 3 -#define blender_scale 4.0f -static float blender_coeffs[(blender_degree + 1) * (blender_ivals + 1)] = { - 0.0f, 0.0f, 0.0f, 1.0f, -32.0f, 24.0f, -6.0f, 1.5f, - -32.0f, 72.0f, -54.0f, 13.5f, 0.0f, 0.0f, 0.0f, 0.0f}; - -/** - * @brief Computes the cubic spline blender for a given distance x. - */ - -__attribute__((always_inline)) INLINE static void blender_eval(float x, - float *W) { - int ind = fmin(x * blender_scale, blender_ivals); - float *coeffs = &blender_coeffs[ind * (blender_degree + 1)]; - float w = coeffs[0] * x + coeffs[1]; - for (int k = 2; k <= blender_degree; k++) w = x * w + coeffs[k]; - *W = w; -} - -/** - * @brief Computes the cubic spline blender and its derivative for a given - * distance x. - */ - -__attribute__((always_inline)) INLINE static void blender_deval(float x, - float *W, - float *dW_dx) { - int ind = fminf(x * blender_scale, blender_ivals); - float *coeffs = &blender_coeffs[ind * (blender_degree + 1)]; - float w = coeffs[0] * x + coeffs[1]; - float dw_dx = coeffs[0]; - for (int k = 2; k <= blender_degree; k++) { - dw_dx = dw_dx * x + w; - w = x * w + coeffs[k]; - } - *W = w; - *dW_dx = dw_dx; -} - -#ifdef VECTORIZE - -/** - * @brief Computes the cubic spline blender and its derivative for a given - * distance x (Vectorized version). Gives a sensible answer only if x<2. - */ - -__attribute__((always_inline)) INLINE static void blender_eval_vec(vector *x, - vector *w) { - - vector ind, c[blender_degree + 1]; - int j, k; - - /* Load x and get the interval id. */ - ind.m = vec_ftoi( - vec_fmin(x->v * vec_set1(blender_scale), vec_set1((float)blender_ivals))); - - /* load the coefficients. */ - for (k = 0; k < VEC_SIZE; k++) - for (j = 0; j < blender_degree + 1; j++) - c[j].f[k] = blender_coeffs[ind.i[k] * (blender_degree + 1) + j]; - - /* Init the iteration for Horner's scheme. */ - w->v = (c[0].v * x->v) + c[1].v; - - /* And we're off! */ - for (int k = 2; k <= blender_degree; k++) w->v = (x->v * w->v) + c[k].v; -} - -/** - * @brief Computes the cubic spline blender and its derivative for a given - * distance x (Vectorized version). Gives a sensible answer only if x<2. - */ - -__attribute__((always_inline)) - INLINE static void blender_deval_vec(vector *x, vector *w, vector *dw_dx) { - - vector ind, c[blender_degree + 1]; - int j, k; - - /* Load x and get the interval id. */ - ind.m = vec_ftoi( - vec_fmin(x->v * vec_set1(blender_scale), vec_set1((float)blender_ivals))); - - /* load the coefficients. */ - for (k = 0; k < VEC_SIZE; k++) - for (j = 0; j < blender_degree + 1; j++) - c[j].f[k] = blender_coeffs[ind.i[k] * (blender_degree + 1) + j]; - - /* Init the iteration for Horner's scheme. */ - w->v = (c[0].v * x->v) + c[1].v; - dw_dx->v = c[0].v; - - /* And we're off! */ - for (int k = 2; k <= blender_degree; k++) { - dw_dx->v = (dw_dx->v * x->v) + w->v; - w->v = (x->v * w->v) + c[k].v; - } -} - -#endif -#endif - -void gravity_kernel_dump(float r_max, int N); - #endif // SWIFT_KERNEL_GRAVITY_H diff --git a/tests/Makefile.am b/tests/Makefile.am index d0c132ad1..e7fdec264 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -22,11 +22,11 @@ AM_LDFLAGS = ../src/.libs/libswiftsim.a $(HDF5_LDFLAGS) $(HDF5_LIBS) # List of programs and scripts to run in the test suite TESTS = testGreetings testReading.sh testSingle testPair.sh testPairPerturbed.sh \ - test27cells.sh test27cellsPerturbed.sh testParser.sh testKernel + test27cells.sh test27cellsPerturbed.sh testParser.sh testKernel testKernelGrav # List of test programs to compile check_PROGRAMS = testGreetings testReading testSingle testTimeIntegration \ - testSPHStep testPair test27cells testParser testKernel + testSPHStep testPair test27cells testParser testKernel testKernelGrav # Sources for the individual programs testGreetings_SOURCES = testGreetings.c @@ -47,6 +47,8 @@ testParser_SOURCES = testParser.c testKernel_SOURCES = testKernel.c +testKernelGrav_SOURCES = testKernelGrav.c + # Files necessary for distribution EXTRA_DIST = testReading.sh makeInput.py testPair.sh testPairPerturbed.sh \ test27cells.sh test27cellsPerturbed.sh tolerance.dat testParser.sh \ diff --git a/tests/testKernelGrav.c b/tests/testKernelGrav.c new file mode 100644 index 000000000..2adc6f703 --- /dev/null +++ b/tests/testKernelGrav.c @@ -0,0 +1,85 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (C) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) + * James Willis (james.s.willis@durham.ac.uk) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + ******************************************************************************/ +#include "kernel_gravity.h" + +#include +#include +#include +#include + +#define numPoints (1 << 6) + +/** + * @brief The Gadget-2 gravity kernel function + * + * @param r The distance between particles + */ +float gadget(float r, float h) { + float fac; + const float r2 = r * r; + if (r >= h) + fac = 1.0f / (r2 * r); + else { + const float h_inv = 1. / h; + const float h_inv3 = h_inv * h_inv * h_inv; + const float u = r * h_inv; + if (u < 0.5) + fac = h_inv3 * (10.666666666667 + u * u * (32.0 * u - 38.4)); + else + fac = + h_inv3 * (21.333333333333 - 48.0 * u + 38.4 * u * u - + 10.666666666667 * u * u * u - 0.066666666667 / (u * u * u)); + } + return fac; +} + +int main() { + + const float h = 3.f; + const float r_max = 5.f; + + for (int k = 1; k < numPoints; ++k) { + + const float r = (r_max * k) / numPoints; + + const float u = r / h; + + const float gadget_w = gadget(r, h); + + float swift_w; + if (u < 1.) { + kernel_grav_eval(u, &swift_w); + swift_w *= (1 / (h * h * h)); + } else { + swift_w = 1 / (r * r * r); + } + + printf("%2d: r= %f h= %f u= %f Wg(r,h)= %f Ws(r,h)= %f\n", k, r, h, u, + gadget_w, swift_w); + + if (fabsf(gadget_w - swift_w) > 2e-7) { + printf("Invalid value ! Gadget= %e, SWIFT= %e\n", gadget_w, swift_w); + return 1; + } + } + + printf("\nAll values are consistent\n"); + return 0; +} -- GitLab From 4b3f8b020aa027b26dccbb0868e4871a544067e2 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 9 Jun 2016 11:09:58 +0200 Subject: [PATCH 36/72] Moved the gravity interaction routines to the correct files. --- src/gravity/Default/gravity_iact.h | 91 ++++++++++- src/kernel_gravity.h | 3 +- src/runner_doiact_grav.h | 246 +++++++++++------------------ src/tools.c | 2 +- 4 files changed, 178 insertions(+), 164 deletions(-) diff --git a/src/gravity/Default/gravity_iact.h b/src/gravity/Default/gravity_iact.h index 6d8aa3261..671ca6a34 100644 --- a/src/gravity/Default/gravity_iact.h +++ b/src/gravity/Default/gravity_iact.h @@ -23,18 +23,97 @@ /* Includes. */ #include "const.h" #include "kernel_gravity.h" +#include "multipole.h" #include "vector.h" /** - * @brief Gravity potential + * @brief Gravity forces between particles */ -__attribute__((always_inline)) INLINE static void runner_iact_grav( - float r2, float *dx, struct gpart *pi, struct gpart *pj) {} +__attribute__((always_inline)) INLINE static void runner_iact_grav_pp( + float r2, const float *dx, struct gpart *gpi, struct gpart *gpj) { + + /* Apply the gravitational acceleration. */ + const float ir = 1.0f / sqrtf(r2); + const float w = ir * ir * ir; + const float wdx[3] = {w * dx[0], w * dx[1], w * dx[2]}; + const float mi = gpi->mass; + const float mj = gpj->mass; + + gpi->a_grav[0] -= wdx[0] * mj; + gpi->a_grav[1] -= wdx[1] * mj; + gpi->a_grav[2] -= wdx[2] * mj; + gpi->mass_interacted += mj; + + gpj->a_grav[0] += wdx[0] * mi; + gpj->a_grav[1] += wdx[1] * mi; + gpj->a_grav[2] += wdx[2] * mi; + gpj->mass_interacted += mi; +} + +__attribute__((always_inline)) INLINE static void runner_iact_grav_pp_nonsym( + float r2, const float *dx, struct gpart *gpi, const struct gpart *gpj) { + + /* Apply the gravitational acceleration. */ + const float ir = 1.0f / sqrtf(r2); + const float w = ir * ir * ir; + const float wdx[3] = {w * dx[0], w * dx[1], w * dx[2]}; + const float mj = gpj->mass; + + gpi->a_grav[0] -= wdx[0] * mj; + gpi->a_grav[1] -= wdx[1] * mj; + gpi->a_grav[2] -= wdx[2] * mj; + gpi->mass_interacted += mj; +} /** - * @brief Gravity potential (Vectorized version) + * @brief Gravity forces between particles */ -__attribute__((always_inline)) INLINE static void runner_iact_vec_grav( - float *R2, float *Dx, struct gpart **pi, struct gpart **pj) {} +__attribute__((always_inline)) INLINE static void runner_iact_grav_pm( + float r2, const float *dx, struct gpart *gp, + const struct multipole *multi) { + + /* Apply the gravitational acceleration. */ + const float r = sqrtf(r2); + const float ir = 1.f / r; + const float mrinv3 = multi->mass * ir * ir * ir; + +#if multipole_order < 2 + + /* 0th and 1st order terms */ + gp->a_grav[0] += mrinv3 * dx[0]; + gp->a_grav[1] += mrinv3 * dx[1]; + gp->a_grav[2] += mrinv3 * dx[2]; + + gp->mass_interacted += multi->mass; +#elif multipole_order == 2 + /* Terms up to 2nd order (quadrupole) */ + + /* Follows the notation in Bonsai */ + const float mrinv5 = mrinv3 * ir * ir; + const float mrinv7 = mrinv5 * ir * ir; + + const float D1 = -mrinv3; + const float D2 = 3.f * mrinv5; + const float D3 = -15.f * mrinv7; + + const float q = multi->I_xx + multi->I_yy + multi->I_zz; + const float qRx = + multi->I_xx * dx[0] + multi->I_xy * dx[1] + multi->I_xz * dx[2]; + const float qRy = + multi->I_xy * dx[0] + multi->I_yy * dx[1] + multi->I_yz * dx[2]; + const float qRz = + multi->I_xz * dx[0] + multi->I_yz * dx[1] + multi->I_zz * dx[2]; + const float qRR = qRx * dx[0] + qRy * dx[1] + qRz * dx[2]; + const float C = D1 + 0.5f * D2 * q + 0.5f * D3 * qRR; + + gp->a_grav[0] -= C * dx[0] + D2 * qRx; + gp->a_grav[1] -= C * dx[1] + D2 * qRy; + gp->a_grav[2] -= C * dx[2] + D2 * qRz; + + gp->mass_interacted += multi->mass; +#else +#error "Multipoles of order >2 not yet implemented." +#endif +} #endif /* SWIFT_RUNNER_IACT_GRAV_H */ diff --git a/src/kernel_gravity.h b/src/kernel_gravity.h index bef650347..1e39f9685 100644 --- a/src/kernel_gravity.h +++ b/src/kernel_gravity.h @@ -31,7 +31,8 @@ r. The resulting value should be post-multiplied with r^-3, resulting in a polynomial with terms ranging from r^-3 to r^3, which are sufficient to model both the direct potential as well as the splines - near the origin. */ + near the origin. + As in the hydro case, the 1/h^3 needs to be multiplied in afterwards */ /* Coefficients for the kernel. */ #define kernel_grav_name "Gadget-2 softening kernel" diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 0b17d6e2b..9dc8432a4 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -22,7 +22,7 @@ /* Includes. */ #include "cell.h" -#include "clocks.h" +#include "gravity.h" #include "part.h" #define ICHECK -1 @@ -113,19 +113,20 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( error("Multipole does not seem to have been set."); #endif - /* Anything to do here? */ - // if (ci->ti_end_min > ti_current) return; - /* Loop over every particle in leaf. */ - /* for (int pid = 0; pid < gcount; pid++) { */ +/* Anything to do here? */ +// if (ci->ti_end_min > ti_current) return; + +#if ICHECK > 0 + for (int pid = 0; pid < gcount; pid++) { - /* /\* Get a hold of the ith part in ci. *\/ */ - /* struct gpart *restrict gp = &gparts[pid]; */ + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &gparts[pid]; - /* if (gp->id == -ICHECK) */ - /* message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, - * cj->loc[0], */ - /* cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); */ - /* } */ + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, cj->loc[0], + cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); + } +#endif /* Loop over every particle in leaf. */ for (int pid = 0; pid < gcount; pid++) { @@ -143,46 +144,8 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( multi.CoM[2] - gp->x[2]}; // z const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; - /* Apply the gravitational acceleration. */ - const float ir = 1.0f / sqrtf(r2); - const float mrinv3 = multi.mass * ir * ir * ir; - -#if multipole_order < 2 - - /* 0th and 1st order terms */ - gp->a_grav[0] += mrinv3 * dx[0]; - gp->a_grav[1] += mrinv3 * dx[1]; - gp->a_grav[2] += mrinv3 * dx[2]; - -#elif multipole_order == 2 - /* Terms up to 2nd order (quadrupole) */ - - /* Follows the notation in Bonsai */ - const float mrinv5 = mrinv3 * ir * ir; - const float mrinv7 = mrinv5 * ir * ir; - - const float D1 = -mrinv3; - const float D2 = 3.f * mrinv5; - const float D3 = -15.f * mrinv7; - - const float q = multi.I_xx + multi.I_yy + multi.I_zz; - const float qRx = - multi.I_xx * dx[0] + multi.I_xy * dx[1] + multi.I_xz * dx[2]; - const float qRy = - multi.I_xy * dx[0] + multi.I_yy * dx[1] + multi.I_yz * dx[2]; - const float qRz = - multi.I_xz * dx[0] + multi.I_yz * dx[1] + multi.I_zz * dx[2]; - const float qRR = qRx * dx[0] + qRy * dx[1] + qRz * dx[2]; - const float C = D1 + 0.5f * D2 * q + 0.5f * D3 * qRR; - - gp->a_grav[0] -= C * dx[0] + D2 * qRx; - gp->a_grav[1] -= C * dx[1] + D2 * qRy; - gp->a_grav[2] -= C * dx[2] + D2 * qRz; - - gp->mass_interacted += multi.mass; -#else -#error "Multipoles of order >2 not yet implemented." -#endif + /* Interact !*/ + runner_iact_grav_pm(r2, dx, gp, &multi); } TIMER_TOC(TIMER_DOPAIR); // MATTHIEU @@ -215,44 +178,42 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( error("Non matching cell sizes !! h_i=%f h_j=%f", ci->h[0], cj->h[0]); #endif - /* Anything to do here? */ - // if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; +/* Anything to do here? */ +// if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; - /* for (int pid = 0; pid < gcount_i; pid++) { */ +#if ICHECK > 0 + for (int pid = 0; pid < gcount_i; pid++) { - /* /\* Get a hold of the ith part in ci. *\/ */ - /* struct gpart *restrict gp = &gparts_i[pid]; */ + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &gparts_i[pid]; - /* if (gp->id == -ICHECK) */ - /* message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, - * cj->loc[0], */ - /* cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); */ - /* } */ + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, cj->loc[0], + cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); + } - /* for (int pid = 0; pid < gcount_j; pid++) { */ + for (int pid = 0; pid < gcount_j; pid++) { - /* /\* Get a hold of the ith part in ci. *\/ */ - /* struct gpart *restrict gp = &gparts_j[pid]; */ + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &gparts_j[pid]; - /* if (gp->id == -ICHECK) */ - /* message("id=%lld loc=[ %f %f %f ] size= %f count=%d", gp->id, - * ci->loc[0], */ - /* ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); */ - /* } */ + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count=%d", gp->id, ci->loc[0], + ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); + } +#endif /* Loop over all particles in ci... */ for (int pid = 0; pid < gcount_i; pid++) { /* Get a hold of the ith part in ci. */ struct gpart *restrict gpi = &gparts_i[pid]; - const float mi = gpi->mass; /* Loop over every particle in the other cell. */ for (int pjd = 0; pjd < gcount_j; pjd++) { /* Get a hold of the jth part in cj. */ struct gpart *restrict gpj = &gparts_j[pjd]; - const float mj = gpj->mass; /* Compute the pairwise distance. */ const float dx[3] = {gpi->x[0] - gpj->x[0], // x @@ -260,23 +221,8 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( gpi->x[2] - gpj->x[2]}; // z const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; - /* Apply the gravitational acceleration. */ - const float ir = 1.0f / sqrtf(r2); - const float w = ir * ir * ir; - const float wdx[3] = {w * dx[0], w * dx[1], w * dx[2]}; - - // if (gpi->ti_end <= ti_current) { - gpi->a_grav[0] -= wdx[0] * mj; - gpi->a_grav[1] -= wdx[1] * mj; - gpi->a_grav[2] -= wdx[2] * mj; - gpi->mass_interacted += mj; - //} - // if (gpj->ti_end <= ti_current) { - gpj->a_grav[0] += wdx[0] * mi; - gpj->a_grav[1] += wdx[1] * mi; - gpj->a_grav[2] += wdx[2] * mi; - gpj->mass_interacted += mi; - // } + /* Interact ! */ + runner_iact_grav_pp(r2, dx, gpi, gpj); } } @@ -306,33 +252,32 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( error("Empty cell !"); #endif - /* Anything to do here? */ - // if (c->ti_end_min > ti_current) return; +/* Anything to do here? */ +// if (c->ti_end_min > ti_current) return; - /* for (int pid = 0; pid < gcount; pid++) { */ +#if ICHECK > 0 + for (int pid = 0; pid < gcount; pid++) { - /* /\* Get a hold of the ith part in ci. *\/ */ - /* struct gpart *restrict gp = &gparts[pid]; */ + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &gparts[pid]; - /* if (gp->id == -ICHECK) */ - /* message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, - * c->loc[0], */ - /* c->loc[1], c->loc[2], c->h[0], c->gcount); */ - /* } */ + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, c->loc[0], + c->loc[1], c->loc[2], c->h[0], c->gcount); + } +#endif /* Loop over all particles in ci... */ for (int pid = 0; pid < gcount; pid++) { /* Get a hold of the ith part in ci. */ struct gpart *restrict gpi = &gparts[pid]; - const float mi = gpi->mass; /* Loop over every particle in the other cell. */ for (int pjd = pid + 1; pjd < gcount; pjd++) { /* Get a hold of the jth part in ci. */ struct gpart *restrict gpj = &gparts[pjd]; - const float mj = gpj->mass; /* Compute the pairwise distance. */ const float dx[3] = {gpi->x[0] - gpj->x[0], // x @@ -340,23 +285,8 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( gpi->x[2] - gpj->x[2]}; // z const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; - /* Apply the gravitational acceleration. */ - const float ir = 1.0f / sqrtf(r2); - const float w = ir * ir * ir; - const float wdx[3] = {w * dx[0], w * dx[1], w * dx[2]}; - - // if (gpi->ti_end <= ti_current) { - gpi->a_grav[0] -= wdx[0] * mj; - gpi->a_grav[1] -= wdx[1] * mj; - gpi->a_grav[2] -= wdx[2] * mj; - gpi->mass_interacted += mj; - //} - // if (gpj->ti_end <= ti_current) { - gpj->a_grav[0] += wdx[0] * mi; - gpj->a_grav[1] += wdx[1] * mi; - gpj->a_grav[2] += wdx[2] * mi; - gpj->mass_interacted += mi; - //} + /* Interact ! */ + runner_iact_grav_pp(r2, dx, gpi, gpj); } } @@ -404,27 +334,27 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, #endif - /* for (int pid = 0; pid < gcount_i; pid++) { */ +#if ICHECK > 0 + for (int pid = 0; pid < gcount_i; pid++) { - /* /\* Get a hold of the ith part in ci. *\/ */ - /* struct gpart *restrict gp = &ci->gparts[pid]; */ + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &ci->gparts[pid]; - /* if (gp->id == -ICHECK) */ - /* message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, - * cj->loc[0], */ - /* cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); */ - /* } */ + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, cj->loc[0], + cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); + } - /* for (int pid = 0; pid < gcount_j; pid++) { */ + for (int pid = 0; pid < gcount_j; pid++) { - /* /\* Get a hold of the ith part in ci. *\/ */ - /* struct gpart *restrict gp = &cj->gparts[pid]; */ + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &cj->gparts[pid]; - /* if (gp->id == -ICHECK) */ - /* message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, - * ci->loc[0], */ - /* ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); */ - /* } */ + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, ci->loc[0], + ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); + } +#endif /* Are both cells split ? */ if (ci->split && cj->split) { @@ -501,7 +431,9 @@ static void runner_dosub_grav(struct runner *r, struct cell *ci, } else { +#ifdef SANITY_CHECKS if (!are_neighbours(ci, cj)) error("Non-neighbouring cells in pair task !"); +#endif runner_dopair_grav(r, ci, cj); } @@ -510,35 +442,37 @@ static void runner_dosub_grav(struct runner *r, struct cell *ci, static void runner_do_grav_mm(struct runner *r, struct cell *ci, struct cell *cj) { - /* for (int pid = 0; pid < ci->gcount; pid++) { */ +#ifdef SANITY_CHECKS + if (are_neighbours(ci, cj)) { + + error("Non-neighbouring cells in mm task !"); - /* /\* Get a hold of the ith part in ci. *\/ */ - /* struct gpart *restrict gp = &ci->gparts[pid]; */ +#endif - /* if (gp->id == -ICHECK) */ - /* message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, - * cj->loc[0], */ - /* cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); */ - /* } */ +#if ICHECK > 0 + for (int pid = 0; pid < ci->gcount; pid++) { - /* for (int pid = 0; pid < cj->gcount; pid++) { */ + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &ci->gparts[pid]; - /* /\* Get a hold of the ith part in ci. *\/ */ - /* struct gpart *restrict gp = &cj->gparts[pid]; */ + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, + cj->loc[0], cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); + } - /* if (gp->id == -ICHECK) */ - /* message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, - * ci->loc[0], */ - /* ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); */ - /* } */ + for (int pid = 0; pid < cj->gcount; pid++) { - if (are_neighbours(ci, cj)) { + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &cj->gparts[pid]; - error("Non-neighbouring cells in mm task !"); - } + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, + ci->loc[0], ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); + } +#endif - runner_dopair_grav_pm(r, ci, cj); - runner_dopair_grav_pm(r, cj, ci); -} + runner_dopair_grav_pm(r, ci, cj); + runner_dopair_grav_pm(r, cj, ci); + } #endif /* SWIFT_RUNNER_DOIACT_GRAV_H */ diff --git a/src/tools.c b/src/tools.c index e4a4f4426..30950381d 100644 --- a/src/tools.c +++ b/src/tools.c @@ -305,7 +305,7 @@ void pairs_single_grav(double *dim, long long int pid, fdx[i] = dx[i]; } r2 = fdx[0] * fdx[0] + fdx[1] * fdx[1] + fdx[2] * fdx[2]; - runner_iact_grav(r2, fdx, &pi, &pj); + runner_iact_grav_pp(r2, fdx, &pi, &pj); a[0] += pi.a_grav[0]; a[1] += pi.a_grav[1]; a[2] += pi.a_grav[2]; -- GitLab From 0c8575ca6e74fcbd4364c1addac4fe17cc6b9b20 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 9 Jun 2016 11:24:52 +0200 Subject: [PATCH 37/72] Multiple time-stepping in the gravity tasks --- src/engine.c | 3 +- src/runner_doiact_grav.h | 78 ++++++++++++++++++++++++++++------------ 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/src/engine.c b/src/engine.c index c0ba9444d..67e6e4553 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1717,7 +1717,8 @@ int engine_marktasks(struct engine *e) { return 1; /* Set the sort flags. */ - if (!t->skip && t->type == task_type_pair) { + if (!t->skip && t->type == task_type_pair && + t->subtype != task_subtype_grav) { if (!(ci->sorted & (1 << t->flags))) { ci->sorts->flags |= (1 << t->flags); ci->sorts->skip = 0; diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 9dc8432a4..81529eea3 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -98,11 +98,11 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( const struct runner *r, const struct cell *restrict ci, const struct cell *restrict cj) { - // const struct engine *e = r->e; + const struct engine *e = r->e; const int gcount = ci->gcount; struct gpart *restrict gparts = ci->gparts; const struct multipole multi = cj->multipole; - // const int ti_current = e->ti_current; + const int ti_current = e->ti_current; TIMER_TIC; @@ -113,8 +113,8 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( error("Multipole does not seem to have been set."); #endif -/* Anything to do here? */ -// if (ci->ti_end_min > ti_current) return; + /* Anything to do here? */ + if (ci->ti_end_min > ti_current) return; #if ICHECK > 0 for (int pid = 0; pid < gcount; pid++) { @@ -134,9 +134,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( /* Get a hold of the ith part in ci. */ struct gpart *restrict gp = &gparts[pid]; - if (gp->id == -ICHECK) message("id=%lld mass= %f", gp->id, multi.mass); - - // if (gp->ti_end > ti_current) continue; + if (gp->ti_end > ti_current) continue; /* Compute the pairwise distance. */ const float dx[3] = {multi.CoM[0] - gp->x[0], // x @@ -164,12 +162,12 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( struct runner *r, struct cell *ci, struct cell *cj) { - // const struct engine *e = r->e; + const struct engine *e = r->e; const int gcount_i = ci->gcount; const int gcount_j = cj->gcount; struct gpart *restrict gparts_i = ci->gparts; struct gpart *restrict gparts_j = cj->gparts; - // const int ti_current = e->ti_current; + const int ti_current = e->ti_current; TIMER_TIC; @@ -178,8 +176,8 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( error("Non matching cell sizes !! h_i=%f h_j=%f", ci->h[0], cj->h[0]); #endif -/* Anything to do here? */ -// if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; + /* Anything to do here? */ + if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; #if ICHECK > 0 for (int pid = 0; pid < gcount_i; pid++) { @@ -216,13 +214,30 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( struct gpart *restrict gpj = &gparts_j[pjd]; /* Compute the pairwise distance. */ - const float dx[3] = {gpi->x[0] - gpj->x[0], // x - gpi->x[1] - gpj->x[1], // y - gpi->x[2] - gpj->x[2]}; // z + float dx[3] = {gpi->x[0] - gpj->x[0], // x + gpi->x[1] - gpj->x[1], // y + gpi->x[2] - gpj->x[2]}; // z const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; /* Interact ! */ - runner_iact_grav_pp(r2, dx, gpi, gpj); + if (gpi->ti_end <= ti_current && gpj->ti_end <= ti_current) { + + runner_iact_grav_pp(r2, dx, gpi, gpj); + + } else { + + if (gpi->ti_end <= ti_current) { + + runner_iact_grav_pp_nonsym(r2, dx, gpi, gpj); + + } else if (gpj->ti_end <= ti_current) { + + dx[0] = -dx[0]; + dx[1] = -dx[1]; + dx[2] = -dx[2]; + runner_iact_grav_pp_nonsym(r2, dx, gpj, gpi); + } + } } } @@ -240,10 +255,10 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( struct runner *r, struct cell *c) { - // const struct engine *e = r->e; + const struct engine *e = r->e; const int gcount = c->gcount; struct gpart *restrict gparts = c->gparts; - // const int ti_current = e->ti_current; + const int ti_current = e->ti_current; TIMER_TIC; @@ -252,8 +267,8 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( error("Empty cell !"); #endif -/* Anything to do here? */ -// if (c->ti_end_min > ti_current) return; + /* Anything to do here? */ + if (c->ti_end_min > ti_current) return; #if ICHECK > 0 for (int pid = 0; pid < gcount; pid++) { @@ -280,13 +295,30 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( struct gpart *restrict gpj = &gparts[pjd]; /* Compute the pairwise distance. */ - const float dx[3] = {gpi->x[0] - gpj->x[0], // x - gpi->x[1] - gpj->x[1], // y - gpi->x[2] - gpj->x[2]}; // z + float dx[3] = {gpi->x[0] - gpj->x[0], // x + gpi->x[1] - gpj->x[1], // y + gpi->x[2] - gpj->x[2]}; // z const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; /* Interact ! */ - runner_iact_grav_pp(r2, dx, gpi, gpj); + if (gpi->ti_end <= ti_current && gpj->ti_end <= ti_current) { + + runner_iact_grav_pp(r2, dx, gpi, gpj); + + } else { + + if (gpi->ti_end <= ti_current) { + + runner_iact_grav_pp_nonsym(r2, dx, gpi, gpj); + + } else if (gpj->ti_end <= ti_current) { + + dx[0] = -dx[0]; + dx[1] = -dx[1]; + dx[2] = -dx[2]; + runner_iact_grav_pp_nonsym(r2, dx, gpj, gpi); + } + } } } -- GitLab From b11b3ea62fb71e51be5a17ba31c2668a45c0d0e4 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 9 Jun 2016 12:03:37 +0200 Subject: [PATCH 38/72] Softened gravity in the interactions --- src/gravity/Default/gravity_iact.h | 90 ++++++++++++++++++++++++------ src/tools.c | 14 +---- 2 files changed, 74 insertions(+), 30 deletions(-) diff --git a/src/gravity/Default/gravity_iact.h b/src/gravity/Default/gravity_iact.h index 671ca6a34..a579127dc 100644 --- a/src/gravity/Default/gravity_iact.h +++ b/src/gravity/Default/gravity_iact.h @@ -33,40 +33,96 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp( float r2, const float *dx, struct gpart *gpi, struct gpart *gpj) { /* Apply the gravitational acceleration. */ - const float ir = 1.0f / sqrtf(r2); - const float w = ir * ir * ir; - const float wdx[3] = {w * dx[0], w * dx[1], w * dx[2]}; + const float r = sqrtf(r2); + const float ir = 1.f / r; const float mi = gpi->mass; const float mj = gpj->mass; - - gpi->a_grav[0] -= wdx[0] * mj; - gpi->a_grav[1] -= wdx[1] * mj; - gpi->a_grav[2] -= wdx[2] * mj; + const float hi = gpi->epsilon; + const float hi_inv = 1.f / hi; + const float hi_inv3 = hi_inv * hi_inv * hi_inv; + const float hj = gpj->epsilon; + const float hj_inv = 1.f / hj; + const float hj_inv3 = hj_inv * hj_inv * hj_inv; + const float ui = r * hi_inv; + const float uj = r * hj_inv; + float fi, fj, W; + + if(r >= hi) { + + /* Get Newtonian graavity */ + fi = mj * ir * ir * ir; + + } else { + + /* Get softened gravity */ + kernel_grav_eval(ui, &W); + fi = mj * hi_inv3 * W; + } + + if(r >= hj) { + + /* Get Newtonian graavity */ + fj = mi * ir * ir * ir; + + } else { + + /* Get softened gravity */ + kernel_grav_eval(uj, &W); + fj = mi * hj_inv3 * W; + } + + + const float fidx[3] = {fi * dx[0], fi * dx[1], fi * dx[2]}; + gpi->a_grav[0] -= fidx[0]; + gpi->a_grav[1] -= fidx[1]; + gpi->a_grav[2] -= fidx[2]; gpi->mass_interacted += mj; - gpj->a_grav[0] += wdx[0] * mi; - gpj->a_grav[1] += wdx[1] * mi; - gpj->a_grav[2] += wdx[2] * mi; + const float fjdx[3] = {fj * dx[0], fj * dx[1], fj * dx[2]}; + gpj->a_grav[0] += fjdx[0]; + gpj->a_grav[1] += fjdx[1]; + gpj->a_grav[2] += fjdx[2]; gpj->mass_interacted += mi; } +/** + * @brief Gravity forces between particles (non-symmetric version) + */ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp_nonsym( float r2, const float *dx, struct gpart *gpi, const struct gpart *gpj) { /* Apply the gravitational acceleration. */ - const float ir = 1.0f / sqrtf(r2); - const float w = ir * ir * ir; - const float wdx[3] = {w * dx[0], w * dx[1], w * dx[2]}; + const float r = sqrtf(r2); + const float ir = 1.f / r; const float mj = gpj->mass; + const float hi = gpi->epsilon; + const float hi_inv = 1.f / hi; + const float hi_inv3 = hi_inv * hi_inv * hi_inv; + const float ui = r * hi_inv; + float f, W; - gpi->a_grav[0] -= wdx[0] * mj; - gpi->a_grav[1] -= wdx[1] * mj; - gpi->a_grav[2] -= wdx[2] * mj; + if (r >= hi) { + + /* Get Newtonian graavity */ + f = mj * ir * ir * ir; + + } else { + + /* Get softened gravity */ + kernel_grav_eval(ui, &W); + f = mj * hi_inv3 * W; + } + + const float fdx[3] = {f * dx[0], f * dx[1], f * dx[2]}; + + gpi->a_grav[0] -= fdx[0]; + gpi->a_grav[1] -= fdx[1]; + gpi->a_grav[2] -= fdx[2]; gpi->mass_interacted += mj; } /** - * @brief Gravity forces between particles + * @brief Gravity forces between particle and multipole */ __attribute__((always_inline)) INLINE static void runner_iact_grav_pm( float r2, const float *dx, struct gpart *gp, diff --git a/src/tools.c b/src/tools.c index 30950381d..3af35051c 100644 --- a/src/tools.c +++ b/src/tools.c @@ -506,13 +506,11 @@ void gravity_n2(struct gpart *gparts, const int gcount, /* Get a hold of the ith part in ci. */ struct gpart *restrict gpi = &gparts[pid]; - const float mi = gpi->mass; for (int pjd = pid + 1; pjd < gcount; pjd++) { /* Get a hold of the jth part in ci. */ struct gpart *restrict gpj = &gparts[pjd]; - const float mj = gpj->mass; /* Compute the pairwise distance. */ const float dx[3] = {gpi->x[0] - gpj->x[0], // x @@ -521,17 +519,7 @@ void gravity_n2(struct gpart *gparts, const int gcount, const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; /* Apply the gravitational acceleration. */ - const float ir = 1.0f / sqrtf(r2); - const float w = ir * ir * ir; - const float wdx[3] = {w * dx[0], w * dx[1], w * dx[2]}; - - gpi->a_grav[0] -= wdx[0] * mj; - gpi->a_grav[1] -= wdx[1] * mj; - gpi->a_grav[2] -= wdx[2] * mj; - - gpj->a_grav[0] += wdx[0] * mi; - gpj->a_grav[1] += wdx[1] * mi; - gpj->a_grav[2] += wdx[2] * mi; + runner_iact_grav_pp(r2, dx, gpi, gpj); } } -- GitLab From 40d813edb588bfbac321802e735ec70b10f5cce0 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 9 Jun 2016 12:06:13 +0200 Subject: [PATCH 39/72] Softened gravity in the interactions --- src/gravity/Default/gravity.h | 4 +++- src/gravity/Default/gravity_iact.h | 17 ++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h index f8365e54d..7349ad8e2 100644 --- a/src/gravity/Default/gravity.h +++ b/src/gravity/Default/gravity.h @@ -76,7 +76,9 @@ gravity_compute_timestep_self(const struct phys_const* const phys_const, * @param gp The particle to act upon */ __attribute__((always_inline)) INLINE static void gravity_first_init_gpart( - struct gpart* gp) {} + struct gpart* gp) { + gp->epsilon = 0.1; // MATTHIEU +} /** * @brief Prepares a g-particle for the gravity calculation diff --git a/src/gravity/Default/gravity_iact.h b/src/gravity/Default/gravity_iact.h index a579127dc..d0624ab2b 100644 --- a/src/gravity/Default/gravity_iact.h +++ b/src/gravity/Default/gravity_iact.h @@ -47,31 +47,30 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp( const float uj = r * hj_inv; float fi, fj, W; - if(r >= hi) { - + if (r >= hi) { + /* Get Newtonian graavity */ fi = mj * ir * ir * ir; - + } else { - + /* Get softened gravity */ kernel_grav_eval(ui, &W); fi = mj * hi_inv3 * W; } - if(r >= hj) { - + if (r >= hj) { + /* Get Newtonian graavity */ fj = mi * ir * ir * ir; - + } else { - + /* Get softened gravity */ kernel_grav_eval(uj, &W); fj = mi * hj_inv3 * W; } - const float fidx[3] = {fi * dx[0], fi * dx[1], fi * dx[2]}; gpi->a_grav[0] -= fidx[0]; gpi->a_grav[1] -= fidx[1]; -- GitLab From a59561b94349740abc5965f217973f19defe776b Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 9 Jun 2016 12:21:24 +0200 Subject: [PATCH 40/72] Merged master changes --- src/engine.c | 4 +-- src/runner.c | 64 ++++++++++++---------------------------- src/runner.h | 2 +- src/runner_doiact.h | 14 ++++----- src/runner_doiact_grav.h | 14 ++++----- 5 files changed, 34 insertions(+), 64 deletions(-) diff --git a/src/engine.c b/src/engine.c index 67e6e4553..2c5700b4c 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2186,8 +2186,6 @@ void engine_init_particles(struct engine *e) { if (e->nodeID == 0) message("Initialising particles"); - engine_prepare(e); - /* Make sure all particles are ready to go */ /* i.e. clean-up any stupid state in the ICs */ if (e->policy & engine_policy_hydro) { @@ -2198,6 +2196,8 @@ void engine_init_particles(struct engine *e) { space_map_cells_pre(s, 0, cell_init_gparts, NULL); } + engine_prepare(e); + engine_marktasks(e); /* Build the masks corresponding to the policy */ diff --git a/src/runner.c b/src/runner.c index e88f4ec1e..772e0478c 100644 --- a/src/runner.c +++ b/src/runner.c @@ -57,46 +57,20 @@ #include "timestep.h" /* Orientation of the cell pairs */ -const float runner_shift[13 * 3] = { - 5.773502691896258e-01, - 5.773502691896258e-01, - 5.773502691896258e-01, - 7.071067811865475e-01, - 7.071067811865475e-01, - 0.0, - 5.773502691896258e-01, - 5.773502691896258e-01, - -5.773502691896258e-01, - 7.071067811865475e-01, - 0.0, - 7.071067811865475e-01, - 1.0, - 0.0, - 0.0, - 7.071067811865475e-01, - 0.0, - -7.071067811865475e-01, - 5.773502691896258e-01, - -5.773502691896258e-01, - 5.773502691896258e-01, - 7.071067811865475e-01, - -7.071067811865475e-01, - 0.0, - 5.773502691896258e-01, - -5.773502691896258e-01, - -5.773502691896258e-01, - 0.0, - 7.071067811865475e-01, - 7.071067811865475e-01, - 0.0, - 1.0, - 0.0, - 0.0, - 7.071067811865475e-01, - -7.071067811865475e-01, - 0.0, - 0.0, - 1.0, +const double runner_shift[13][3] = { + {5.773502691896258e-01, 5.773502691896258e-01, 5.773502691896258e-01}, + {7.071067811865475e-01, 7.071067811865475e-01, 0.0}, + {5.773502691896258e-01, 5.773502691896258e-01, -5.773502691896258e-01}, + {7.071067811865475e-01, 0.0, 7.071067811865475e-01}, + {1.0, 0.0, 0.0}, + {7.071067811865475e-01, 0.0, -7.071067811865475e-01}, + {5.773502691896258e-01, -5.773502691896258e-01, 5.773502691896258e-01}, + {7.071067811865475e-01, -7.071067811865475e-01, 0.0}, + {5.773502691896258e-01, -5.773502691896258e-01, -5.773502691896258e-01}, + {0.0, 7.071067811865475e-01, 7.071067811865475e-01}, + {0.0, 1.0, 0.0}, + {0.0, 7.071067811865475e-01, -7.071067811865475e-01}, + {0.0, 0.0, 1.0}, }; /* Does the axis need flipping ? */ @@ -256,8 +230,8 @@ void runner_do_sort(struct runner *r, struct cell *c, int flags, int clock) { struct entry *sort; int j, k, count = c->count; int i, ind, off[8], inds[8], temp_i, missing; - // float shift[3]; - float buff[8], px[3]; + float buff[8]; + double px[3]; TIMER_TIC @@ -361,9 +335,9 @@ void runner_do_sort(struct runner *r, struct cell *c, int flags, int clock) { for (j = 0; j < 13; j++) if (flags & (1 << j)) { sort[j * (count + 1) + k].i = k; - sort[j * (count + 1) + k].d = px[0] * runner_shift[3 * j + 0] + - px[1] * runner_shift[3 * j + 1] + - px[2] * runner_shift[3 * j + 2]; + sort[j * (count + 1) + k].d = px[0] * runner_shift[j][0] + + px[1] * runner_shift[j][1] + + px[2] * runner_shift[j][2]; } } diff --git a/src/runner.h b/src/runner.h index 35e5f56a7..758b6cf57 100644 --- a/src/runner.h +++ b/src/runner.h @@ -27,7 +27,7 @@ #include "cell.h" #include "inline.h" -extern const float runner_shift[13 * 3]; +extern const double runner_shift[13][3]; extern const char runner_flip[27]; /* A struct representing a runner's thread and its data. */ diff --git a/src/runner_doiact.h b/src/runner_doiact.h index 97e22138b..e0c13e4e0 100644 --- a/src/runner_doiact.h +++ b/src/runner_doiact.h @@ -376,9 +376,8 @@ void DOPAIR_SUBSET(struct runner *r, struct cell *restrict ci, for (k = 0; k < 3; k++) pix[k] = pi->x[k] - shift[k]; hi = pi->h; hig2 = hi * hi * kernel_gamma2; - di = hi * kernel_gamma + dxj + pix[0] * runner_shift[3 * sid + 0] + - pix[1] * runner_shift[3 * sid + 1] + - pix[2] * runner_shift[3 * sid + 2]; + di = hi * kernel_gamma + dxj + pix[0] * runner_shift[sid][0] + + pix[1] * runner_shift[sid][1] + pix[2] * runner_shift[sid][2]; /* Loop over the parts in cj. */ for (pjd = 0; pjd < count_j && sort_j[pjd].d < di; pjd++) { @@ -439,9 +438,8 @@ void DOPAIR_SUBSET(struct runner *r, struct cell *restrict ci, for (k = 0; k < 3; k++) pix[k] = pi->x[k] - shift[k]; hi = pi->h; hig2 = hi * hi * kernel_gamma2; - di = -hi * kernel_gamma - dxj + pix[0] * runner_shift[3 * sid + 0] + - pix[1] * runner_shift[3 * sid + 1] + - pix[2] * runner_shift[3 * sid + 2]; + di = -hi * kernel_gamma - dxj + pix[0] * runner_shift[sid][0] + + pix[1] * runner_shift[sid][1] + pix[2] * runner_shift[sid][2]; /* Loop over the parts in cj. */ for (pjd = count_j - 1; pjd >= 0 && di < sort_j[pjd].d; pjd--) { @@ -758,7 +756,7 @@ void DOPAIR1(struct runner *r, struct cell *ci, struct cell *cj) { /* Get the cutoff shift. */ for (rshift = 0.0, k = 0; k < 3; k++) - rshift += shift[k] * runner_shift[3 * sid + k]; + rshift += shift[k] * runner_shift[sid][k]; /* Pick-out the sorted lists. */ sort_i = &ci->sort[sid * (ci->count + 1)]; @@ -952,7 +950,7 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) { /* Get the cutoff shift. */ for (rshift = 0.0, k = 0; k < 3; k++) - rshift += shift[k] * runner_shift[3 * sid + k]; + rshift += shift[k] * runner_shift[sid][k]; /* Pick-out the sorted lists. */ sort_i = &ci->sort[sid * (ci->count + 1)]; diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 81529eea3..2dcb62cba 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -51,10 +51,9 @@ void runner_do_grav_up(struct runner *r, struct cell *c) { } else { /* Leaf node. */ - /* Just construct the multipole from the gparts. */ - multipole_init(&c->multipole, c->gparts, c->gcount); - } -} + /* Make sure the cells are sorted. */ + runner_do_gsort(r, ci, (1 << sid), 0); + runner_do_gsort(r, cj, (1 << sid), 0); /** * @brief Checks whether the cells are direct neighbours ot not. Both cells have @@ -68,10 +67,9 @@ void runner_do_grav_up(struct runner *r, struct cell *c) { __attribute__((always_inline)) INLINE static int are_neighbours( const struct cell *restrict ci, const struct cell *restrict cj) { -#ifdef SANITY_CHECKS - if (ci->h[0] != cj->h[0]) - error(" Cells of different size in distance calculation."); -#endif + /* Get the cutoff shift. */ + for (rshift = 0.0, k = 0; k < 3; k++) + rshift += shift[k] * runner_shift[3 * sid + k]; /* Maximum allowed distance */ const double min_dist = 1.2 * ci->h[0]; /* 1.2 accounts for rounding errors */ -- GitLab From 5497fe79434caec1d4041e3e738d6c084049f771 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 9 Jun 2016 12:22:05 +0200 Subject: [PATCH 41/72] Post-merge fixes --- src/runner_doiact_grav.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 2dcb62cba..86bb47ae6 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -50,10 +50,10 @@ void runner_do_grav_up(struct runner *r, struct cell *c) { } } else { /* Leaf node. */ - - /* Make sure the cells are sorted. */ - runner_do_gsort(r, ci, (1 << sid), 0); - runner_do_gsort(r, cj, (1 << sid), 0); + /* Just construct the multipole from the gparts. */ + multipole_init(&c->multipole, c->gparts, c->gcount); + } +} /** * @brief Checks whether the cells are direct neighbours ot not. Both cells have @@ -67,10 +67,6 @@ void runner_do_grav_up(struct runner *r, struct cell *c) { __attribute__((always_inline)) INLINE static int are_neighbours( const struct cell *restrict ci, const struct cell *restrict cj) { - /* Get the cutoff shift. */ - for (rshift = 0.0, k = 0; k < 3; k++) - rshift += shift[k] * runner_shift[3 * sid + k]; - /* Maximum allowed distance */ const double min_dist = 1.2 * ci->h[0]; /* 1.2 accounts for rounding errors */ -- GitLab From 6b6c7c841bc7a607280bfc079b26a4749759913e Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sun, 12 Jun 2016 19:21:42 +0200 Subject: [PATCH 42/72] Use definition of atomics everywhere in cell.c --- src/cell.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cell.c b/src/cell.c index f301e9dc5..ba08fc1fd 100644 --- a/src/cell.c +++ b/src/cell.c @@ -269,7 +269,7 @@ int cell_locktree(struct cell *c) { /* Undo the holds up to finger. */ for (struct cell *finger2 = c->parent; finger2 != finger; finger2 = finger2->parent) - __sync_fetch_and_sub(&finger2->hold, 1); + atomic_dec(&finger2->hold); /* Unlock this cell. */ if (lock_unlock(&c->lock) != 0) error("Failed to unlock cell."); @@ -309,7 +309,7 @@ int cell_glocktree(struct cell *c) { if (lock_trylock(&finger->glock) != 0) break; /* Increment the hold. */ - __sync_fetch_and_add(&finger->ghold, 1); + atomic_inc(&finger->ghold); /* Unlock the cell. */ if (lock_unlock(&finger->glock) != 0) error("Failed to unlock cell."); @@ -327,7 +327,7 @@ int cell_glocktree(struct cell *c) { /* Undo the holds up to finger. */ for (struct cell *finger2 = c->parent; finger2 != finger; finger2 = finger2->parent) - __sync_fetch_and_sub(&finger2->ghold, 1); + atomic_dec(&finger2->ghold); /* Unlock this cell. */ if (lock_unlock(&c->glock) != 0) error("Failed to unlock cell."); @@ -353,7 +353,7 @@ void cell_unlocktree(struct cell *c) { /* Climb up the tree and unhold the parents. */ for (struct cell *finger = c->parent; finger != NULL; finger = finger->parent) - __sync_fetch_and_sub(&finger->hold, 1); + atomic_dec(&finger->hold); TIMER_TOC(timer_locktree); } @@ -367,7 +367,7 @@ void cell_gunlocktree(struct cell *c) { /* Climb up the tree and unhold the parents. */ for (struct cell *finger = c->parent; finger != NULL; finger = finger->parent) - __sync_fetch_and_sub(&finger->ghold, 1); + atomic_dec(&finger->ghold); TIMER_TOC(timer_locktree); } -- GitLab From 487a1f08b7b48d69e8f414414f61a9ac2bd5adad Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sun, 12 Jun 2016 19:28:03 +0200 Subject: [PATCH 43/72] Use atomic definitions --- src/map.c | 13 +++++++++++-- src/queue.c | 7 ------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/map.c b/src/map.c index fbe57fde7..cb911c36f 100644 --- a/src/map.c +++ b/src/map.c @@ -18,9 +18,18 @@ * ******************************************************************************/ -#include "map.h" +/* Config parameters. */ +#include "../config.h" + +/* Some standard headers. */ #include #include + +/* This object's header. */ +#include "map.h" + +/* Local headers. */ +#include "atomic.h" #include "error.h" /** @@ -97,7 +106,7 @@ void map_cells_plot(struct cell *c, void *data) { void map_cellcheck(struct cell *c, void *data) { int *count = (int *)data; - __sync_fetch_and_add(count, c->count); + atomic_add(count, c->count); /* Loop over all parts and check if they are in the cell. */ for (int k = 0; k < c->count; k++) { diff --git a/src/queue.c b/src/queue.c index a62ded256..57aa5701d 100644 --- a/src/queue.c +++ b/src/queue.c @@ -38,13 +38,6 @@ #include "const.h" #include "error.h" -/* Counter macros. */ -#ifdef COUNTER -#define COUNT(c) (__sync_add_and_fetch(&queue_counter[c], 1)) -#else -#define COUNT(c) -#endif - /* The counters. */ int queue_counter[queue_counter_count]; -- GitLab From 111fdbf920aaf41757924a5eba23f5befb838db8 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sun, 12 Jun 2016 19:53:41 +0200 Subject: [PATCH 44/72] Set the locking and unlocking of cells for gravity tasks --- src/task.c | 177 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 121 insertions(+), 56 deletions(-) diff --git a/src/task.c b/src/task.c index 07218d903..8b0f0de8a 100644 --- a/src/task.c +++ b/src/task.c @@ -58,7 +58,6 @@ const char *subtaskID_names[task_type_count] = {"none", "density", "force", /** * @brief Computes the overlap between the parts array of two given cells. */ - size_t task_cell_overlap(const struct cell *ci, const struct cell *cj) { if (ci == NULL || cj == NULL) return 0; if (ci->parts <= cj->parts && @@ -78,7 +77,6 @@ size_t task_cell_overlap(const struct cell *ci, const struct cell *cj) { * @param ta The first #task. * @param tb The second #task. */ - float task_overlap(const struct task *ta, const struct task *tb) { /* First check if any of the two tasks are of a type that don't use cells. */ @@ -110,25 +108,50 @@ float task_overlap(const struct task *ta, const struct task *tb) { * * @param t The #task. */ - void task_unlock(struct task *t) { + const int type = t->type; + const int subtype = t->subtype; + struct cell *ci = t->ci, *cj = t->cj; + /* Act based on task type. */ - switch (t->type) { - case task_type_self: + switch (type) { + case task_type_sort: - cell_unlocktree(t->ci); + cell_unlocktree(ci); + break; + + case task_type_self: + if (subtype == task_subtype_grav) { + cell_gunlocktree(ci); + } else { + cell_unlocktree(ci); + } break; + case task_type_pair: + if (subtype == task_subtype_grav) { + cell_gunlocktree(ci); + cell_gunlocktree(cj); + } else { + cell_unlocktree(ci); + cell_unlocktree(cj); + } + break; + case task_type_sub: - cell_unlocktree(t->ci); - if (t->cj != NULL) cell_unlocktree(t->cj); + if (subtype == task_subtype_grav) { + cell_gunlocktree(ci); + if (cj != NULL) cell_gunlocktree(cj); + } else { + cell_unlocktree(ci); + if (cj != NULL) cell_unlocktree(cj); + } break; - // case task_type_grav_pp: + case task_type_grav_mm: - // case task_type_grav_down: - cell_gunlocktree(t->ci); - if (t->cj != NULL) cell_gunlocktree(t->cj); + cell_gunlocktree(ci); + cell_gunlocktree(cj); break; default: break; @@ -140,58 +163,104 @@ void task_unlock(struct task *t) { * * @param t the #task. */ - int task_lock(struct task *t) { - int type = t->type; + const int type = t->type; + const int subtype = t->subtype; struct cell *ci = t->ci, *cj = t->cj; +#ifdef WITH_MPI + int res = 0, err = 0; + MPI_Status stat; +#endif - /* Communication task? */ - if (type == task_type_recv || type == task_type_send) { + switch (type) { + /* Communication task? */ + case task_type_recv: + case task_type_send: #ifdef WITH_MPI - /* Check the status of the MPI request. */ - int res = 0, err = 0; - MPI_Status stat; - if ((err = MPI_Test(&t->req, &res, &stat)) != MPI_SUCCESS) { - char buff[MPI_MAX_ERROR_STRING]; - int len; - MPI_Error_string(err, buff, &len); - error("Failed to test request on send/recv task (tag=%i, %s).", t->flags, - buff); - } - return res; + /* Check the status of the MPI request. */ + if ((err = MPI_Test(&t->req, &res, &stat)) != MPI_SUCCESS) { + char buff[MPI_MAX_ERROR_STRING]; + int len; + MPI_Error_string(err, buff, &len); + error("Failed to test request on send/recv task (tag=%i, %s).", + t->flags, buff); + } + return res; #else - error("SWIFT was not compiled with MPI support."); + error("SWIFT was not compiled with MPI support."); #endif + break; - } + case task_type_sort: + if (cell_locktree(ci) != 0) return 0; + break; - /* Unary lock? */ - else if (type == task_type_self || type == task_type_sort || - (type == task_type_sub && cj == NULL)) { - if (cell_locktree(ci) != 0) return 0; - } + case task_type_self: + if (subtype == task_subtype_grav) { + if (cell_glocktree(ci) != 0) return 0; + } else { + if (cell_locktree(ci) != 0) return 0; + } + break; - /* Otherwise, binary lock. */ - else if (type == task_type_pair || (type == task_type_sub && cj != NULL)) { - if (ci->hold || cj->hold) return 0; - if (cell_locktree(ci) != 0) return 0; - if (cell_locktree(cj) != 0) { - cell_unlocktree(ci); - return 0; - } - } + case task_type_pair: + if (subtype == task_subtype_grav) { + if (ci->ghold || cj->ghold) return 0; + if (cell_glocktree(ci) != 0) return 0; + if (cell_glocktree(cj) != 0) { + cell_gunlocktree(ci); + return 0; + } + } else { + if (ci->hold || cj->hold) return 0; + if (cell_locktree(ci) != 0) return 0; + if (cell_locktree(cj) != 0) { + cell_unlocktree(ci); + return 0; + } + } + break; - /* Gravity tasks? */ - else if (type == task_type_grav_mm) { - //|| type == task_type_grav_pp || type == task_type_grav_down) { - if (ci->ghold || (cj != NULL && cj->ghold)) return 0; - if (cell_glocktree(ci) != 0) return 0; - if (cj != NULL && cell_glocktree(cj) != 0) { - cell_gunlocktree(ci); - return 0; - } + case task_type_sub: + if (cj == NULL) { /* sub-self */ + + if (subtype == task_subtype_grav) { + if (cell_glocktree(ci) != 0) return 0; + } else { + if (cell_locktree(ci) != 0) return 0; + } + + } else { /* Sub-pair */ + if (subtype == task_subtype_grav) { + if (ci->ghold || cj->ghold) return 0; + if (cell_glocktree(ci) != 0) return 0; + if (cell_glocktree(cj) != 0) { + cell_gunlocktree(ci); + return 0; + } + } else { + if (ci->hold || cj->hold) return 0; + if (cell_locktree(ci) != 0) return 0; + if (cell_locktree(cj) != 0) { + cell_unlocktree(ci); + return 0; + } + } + } + break; + + case task_type_grav_mm: + if (ci->ghold || cj->ghold) return 0; + if (cell_glocktree(ci) != 0) return 0; + if (cell_glocktree(cj) != 0) { + cell_gunlocktree(ci); + return 0; + } + + default: + break; } /* If we made it this far, we've got a lock. */ @@ -204,7 +273,6 @@ int task_lock(struct task *t) { * @param t The #task. * @param type The task type ID to remove. */ - void task_cleanunlock(struct task *t, int type) { int k; @@ -226,7 +294,6 @@ void task_cleanunlock(struct task *t, int type) { * @param ta The unlocking #task. * @param tb The #task that will be unlocked. */ - void task_rmunlock(struct task *ta, struct task *tb) { int k; @@ -252,7 +319,6 @@ void task_rmunlock(struct task *ta, struct task *tb) { * Differs from #task_rmunlock in that it will not fail if * the task @c tb is not in the unlocks of @c ta. */ - void task_rmunlock_blind(struct task *ta, struct task *tb) { int k; @@ -275,7 +341,6 @@ void task_rmunlock_blind(struct task *ta, struct task *tb) { * @param ta The unlocking #task. * @param tb The #task that will be unlocked. */ - void task_addunlock(struct task *ta, struct task *tb) { error("Use sched_addunlock instead."); -- GitLab From c5197e0804cfe32033ff03baa4adb0fba5db924d Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sun, 12 Jun 2016 20:17:22 +0200 Subject: [PATCH 45/72] Added function to compute long-range FFT correction term --- src/Makefile.am | 4 +-- src/gravity/Default/gravity_iact.h | 7 +++-- src/kernel_gravity.h | 4 +-- src/kernel_long_gravity.h | 50 ++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 src/kernel_long_gravity.h diff --git a/src/Makefile.am b/src/Makefile.am index cd5a47ea8..311c49570 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -47,8 +47,8 @@ AM_SOURCES = space.c runner.c queue.c task.c cell.c engine.c \ # Include files for distribution, not installation. nobase_noinst_HEADERS = approx_math.h atomic.h cycle.h error.h inline.h kernel_hydro.h kernel_gravity.h \ - vector.h runner_doiact.h runner_doiact_grav.h units.h intrinsics.h minmax.h kick.h \ - timestep.h drift.h \ + kernel_long_gravity.h vector.h runner_doiact.h runner_doiact_grav.h units.h intrinsics.h \ + minmax.h kick.h timestep.h drift.h \ gravity.h gravity_io.h \ gravity/Default/gravity.h gravity/Default/gravity_iact.h gravity/Default/gravity_io.h \ gravity/Default/gravity_debug.h gravity/Default/gravity_part.h \ diff --git a/src/gravity/Default/gravity_iact.h b/src/gravity/Default/gravity_iact.h index d0624ab2b..997bff0fb 100644 --- a/src/gravity/Default/gravity_iact.h +++ b/src/gravity/Default/gravity_iact.h @@ -23,6 +23,7 @@ /* Includes. */ #include "const.h" #include "kernel_gravity.h" +#include "kernel_long_gravity.h" #include "multipole.h" #include "vector.h" @@ -49,7 +50,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp( if (r >= hi) { - /* Get Newtonian graavity */ + /* Get Newtonian gravity */ fi = mj * ir * ir * ir; } else { @@ -61,7 +62,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp( if (r >= hj) { - /* Get Newtonian graavity */ + /* Get Newtonian gravity */ fj = mi * ir * ir * ir; } else { @@ -102,7 +103,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp_nonsym( if (r >= hi) { - /* Get Newtonian graavity */ + /* Get Newtonian gravity */ f = mj * ir * ir * ir; } else { diff --git a/src/kernel_gravity.h b/src/kernel_gravity.h index 1e39f9685..b38feb575 100644 --- a/src/kernel_gravity.h +++ b/src/kernel_gravity.h @@ -63,9 +63,9 @@ static const float 0.f}; /* 1 < u */ /** - * @brief Computes the kernel function. + * @brief Computes the gravity softening function. * - * @param u The ratio of the distance to the smoothing length $u = x/h$. + * @param u The ratio of the distance to the softening length $u = x/h$. * @param W (return) The value of the kernel function $W(x,h)$. */ __attribute__((always_inline)) INLINE static void kernel_grav_eval( diff --git a/src/kernel_long_gravity.h b/src/kernel_long_gravity.h new file mode 100644 index 000000000..d247c7a46 --- /dev/null +++ b/src/kernel_long_gravity.h @@ -0,0 +1,50 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + ******************************************************************************/ +#ifndef SWIFT_KERNEL_LONG_GRAVITY_H +#define SWIFT_KERNEL_LONG_GRAVITY_H + +#include + +/* Includes. */ +#include "const.h" +#include "inline.h" +#include "vector.h" + +#define one_over_sqrt_pi ((float)(M_2_SQRTPI * 0.5)) + +/** + * @brief Computes the long-range correction term for the FFT calculation. + * + * @param u The ratio of the distance to the FFT cell scale $u = x/A$. + * @param W (return) The value of the kernel function. + */ +__attribute__((always_inline)) INLINE static void kernel_long_grav_eval( + float u, float *const W) { + + const float arg1 = u * 0.5f; + const float arg2 = u * one_over_sqrt_pi; + const float arg3 = -arg1 * arg1; + + const float term1 = erfc(arg1); + const float term2 = arg2 * expf(arg3); + + *W = term1 + term2; +} + +#endif // SWIFT_KERNEL_LONG_GRAVITY_H -- GitLab From d44155a8bc3cb9c48dcafe22c6a3f0d9aa127e9b Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 13 Jun 2016 00:04:57 +0100 Subject: [PATCH 46/72] Use the long-range smoothing kernel --- src/const.h | 4 +- src/gravity/Default/gravity_iact.h | 66 +++++++++++++++++++----------- src/multipole.c | 24 ++++++----- src/multipole.h | 12 +++--- src/runner_doiact_grav.h | 17 ++++---- src/tools.c | 4 +- 6 files changed, 76 insertions(+), 51 deletions(-) diff --git a/src/const.h b/src/const.h index f7cf61133..ba71e3aeb 100644 --- a/src/const.h +++ b/src/const.h @@ -53,7 +53,9 @@ //#define DEFAULT_SPH /* Self gravity stuff. */ -#define multipole_order 2 +#define const_gravity_multipole_order 2 +#define const_gravity_a_smooth 1.25f +#define const_gravity_r_cut 4.5f #define const_gravity_eta 0.025f /* External gravity properties */ diff --git a/src/gravity/Default/gravity_iact.h b/src/gravity/Default/gravity_iact.h index 997bff0fb..2b3dfc855 100644 --- a/src/gravity/Default/gravity_iact.h +++ b/src/gravity/Default/gravity_iact.h @@ -31,7 +31,8 @@ * @brief Gravity forces between particles */ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp( - float r2, const float *dx, struct gpart *gpi, struct gpart *gpj) { + float rlr_inv, float r2, const float *dx, struct gpart *gpi, + struct gpart *gpj) { /* Apply the gravitational acceleration. */ const float r = sqrtf(r2); @@ -39,37 +40,45 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp( const float mi = gpi->mass; const float mj = gpj->mass; const float hi = gpi->epsilon; - const float hi_inv = 1.f / hi; - const float hi_inv3 = hi_inv * hi_inv * hi_inv; const float hj = gpj->epsilon; - const float hj_inv = 1.f / hj; - const float hj_inv3 = hj_inv * hj_inv * hj_inv; - const float ui = r * hi_inv; - const float uj = r * hj_inv; - float fi, fj, W; + const float u = r * rlr_inv; + float f_lr, fi, fj, W; + + /* Get long-range correction */ + kernel_long_grav_eval(u, &f_lr); if (r >= hi) { /* Get Newtonian gravity */ - fi = mj * ir * ir * ir; + fi = mj * ir * ir * ir * f_lr; } else { - /* Get softened gravity */ + const float hi_inv = 1.f / hi; + const float hi_inv3 = hi_inv * hi_inv * hi_inv; + const float ui = r * hi_inv; + kernel_grav_eval(ui, &W); - fi = mj * hi_inv3 * W; + + /* Get softened gravity */ + fi = mj * hi_inv3 * W * f_lr; } if (r >= hj) { /* Get Newtonian gravity */ - fj = mi * ir * ir * ir; + fj = mi * ir * ir * ir * f_lr; } else { - /* Get softened gravity */ + const float hj_inv = 1.f / hj; + const float hj_inv3 = hj_inv * hj_inv * hj_inv; + const float uj = r * hj_inv; + kernel_grav_eval(uj, &W); - fj = mi * hj_inv3 * W; + + /* Get softened gravity */ + fj = mi * hj_inv3 * W * f_lr; } const float fidx[3] = {fi * dx[0], fi * dx[1], fi * dx[2]}; @@ -89,28 +98,35 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp( * @brief Gravity forces between particles (non-symmetric version) */ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp_nonsym( - float r2, const float *dx, struct gpart *gpi, const struct gpart *gpj) { + float rlr_inv, float r2, const float *dx, struct gpart *gpi, + const struct gpart *gpj) { /* Apply the gravitational acceleration. */ const float r = sqrtf(r2); const float ir = 1.f / r; const float mj = gpj->mass; const float hi = gpi->epsilon; - const float hi_inv = 1.f / hi; - const float hi_inv3 = hi_inv * hi_inv * hi_inv; - const float ui = r * hi_inv; - float f, W; + const float u = r * rlr_inv; + float f_lr, f, W; + + /* Get long-range correction */ + kernel_long_grav_eval(u, &f_lr); if (r >= hi) { /* Get Newtonian gravity */ - f = mj * ir * ir * ir; + f = mj * ir * ir * ir * f_lr; } else { - /* Get softened gravity */ + const float hi_inv = 1.f / hi; + const float hi_inv3 = hi_inv * hi_inv * hi_inv; + const float ui = r * hi_inv; + kernel_grav_eval(ui, &W); - f = mj * hi_inv3 * W; + + /* Get softened gravity */ + f = mj * hi_inv3 * W * f_lr; } const float fdx[3] = {f * dx[0], f * dx[1], f * dx[2]}; @@ -125,7 +141,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp_nonsym( * @brief Gravity forces between particle and multipole */ __attribute__((always_inline)) INLINE static void runner_iact_grav_pm( - float r2, const float *dx, struct gpart *gp, + float rlr_inv, float r2, const float *dx, struct gpart *gp, const struct multipole *multi) { /* Apply the gravitational acceleration. */ @@ -133,7 +149,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pm( const float ir = 1.f / r; const float mrinv3 = multi->mass * ir * ir * ir; -#if multipole_order < 2 +#if const_gravity_multipole_order < 2 /* 0th and 1st order terms */ gp->a_grav[0] += mrinv3 * dx[0]; @@ -141,7 +157,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pm( gp->a_grav[2] += mrinv3 * dx[2]; gp->mass_interacted += multi->mass; -#elif multipole_order == 2 +#elif const_gravity_multipole_order == 2 /* Terms up to 2nd order (quadrupole) */ /* Follows the notation in Bonsai */ diff --git a/src/multipole.c b/src/multipole.c index dcd4f120d..f0d0c7084 100644 --- a/src/multipole.c +++ b/src/multipole.c @@ -48,7 +48,7 @@ void multipole_reset(struct multipole *m) { void multipole_init(struct multipole *m, const struct gpart *gparts, int gcount) { -#if multipole_order > 2 +#if const_gravity_multipole_order > 2 #error "Multipoles of order >2 not yet implemented." #endif @@ -59,7 +59,7 @@ void multipole_init(struct multipole *m, const struct gpart *gparts, double mass = 0.0; double com[3] = {0.0, 0.0, 0.0}; -#if multipole_order >= 2 +#if const_gravity_multipole_order >= 2 double I_xx = 0.0, I_yy = 0.0, I_zz = 0.0; double I_xy = 0.0, I_xz = 0.0, I_yz = 0.0; #endif @@ -73,7 +73,7 @@ void multipole_init(struct multipole *m, const struct gpart *gparts, com[1] += gparts[k].x[1] * w; com[2] += gparts[k].x[2] * w; -#if multipole_order >= 2 +#if const_gravity_multipole_order >= 2 I_xx += gparts[k].x[0] * gparts[k].x[0] * w; I_yy += gparts[k].x[1] * gparts[k].x[1] * w; I_zz += gparts[k].x[2] * gparts[k].x[2] * w; @@ -91,7 +91,7 @@ void multipole_init(struct multipole *m, const struct gpart *gparts, m->CoM[1] = com[1] * imass; m->CoM[2] = com[2] * imass; -#if multipole_order >= 2 +#if const_gravity_multipole_order >= 2 m->I_xx = I_xx - imass * com[0] * com[0]; m->I_yy = I_yy - imass * com[1] * com[1]; m->I_zz = I_zz - imass * com[2] * com[2]; @@ -110,7 +110,7 @@ void multipole_init(struct multipole *m, const struct gpart *gparts, void multipole_add(struct multipole *ma, const struct multipole *mb) { -#if multipole_order > 2 +#if const_gravity_multipole_order > 2 #error "Multipoles of order >2 not yet implemented." #endif @@ -123,7 +123,7 @@ void multipole_add(struct multipole *ma, const struct multipole *mb) { const double ma_CoM[3] = {ma->CoM[0], ma->CoM[1], ma->CoM[2]}; const double mb_CoM[3] = {mb->CoM[0], mb->CoM[1], mb->CoM[2]}; -#if multipole_order >= 2 +#if const_gravity_multipole_order >= 2 const double ma_I_xx = (double)ma->I_xx + ma_mass * ma_CoM[0] * ma_CoM[0]; const double ma_I_yy = (double)ma->I_yy + ma_mass * ma_CoM[1] * ma_CoM[1]; const double ma_I_zz = (double)ma->I_zz + ma_mass * ma_CoM[2] * ma_CoM[2]; @@ -148,7 +148,7 @@ void multipole_add(struct multipole *ma, const struct multipole *mb) { ma->CoM[2] = (ma_CoM[2] * ma_mass + mb_CoM[2] * mb_mass) * M_tot_inv; /* New quadrupole */ -#if multipole_order >= 2 +#if const_gravity_multipole_order >= 2 ma->I_xx = (ma_I_xx + mb_I_xx) - M_tot * ma->CoM[0] * ma->CoM[0]; ma->I_yy = (ma_I_yy + mb_I_yy) - M_tot * ma->CoM[1] * ma->CoM[1]; ma->I_zz = (ma_I_zz + mb_I_zz) - M_tot * ma->CoM[2] * ma->CoM[2]; @@ -167,7 +167,7 @@ void multipole_add(struct multipole *ma, const struct multipole *mb) { void multipole_addpart(struct multipole *m, struct gpart *p) { - /* #if multipole_order == 1 */ + /* #if const_gravity_multipole_order == 1 */ /* /\* Correct the position. *\/ */ /* float mm = m->coeffs[0], mp = p->mass; */ @@ -179,7 +179,8 @@ void multipole_addpart(struct multipole *m, struct gpart *p) { /* m->coeffs[0] = mm + mp; */ /* #else */ - /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + /* #error( "Multipoles of order %i not yet implemented." , + * const_gravity_multipole_order ) */ /* #endif */ } @@ -194,7 +195,7 @@ void multipole_addpart(struct multipole *m, struct gpart *p) { void multipole_addparts(struct multipole *m, struct gpart *p, int N) { - /* #if multipole_order == 1 */ + /* #if const_gravity_multipole_order == 1 */ /* /\* Get the combined mass and positions. *\/ */ /* double xp[3] = {0.0, 0.0, 0.0}; */ @@ -216,7 +217,8 @@ void multipole_addparts(struct multipole *m, struct gpart *p, int N) { /* m->coeffs[0] = mm + mp; */ /* #else */ - /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + /* #error( "Multipoles of order %i not yet implemented." , + * const_gravity_multipole_order ) */ /* #endif */ } diff --git a/src/multipole.h b/src/multipole.h index e9fa348b3..dc1f914dd 100644 --- a/src/multipole.h +++ b/src/multipole.h @@ -38,7 +38,7 @@ struct multipole { /* Multipole mass */ float mass; -#if multipole_order >= 2 +#if const_gravity_multipole_order >= 2 /* Quadrupole terms */ float I_xx, I_yy, I_zz; float I_xy, I_xz, I_yz; @@ -85,14 +85,15 @@ __attribute__((always_inline)) INLINE static void multipole_iact_mm( /* acc *= const_G * ir * ir * ir; */ /* /\* Compute the forces on both multipoles. *\/ */ - /* #if multipole_order == 1 */ + /* #if const_gravity_multipole_order == 1 */ /* float mma = ma->coeffs[0], mmb = mb->coeffs[0]; */ /* for (k = 0; k < 3; k++) { */ /* ma->a[k] -= dx[k] * acc * mmb; */ /* mb->a[k] += dx[k] * acc * mma; */ /* } */ /* #else */ - /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + /* #error( "Multipoles of order %i not yet implemented." , + * const_gravity_multipole_order ) */ /* #endif */ } @@ -127,10 +128,11 @@ __attribute__((always_inline)) INLINE static void multipole_iact_mp( /* acc *= const_G * ir * ir * ir * m->coeffs[0]; */ /* /\* Compute the forces on both multipoles. *\/ */ - /* #if multipole_order == 1 */ + /* #if const_gravity_multipole_order == 1 */ /* for (k = 0; k < 3; k++) p->a_grav[k] += dx[k] * acc; */ /* #else */ - /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + /* #error( "Multipoles of order %i not yet implemented." , + * const_gravity_multipole_order ) */ /* #endif */ } diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 86bb47ae6..b8c820ea9 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -97,6 +97,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( struct gpart *restrict gparts = ci->gparts; const struct multipole multi = cj->multipole; const int ti_current = e->ti_current; + const float rlr_inv = 1.f; TIMER_TIC; @@ -137,7 +138,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; /* Interact !*/ - runner_iact_grav_pm(r2, dx, gp, &multi); + runner_iact_grav_pm(rlr_inv, r2, dx, gp, &multi); } TIMER_TOC(TIMER_DOPAIR); // MATTHIEU @@ -162,6 +163,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( struct gpart *restrict gparts_i = ci->gparts; struct gpart *restrict gparts_j = cj->gparts; const int ti_current = e->ti_current; + const float rlr_inv = 1.f; TIMER_TIC; @@ -216,20 +218,20 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( /* Interact ! */ if (gpi->ti_end <= ti_current && gpj->ti_end <= ti_current) { - runner_iact_grav_pp(r2, dx, gpi, gpj); + runner_iact_grav_pp(rlr_inv, r2, dx, gpi, gpj); } else { if (gpi->ti_end <= ti_current) { - runner_iact_grav_pp_nonsym(r2, dx, gpi, gpj); + runner_iact_grav_pp_nonsym(rlr_inv, r2, dx, gpi, gpj); } else if (gpj->ti_end <= ti_current) { dx[0] = -dx[0]; dx[1] = -dx[1]; dx[2] = -dx[2]; - runner_iact_grav_pp_nonsym(r2, dx, gpj, gpi); + runner_iact_grav_pp_nonsym(rlr_inv, r2, dx, gpj, gpi); } } } @@ -253,6 +255,7 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( const int gcount = c->gcount; struct gpart *restrict gparts = c->gparts; const int ti_current = e->ti_current; + const float rlr_inv = 1.f; TIMER_TIC; @@ -297,20 +300,20 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( /* Interact ! */ if (gpi->ti_end <= ti_current && gpj->ti_end <= ti_current) { - runner_iact_grav_pp(r2, dx, gpi, gpj); + runner_iact_grav_pp(rlr_inv, r2, dx, gpi, gpj); } else { if (gpi->ti_end <= ti_current) { - runner_iact_grav_pp_nonsym(r2, dx, gpi, gpj); + runner_iact_grav_pp_nonsym(rlr_inv, r2, dx, gpi, gpj); } else if (gpj->ti_end <= ti_current) { dx[0] = -dx[0]; dx[1] = -dx[1]; dx[2] = -dx[2]; - runner_iact_grav_pp_nonsym(r2, dx, gpj, gpi); + runner_iact_grav_pp_nonsym(rlr_inv, r2, dx, gpj, gpi); } } } diff --git a/src/tools.c b/src/tools.c index 3af35051c..743b28228 100644 --- a/src/tools.c +++ b/src/tools.c @@ -305,7 +305,7 @@ void pairs_single_grav(double *dim, long long int pid, fdx[i] = dx[i]; } r2 = fdx[0] * fdx[0] + fdx[1] * fdx[1] + fdx[2] * fdx[2]; - runner_iact_grav_pp(r2, fdx, &pi, &pj); + runner_iact_grav_pp(0.f, r2, fdx, &pi, &pj); a[0] += pi.a_grav[0]; a[1] += pi.a_grav[1]; a[2] += pi.a_grav[2]; @@ -519,7 +519,7 @@ void gravity_n2(struct gpart *gparts, const int gcount, const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; /* Apply the gravitational acceleration. */ - runner_iact_grav_pp(r2, dx, gpi, gpj); + runner_iact_grav_pp(0.f, r2, dx, gpi, gpj); } } -- GitLab From 170d2b7ffbca39f368108c7172ba251d2b22d0ef Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 13 Jun 2016 12:07:39 +0100 Subject: [PATCH 47/72] Better documentation of the gravity stuff in engine --- src/engine.c | 74 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/src/engine.c b/src/engine.c index 2c5700b4c..754add25a 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1086,6 +1086,14 @@ void engine_exchange_strays(struct engine *e, size_t offset_parts, #endif } +/** + * @brief Checks whether two cells are direct neighbours or not. + * + * @param ci First #cell. + * @param cj Second #cell. + * + * @return 1 if the cell are touching (by a face, edge or corner). + */ __attribute__((always_inline)) INLINE static int are_neighbours( const struct cell *restrict ci, const struct cell *restrict cj) { @@ -1108,9 +1116,12 @@ __attribute__((always_inline)) INLINE static int are_neighbours( } /** - * @brief Constructs the top-level pair tasks for the gravity M-M interactions + * @brief Constructs the top-level pair tasks for the short-range gravity + * interactions. * - * Correct implementation is still lacking here. + * All top-cells get a self task. + * All neighbouring pairs get a pair task. + * All non-neighbouring pairs within a range of 6 cells get a M-M task. * * @param e The #engine. */ @@ -1158,7 +1169,7 @@ void engine_make_gravity_tasks(struct engine *e) { /** * @brief Constructs the top-level pair tasks for the first hydro loop over - *neighbours + * neighbours * * Here we construct all the tasks for all possible neighbouring non-empty * local cells in the hierarchy. No dependencies are being added thus far. @@ -1286,7 +1297,30 @@ void engine_count_and_link_tasks(struct engine *e) { } } -void engine_make_gravity_dependencies(struct engine *e) { +/** + * @brief Creates the dependency network for the gravity tasks of a given cell. + * + * @param sched The #scheduler. + * @param gravity The gravity task to link. + * @param c The cell. + */ +static inline void engine_make_gravity_dependencies(struct scheduler *sched, + struct task *gravity, + struct cell *c) { + + /* init --> gravity --> kick */ + /* grav_up --> gravity ( --> kick) */ + scheduler_addunlock(sched, c->super->init, gravity); + scheduler_addunlock(sched, c->super->grav_up, gravity); + scheduler_addunlock(sched, gravity, c->super->kick); +} + +/** + * @brief Creates all the task dependencies for the gravity + * + * @param e The #engine + */ +void engine_link_gravity_tasks(struct engine *e) { struct scheduler *sched = &e->sched; const int nodeID = e->nodeID; @@ -1303,21 +1337,14 @@ void engine_make_gravity_dependencies(struct engine *e) { /* Long-range interaction */ if (t->type == task_type_grav_mm) { - scheduler_addunlock(sched, t->ci->super->init, t); - scheduler_addunlock(sched, t->ci->super->grav_up, t); - scheduler_addunlock(sched, t, t->ci->super->kick); - - scheduler_addunlock(sched, t->cj->super->init, t); - scheduler_addunlock(sched, t->cj->super->grav_up, t); - scheduler_addunlock(sched, t, t->cj->super->kick); + engine_make_gravity_dependencies(sched, t, t->ci); + engine_make_gravity_dependencies(sched, t, t->cj); } /* Self-interaction? */ if (t->type == task_type_self && t->subtype == task_subtype_grav) { - scheduler_addunlock(sched, t->ci->super->init, t); - scheduler_addunlock(sched, t->ci->super->grav_up, t); - scheduler_addunlock(sched, t, t->ci->super->kick); + engine_make_gravity_dependencies(sched, t, t->ci); } @@ -1326,16 +1353,12 @@ void engine_make_gravity_dependencies(struct engine *e) { if (t->ci->nodeID == nodeID) { - scheduler_addunlock(sched, t->ci->super->init, t); - scheduler_addunlock(sched, t->ci->super->grav_up, t); - scheduler_addunlock(sched, t, t->ci->super->kick); + engine_make_gravity_dependencies(sched, t, t->ci); } if (t->cj->nodeID == nodeID && t->ci->super != t->cj->super) { - scheduler_addunlock(sched, t->cj->super->init, t); - scheduler_addunlock(sched, t->cj->super->grav_up, t); - scheduler_addunlock(sched, t, t->cj->super->kick); + engine_make_gravity_dependencies(sched, t, t->cj); } } @@ -1345,16 +1368,12 @@ void engine_make_gravity_dependencies(struct engine *e) { if (t->ci->nodeID == nodeID) { - scheduler_addunlock(sched, t->ci->super->init, t); - scheduler_addunlock(sched, t->ci->super->grav_up, t); - scheduler_addunlock(sched, t, t->ci->super->kick); + engine_make_gravity_dependencies(sched, t, t->ci); } if (t->cj != NULL && t->cj->nodeID == nodeID && t->ci->super != t->cj->super) { - scheduler_addunlock(sched, t->cj->super->init, t); - scheduler_addunlock(sched, t->cj->super->grav_up, t); - scheduler_addunlock(sched, t, t->cj->super->kick); + engine_make_gravity_dependencies(sched, t, t->cj); } } } @@ -1578,8 +1597,7 @@ void engine_maketasks(struct engine *e) { if (e->policy & engine_policy_hydro) engine_make_extra_hydroloop_tasks(e); /* Add the dependencies for the self-gravity stuff */ - if (e->policy & engine_policy_self_gravity) - engine_make_gravity_dependencies(e); + if (e->policy & engine_policy_self_gravity) engine_link_gravity_tasks(e); #ifdef WITH_MPI -- GitLab From e1b31a1581acd592c2d204f2fda2caac1f824026 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 13 Jun 2016 14:56:31 +0100 Subject: [PATCH 48/72] Better documentation of the gravity stuff in engine --- src/engine.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/engine.c b/src/engine.c index 754add25a..bdb3ad395 100644 --- a/src/engine.c +++ b/src/engine.c @@ -95,7 +95,6 @@ static cpu_set_t entry_affinity; * * @return The new #link pointer. */ - struct link *engine_addlink(struct engine *e, struct link *l, struct task *t) { const int ind = atomic_inc(&e->nr_links); @@ -118,7 +117,6 @@ struct link *engine_addlink(struct engine *e, struct link *l, struct task *t) { * @param c The #cell. * @param super The super #cell. */ - void engine_make_hierarchical_tasks(struct engine *e, struct cell *c, struct cell *super) { @@ -542,7 +540,6 @@ void engine_redistribute(struct engine *e) { * * @param e The #engine. */ - void engine_repartition(struct engine *e) { #if defined(WITH_MPI) && defined(HAVE_METIS) @@ -592,7 +589,6 @@ void engine_repartition(struct engine *e) { * @param up The upward gravity #task. * @param down The downward gravity #task. */ - void engine_addtasks_grav(struct engine *e, struct cell *c, struct task *up, struct task *down) { @@ -614,7 +610,6 @@ void engine_addtasks_grav(struct engine *e, struct cell *c, struct task *up, * @param ci The sending #cell. * @param cj The receiving #cell */ - void engine_addtasks_send(struct engine *e, struct cell *ci, struct cell *cj) { #ifdef WITH_MPI @@ -665,7 +660,6 @@ void engine_addtasks_send(struct engine *e, struct cell *ci, struct cell *cj) { * @param t_xv The recv_xv #task, if it has already been created. * @param t_rho The recv_rho #task, if it has already been created. */ - void engine_addtasks_recv(struct engine *e, struct cell *c, struct task *t_xv, struct task *t_rho) { @@ -707,7 +701,6 @@ void engine_addtasks_recv(struct engine *e, struct cell *c, struct task *t_xv, * * @param e The #engine. */ - void engine_exchange_cells(struct engine *e) { #ifdef WITH_MPI @@ -855,7 +848,6 @@ void engine_exchange_cells(struct engine *e) { * Note that this function does not mess-up the linkage between parts and * gparts, i.e. the received particles have correct linkeage. */ - 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) { @@ -1092,7 +1084,7 @@ void engine_exchange_strays(struct engine *e, size_t offset_parts, * @param ci First #cell. * @param cj Second #cell. * - * @return 1 if the cell are touching (by a face, edge or corner). + * @return 1 if the cell are touching (by a face, edge or corner), 0 otherwise. */ __attribute__((always_inline)) INLINE static int are_neighbours( const struct cell *restrict ci, const struct cell *restrict cj) { @@ -1645,7 +1637,6 @@ void engine_maketasks(struct engine *e) { * * @return 1 if the space has to be rebuilt, 0 otherwise. */ - int engine_marktasks(struct engine *e) { struct scheduler *s = &e->sched; @@ -1785,7 +1776,6 @@ int engine_marktasks(struct engine *e) { * * @param e The #engine. */ - void engine_print_task_counts(struct engine *e) { struct scheduler *sched = &e->sched; @@ -1818,7 +1808,6 @@ void engine_print_task_counts(struct engine *e) { * * @param e The #engine. */ - void engine_rebuild(struct engine *e) { const ticks tic = getticks(); @@ -1854,7 +1843,6 @@ void engine_rebuild(struct engine *e) { * * @param e The #engine to prepare. */ - void engine_prepare(struct engine *e) { TIMER_TIC; @@ -1895,7 +1883,6 @@ void engine_prepare(struct engine *e) { * @param e The #engine. * @param tid The thread ID */ - void engine_barrier(struct engine *e, int tid) { /* First, get the barrier mutex. */ @@ -2081,6 +2068,11 @@ void engine_collect_drift(struct cell *c) { c->ang_mom[2] = ang_mom[2]; } +/** + * @brief Print the conserved quantities statistics to a log file + * + * @param e The #engine. + */ void engine_print_stats(struct engine *e) { const struct space *s = e->s; -- GitLab From 35bf96ad08dad86c7d083328d5e67b52ac011d47 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 13 Jun 2016 18:13:43 +0100 Subject: [PATCH 49/72] Moved the cell neighbour test function to the cell object --- src/cell.c | 29 ++++++++++++++++ src/cell.h | 2 ++ src/engine.c | 31 +----------------- src/runner_doiact_grav.h | 71 +++++++++++++--------------------------- tests/testKernelGrav.c | 1 + 5 files changed, 56 insertions(+), 78 deletions(-) diff --git a/src/cell.c b/src/cell.c index ba08fc1fd..96705bfa7 100644 --- a/src/cell.c +++ b/src/cell.c @@ -662,6 +662,35 @@ void cell_clean_links(struct cell *c, void *data) { c->nr_force = 0; } +/** + * @brief Checks whether the cells are direct neighbours ot not. Both cells have + * to be of the same size + * + * @param ci First #cell. + * @param cj Second #cell. + * + * @todo Deal with periodicity. + */ +int cell_are_neighbours(const struct cell *restrict ci, + const struct cell *restrict cj) { + +#ifdef SANITY_CHECKS + if (ci->h[0] != cj->h[0]) error("Cells of different size !"); +#endif + + /* Maximum allowed distance */ + const double min_dist = 1.2 * ci->h[0]; /* 1.2 accounts for rounding errors */ + + /* (Manhattan) Distance between the cells */ + for (int k = 0; k < 3; k++) { + const double center_i = ci->loc[k]; + const double center_j = cj->loc[k]; + if (fabsf(center_i - center_j) > min_dist) return 0; + } + + return 1; +} + /** * @brief Computes the multi-pole brutally and compare to the * recursively computed one. diff --git a/src/cell.h b/src/cell.h index 9095f6c70..a71c82b67 100644 --- a/src/cell.h +++ b/src/cell.h @@ -188,6 +188,8 @@ 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); +int cell_are_neighbours(const struct cell *restrict ci, + const struct cell *restrict cj); void cell_check_multipole(struct cell *c, void *data); #endif /* SWIFT_CELL_H */ diff --git a/src/engine.c b/src/engine.c index bdb3ad395..438ae251a 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1078,35 +1078,6 @@ void engine_exchange_strays(struct engine *e, size_t offset_parts, #endif } -/** - * @brief Checks whether two cells are direct neighbours or not. - * - * @param ci First #cell. - * @param cj Second #cell. - * - * @return 1 if the cell are touching (by a face, edge or corner), 0 otherwise. - */ -__attribute__((always_inline)) INLINE static int are_neighbours( - const struct cell *restrict ci, const struct cell *restrict cj) { - -#ifdef SANITY_CHECKS - if (ci->h[0] != cj->h[0]) - error(" Cells of different size in distance calculation."); -#endif - - /* Maximum allowed distance */ - const double min_dist = 1.2 * ci->h[0]; /* 1.2 accounts for rounding errors */ - - /* (Manhattan) Distance between the cells */ - for (int k = 0; k < 3; k++) { - const double center_i = ci->loc[k]; - const double center_j = cj->loc[k]; - if (fabsf(center_i - center_j) > min_dist) return 0; - } - - return 1; -} - /** * @brief Constructs the top-level pair tasks for the short-range gravity * interactions. @@ -1149,7 +1120,7 @@ void engine_make_gravity_tasks(struct engine *e) { /* Is that neighbour local ? */ if (cj->nodeID != nodeID) continue; - if (are_neighbours(ci, cj)) + if (cell_are_neighbours(ci, cj)) scheduler_addtask(sched, task_type_pair, task_subtype_grav, 0, 0, ci, cj, 1); else diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index b8c820ea9..2a9d12611 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -55,31 +55,6 @@ void runner_do_grav_up(struct runner *r, struct cell *c) { } } -/** - * @brief Checks whether the cells are direct neighbours ot not. Both cells have - * to be of the same size - * - * @param ci First #cell. - * @param cj Second #cell. - * - * @todo Deal with periodicity. - */ -__attribute__((always_inline)) INLINE static int are_neighbours( - const struct cell *restrict ci, const struct cell *restrict cj) { - - /* Maximum allowed distance */ - const double min_dist = 1.2 * ci->h[0]; /* 1.2 accounts for rounding errors */ - - /* (Manhattan) Distance between the cells */ - for (int k = 0; k < 3; k++) { - const double center_i = ci->loc[k]; - const double center_j = cj->loc[k]; - if (fabsf(center_i - center_j) > min_dist) return 0; - } - - return 1; -} - /** * @brief Computes the interaction of all the particles in a cell with the * multipole of another cell. @@ -354,7 +329,7 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, "itself."); /* Are the cells direct neighbours? */ - if (!are_neighbours(ci, cj)) + if (!cell_are_neighbours(ci, cj)) error( "Non-neighbouring cells ! ci->x=[%f %f %f] ci->h=%f cj->loc=[%f %f %f] " "cj->h=%f", @@ -394,7 +369,7 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, for (int k = 0; k < 8; k++) { if (cj->progeny[k] != NULL) { - if (are_neighbours(ci->progeny[j], cj->progeny[k])) { + if (cell_are_neighbours(ci->progeny[j], cj->progeny[k])) { /* Recurse */ runner_dopair_grav(r, ci->progeny[j], cj->progeny[k]); @@ -461,7 +436,8 @@ static void runner_dosub_grav(struct runner *r, struct cell *ci, } else { #ifdef SANITY_CHECKS - if (!are_neighbours(ci, cj)) error("Non-neighbouring cells in pair task !"); + if (!cell_are_neighbours(ci, cj)) + error("Non-neighbouring cells in pair task !"); #endif runner_dopair_grav(r, ci, cj); @@ -472,36 +448,35 @@ static void runner_do_grav_mm(struct runner *r, struct cell *ci, struct cell *cj) { #ifdef SANITY_CHECKS - if (are_neighbours(ci, cj)) { - + if (cell_are_neighbours(ci, cj)) { error("Non-neighbouring cells in mm task !"); - + } #endif #if ICHECK > 0 - for (int pid = 0; pid < ci->gcount; pid++) { + for (int pid = 0; pid < ci->gcount; pid++) { - /* Get a hold of the ith part in ci. */ - struct gpart *restrict gp = &ci->gparts[pid]; + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &ci->gparts[pid]; - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, - cj->loc[0], cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); - } + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, cj->loc[0], + cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); + } - for (int pid = 0; pid < cj->gcount; pid++) { + for (int pid = 0; pid < cj->gcount; pid++) { - /* Get a hold of the ith part in ci. */ - struct gpart *restrict gp = &cj->gparts[pid]; + /* Get a hold of the ith part in ci. */ + struct gpart *restrict gp = &cj->gparts[pid]; - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, - ci->loc[0], ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); - } + if (gp->id == -ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, ci->loc[0], + ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); + } #endif - runner_dopair_grav_pm(r, ci, cj); - runner_dopair_grav_pm(r, cj, ci); - } + runner_dopair_grav_pm(r, ci, cj); + runner_dopair_grav_pm(r, cj, ci); +} #endif /* SWIFT_RUNNER_DOIACT_GRAV_H */ diff --git a/tests/testKernelGrav.c b/tests/testKernelGrav.c index 2adc6f703..c05d15bcb 100644 --- a/tests/testKernelGrav.c +++ b/tests/testKernelGrav.c @@ -30,6 +30,7 @@ * @brief The Gadget-2 gravity kernel function * * @param r The distance between particles + * @param h The cut-off distance of the kernel */ float gadget(float r, float h) { float fac; -- GitLab From aa075f20233240e6f2b68f7b711666c7fcd5198a Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 14 Jun 2016 10:51:44 +0100 Subject: [PATCH 50/72] Added linking of the FFTW 3.x library --- configure.ac | 12 + examples/Makefile.am | 8 +- src/Makefile.am | 5 +- src/runner_doiact_grav_old.h | 606 ----------------------------------- 4 files changed, 19 insertions(+), 612 deletions(-) delete mode 100644 src/runner_doiact_grav_old.h diff --git a/configure.ac b/configure.ac index 497107121..c69da085c 100644 --- a/configure.ac +++ b/configure.ac @@ -344,6 +344,17 @@ if test "$ac_cv_func_pthread_setaffinity_np" = "yes"; then fi fi +# Check for FFTW +have_fftw3="no" +AC_CHECK_HEADER([fftw3.h]) +if test "$ac_cv_header_fftw3_h" = "yes"; then + AC_CHECK_LIB([fftw3],[fftw_malloc], [AC_DEFINE([HAVE_FFTW], + [1],[Defined if FFTW 3.x exists.])] ) + FFTW_LIBS="-lfftw3" + have_fftw3="yes" +fi +AC_SUBST([FFTW_LIBS]) + # Check for Intel intrinsics header optionally used by vector.h. AC_CHECK_HEADERS([immintrin.h]) @@ -409,6 +420,7 @@ AC_MSG_RESULT([ HDF5 enabled : $with_hdf5 - parallel : $have_parallel_hdf5 Metis enabled : $have_metis + FFTW3 enabled : $have_fftw3 libNUMA enabled : $have_numa ]) diff --git a/examples/Makefile.am b/examples/Makefile.am index 15fceb236..6ddb07fb7 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -46,20 +46,20 @@ endif # Sources for swift swift_SOURCES = main.c swift_CFLAGS = $(MYFLAGS) $(AM_CFLAGS) -DENGINE_POLICY="engine_policy_keep $(ENGINE_POLICY_SETAFFINITY)" -swift_LDADD = ../src/.libs/libswiftsim.a $(HDF5_LDFLAGS) $(HDF5_LIBS) +swift_LDADD = ../src/.libs/libswiftsim.a $(HDF5_LDFLAGS) $(HDF5_LIBS) $(FFTW_LIBS) swift_fixdt_SOURCES = main.c swift_fixdt_CFLAGS = $(MYFLAGS) $(AM_CFLAGS) -DENGINE_POLICY="engine_policy_fixdt | engine_policy_keep $(ENGINE_POLICY_SETAFFINITY)" -swift_fixdt_LDADD = ../src/.libs/libswiftsim.a $(HDF5_LDFLAGS) $(HDF5_LIBS) +swift_fixdt_LDADD = ../src/.libs/libswiftsim.a $(HDF5_LDFLAGS) $(HDF5_LIBS) $(FFTW_LIBS) # Sources for swift_mpi, do we need an affinity policy for MPI? swift_mpi_SOURCES = main.c swift_mpi_CFLAGS = $(MYFLAGS) $(AM_CFLAGS) $(MPI_FLAGS) -DENGINE_POLICY="engine_policy_keep $(ENGINE_POLICY_SETAFFINITY)" -swift_mpi_LDADD = ../src/.libs/libswiftsim_mpi.a $(HDF5_LDFLAGS) $(HDF5_LIBS) $(MPI_LIBS) +swift_mpi_LDADD = ../src/.libs/libswiftsim_mpi.a $(HDF5_LDFLAGS) $(HDF5_LIBS) $(FFTW_LIBS) $(MPI_LIBS) swift_fixdt_mpi_SOURCES = main.c swift_fixdt_mpi_CFLAGS = $(MYFLAGS) $(AM_CFLAGS) $(MPI_FLAGS) -DENGINE_POLICY="engine_policy_fixdt | engine_policy_keep $(ENGINE_POLICY_SETAFFINITY)" -swift_fixdt_mpi_LDADD = ../src/.libs/libswiftsim_mpi.a $(HDF5_LDFLAGS) $(HDF5_LIBS) $(MPI_LIBS) +swift_fixdt_mpi_LDADD = ../src/.libs/libswiftsim_mpi.a $(HDF5_LDFLAGS) $(HDF5_LIBS) $(FFTW_LIBS) $(MPI_LIBS) # Scripts to generate ICs EXTRA_DIST = UniformBox/makeIC.py UniformBox/run.sh UniformBox/uniformBox.yml \ diff --git a/src/Makefile.am b/src/Makefile.am index 311c49570..295f9efa5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,10 +17,10 @@ # along with this program. If not, see . # Add the debug flag to the whole thing -AM_CFLAGS = -DTIMER -DCOUNTER $(HDF5_CPPFLAGS) +AM_CFLAGS = -DTIMER $(HDF5_CPPFLAGS) # Assign a "safe" version number -AM_LDFLAGS = $(LAPACK_LIBS) $(BLAS_LIBS) $(HDF5_LDFLAGS) -version-info 0:0:0 # -fsanitize=address +AM_LDFLAGS = $(HDF5_LDFLAGS) $(FFTW_LIBS) -version-info 0:0:0 # -fsanitize=address # The git command, if available. GIT_CMD = @GIT_CMD@ @@ -70,6 +70,7 @@ libswiftsim_la_SOURCES = $(AM_SOURCES) # Sources and flags for MPI library libswiftsim_mpi_la_SOURCES = $(AM_SOURCES) libswiftsim_mpi_la_CFLAGS = $(AM_CFLAGS) -DWITH_MPI $(METIS_INCS) +libswiftsim_mpi_la_LDFLAGS = $(AM_LDFLAGS) $(METIS_LIBS) libswiftsim_mpi_la_SHORTNAME = mpi diff --git a/src/runner_doiact_grav_old.h b/src/runner_doiact_grav_old.h deleted file mode 100644 index 8a22024ca..000000000 --- a/src/runner_doiact_grav_old.h +++ /dev/null @@ -1,606 +0,0 @@ -/******************************************************************************* - * This file is part of SWIFT. - * Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk) - * 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - ******************************************************************************/ -#ifndef SWIFT_RUNNER_DOIACT_GRAV_H -#define SWIFT_RUNNER_DOIACT_GRAV_H - -/* Includes. */ -#include "cell.h" -#include "clocks.h" -#include "part.h" - -/* /\** */ -/* * @brief Compute the sorted gravity interactions between a cell pair. */ -/* * */ -/* * @param r The #runner. */ -/* * @param ci The first #cell. */ -/* * @param cj The second #cell. */ -/* *\/ */ - -/* void runner_dopair_grav_new(struct runner *r, struct cell *ci, */ -/* struct cell *cj) { */ - -/* struct engine *restrict e = r->e; */ -/* int pid, pjd, k, sid; */ -/* double rshift, shift[3] = {0.0, 0.0, 0.0}, nshift[3]; */ -/* struct entry *restrict sort_i, *restrict sort_j; */ -/* struct gpart *restrict pi, *restrict pj, *restrict parts_i, *restrict - * parts_j; */ -/* double pix[3]; */ -/* float dx[3], r2, h_max, di, dj; */ -/* int count_i, count_j, cnj, cnj_new; */ -/* const int ti_current = e->ti_current; */ -/* struct multipole m; */ -/* #ifdef VECTORIZE */ -/* int icount = 0; */ -/* float r2q[VEC_SIZE] __attribute__((aligned(16))); */ -/* float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); */ -/* struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; */ -/* #endif */ -/* TIMER_TIC */ - -/* /\* Anything to do here? *\/ */ -/* if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; */ - -/* /\* Get the sort ID. *\/ */ -/* sid = space_getsid(e->s, &ci, &cj, shift); */ - -/* /\* Make sure the cells are sorted. *\/ */ -/* runner_dogsort(r, ci, (1 << sid), 0); */ -/* runner_dogsort(r, cj, (1 << sid), 0); */ - -/* /\* Have the cells been sorted? *\/ */ -/* if (!(ci->gsorted & (1 << sid)) || !(cj->gsorted & (1 << sid))) */ -/* error("Trying to interact unsorted cells."); */ - -/* /\* Get the cutoff shift. *\/ */ -/* for (rshift = 0.0, k = 0; k < 3; k++) */ -/* rshift += shift[k] * runner_shift[3 * sid + k]; */ - -/* /\* Pick-out the sorted lists. *\/ */ -/* sort_i = &ci->gsort[sid * (ci->count + 1)]; */ -/* sort_j = &cj->gsort[sid * (cj->count + 1)]; */ - -/* /\* Get some other useful values. *\/ */ -/* h_max = */ -/* sqrtf(ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * ci->h[2]) - * * */ -/* const_theta_max; */ -/* count_i = ci->gcount; */ -/* count_j = cj->gcount; */ -/* parts_i = ci->gparts; */ -/* parts_j = cj->gparts; */ -/* cnj = count_j; */ -/* multipole_reset(&m); */ -/* nshift[0] = -shift[0]; */ -/* nshift[1] = -shift[1]; */ -/* nshift[2] = -shift[2]; */ - -/* /\* Loop over the parts in ci. *\/ */ -/* for (pid = count_i - 1; pid >= 0; pid--) { */ - -/* /\* Get a hold of the ith part in ci. *\/ */ -/* pi = &parts_i[sort_i[pid].i]; */ -/* if (pi->ti_end > ti_current) continue; */ -/* di = sort_i[pid].d + h_max - rshift; */ - -/* for (k = 0; k < 3; k++) pix[k] = pi->x[k] - shift[k]; */ - -/* /\* Loop over the parts in cj. *\/ */ -/* for (pjd = 0; pjd < cnj && sort_j[pjd].d < di; pjd++) { */ - -/* /\* Get a pointer to the jth particle. *\/ */ -/* pj = &parts_j[sort_j[pjd].i]; */ - -/* /\* Compute the pairwise distance. *\/ */ -/* r2 = 0.0f; */ -/* for (k = 0; k < 3; k++) { */ -/* dx[k] = pix[k] - pj->x[k]; */ -/* r2 += dx[k] * dx[k]; */ -/* } */ - -/* #ifndef VECTORIZE */ - -/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 - * ) */ -/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e - * in */ -/* // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long - */ -/* // long int)ci) / sizeof(struct cell) , ((long long int)cj) / */ -/* // sizeof(struct cell) ); */ - -/* runner_iact_grav(r2, dx, pi, pj); */ - -/* #else */ - -/* /\* Add this interaction to the queue. *\/ */ -/* r2q[icount] = r2; */ -/* dxq[3 * icount + 0] = dx[0]; */ -/* dxq[3 * icount + 1] = dx[1]; */ -/* dxq[3 * icount + 2] = dx[2]; */ -/* piq[icount] = pi; */ -/* pjq[icount] = pj; */ -/* icount += 1; */ - -/* /\* Flush? *\/ */ -/* if (icount == VEC_SIZE) { */ -/* runner_iact_vec_grav(r2q, dxq, piq, pjq); */ -/* icount = 0; */ -/* } */ - -/* #endif */ - -/* } /\* loop over the parts in cj. *\/ */ - -/* /\* Set the new limit. *\/ */ -/* cnj_new = pjd; */ - -/* /\* Add trailing parts to the multipole. *\/ */ -/* for (pjd = cnj_new; pjd < cnj; pjd++) { */ - -/* /\* Add the part to the multipole. *\/ */ -/* multipole_addpart(&m, &parts_j[sort_j[pjd].i]); */ - -/* } /\* add trailing parts to the multipole. *\/ */ - -/* /\* Set the new cnj. *\/ */ -/* cnj = cnj_new; */ - -/* /\* Interact the ith particle with the multipole. *\/ */ -/* multipole_iact_mp(&m, pi, nshift); */ - -/* } /\* loop over the parts in ci. *\/ */ - -/* #ifdef VECTORIZE */ -/* /\* Pick up any leftovers. *\/ */ -/* if (icount > 0) */ -/* for (k = 0; k < icount; k++) */ -/* runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); */ -/* #endif */ - -/* /\* Re-set the multipole. *\/ */ -/* multipole_reset(&m); */ - -/* /\* Loop over the parts in cj and interact with the multipole in ci. *\/ */ -/* for (pid = count_i - 1, pjd = 0; pjd < count_j; pjd++) { */ - -/* /\* Get the position of pj along the axis. *\/ */ -/* dj = sort_j[pjd].d - h_max + rshift; */ - -/* /\* Add any left-over parts in cell_i to the multipole. *\/ */ -/* while (pid >= 0 && sort_i[pid].d < dj) { */ - -/* /\* Add this particle to the multipole. *\/ */ -/* multipole_addpart(&m, &parts_i[sort_i[pid].i]); */ - -/* /\* Decrease pid. *\/ */ -/* pid -= 1; */ -/* } */ - -/* /\* Interact pj with the multipole. *\/ */ -/* multipole_iact_mp(&m, &parts_j[sort_j[pjd].i], shift); */ - -/* } /\* loop over the parts in cj and interact with the multipole. *\/ */ - -/* TIMER_TOC(TIMER_DOPAIR); */ -/* } */ - -/** - * @brief Compute the recursive upward sweep, i.e. construct the - * multipoles in a cell hierarchy. - * - * @param r The #runner. - * @param c The top-level #cell. - */ - -void runner_dograv_up(struct runner *r, struct cell *c) { - - if (c->split) { /* Regular node */ - - /* Recurse. */ - for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) runner_dograv_up(r, c->progeny[k]); - - /* Collect the multipoles from the progeny. */ - multipole_reset(&c->multipole); - for (int k = 0; k < 8; k++) { - if (c->progeny[k] != NULL) - multipole_add(&c->multipole, &c->progeny[k]->multipole); - } - - } else { /* Leaf node. */ - - /* Just construct the multipole from the gparts. */ - multipole_init(&c->multipole, c->gparts, c->gcount); - } -} - -/* /\** */ -/* * @brief Compute the recursive downward sweep, i.e. apply the multipole */ -/* * acceleration on all the particles. */ -/* * */ -/* * @param r The #runner. */ -/* * @param c The top-level #cell. */ -/* *\/ */ - -/* void runner_dograv_down(struct runner *r, struct cell *c) { */ - -/* struct multipole *m = &c->multipole; */ - -/* /\* Split? *\/ */ -/* if (c->split) { */ - -/* /\* Apply this cell's acceleration on the multipoles below. *\/ */ -/* for (int k = 0; k < 8; k++) */ -/* if (c->progeny[k] != NULL) { */ -/* struct multipole *mp = &c->progeny[k]->multipole; */ -/* mp->a[0] += m->a[0]; */ -/* mp->a[1] += m->a[1]; */ -/* mp->a[2] += m->a[2]; */ -/* } */ - -/* /\* Recurse. *\/ */ -/* for (int k = 0; k < 8; k++) */ -/* if (c->progeny[k] != NULL) runner_dograv_down(r, c->progeny[k]); */ - -/* } */ - -/* /\* No, leaf node. *\/ */ -/* else { */ - -/* /\* Apply the multipole acceleration to all gparts. *\/ */ -/* for (int k = 0; k < c->gcount; k++) { */ -/* struct gpart *p = &c->gparts[k]; */ -/* p->a_grav[0] += m->a[0]; */ -/* p->a_grav[1] += m->a[1]; */ -/* p->a_grav[2] += m->a[2]; */ -/* } */ -/* } */ -/* } */ - -/* /\** */ -/* * @brief Compute the multipole-multipole interaction between two cells. */ -/* * */ -/* * @param r The #runner. */ -/* * @param ci The first #cell. */ -/* * @param cj The second #cell. */ -/* *\/ */ - -/* void runner_dograv_mm(struct runner *r, struct cell *restrict ci, */ -/* struct cell *restrict cj) { */ - -/* struct engine *e = r->e; */ -/* int k; */ -/* double shift[3] = {0.0, 0.0, 0.0}; */ -/* float dx[3], theta; */ - -/* /\* Compute the shift between the cells. *\/ */ -/* for (k = 0; k < 3; k++) { */ -/* dx[k] = cj->loc[k] - ci->loc[k]; */ -/* if (r->e->s->periodic) { */ -/* if (dx[k] < -e->s->dim[k] / 2) */ -/* shift[k] = e->s->dim[k]; */ -/* else if (dx[k] > e->s->dim[k] / 2) */ -/* shift[k] = -e->s->dim[k]; */ -/* dx[k] += shift[k]; */ -/* } */ -/* } */ -/* theta = */ -/* sqrt((dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */ -/* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * - * ci->h[2])); */ - -/* /\* Do an MM or an MP/PM? *\/ */ -/* if (theta > const_theta_max * 4) { */ - -/* /\* Update the multipoles. *\/ */ -/* multipole_iact_mm(&ci->multipole, &cj->multipole, shift); */ - -/* } else { */ - -/* /\* Interact the multipoles via their parts. *\/ */ -/* for (k = 0; k < ci->gcount; k++) */ -/* multipole_iact_mp(&cj->multipole, &ci->gparts[k], shift); */ -/* for (k = 0; k < cj->gcount; k++) */ -/* multipole_iact_mp(&ci->multipole, &cj->gparts[k], shift); */ -/* } */ -/* } */ - -/* /\** */ -/* * @brief Compute the interactions between a cell pair. */ -/* * */ -/* * @param r The #runner. */ -/* * @param ci The first #cell. */ -/* * @param cj The second #cell. */ -/* *\/ */ - -/* void runner_dopair_grav(struct runner *r, struct cell *restrict ci, */ -/* struct cell *restrict cj) { */ - -/* struct engine *e = r->e; */ -/* int pid, pjd, k, count_i = ci->gcount, count_j = cj->gcount; */ -/* double shift[3] = {0.0, 0.0, 0.0}; */ -/* struct gpart *restrict parts_i = ci->gparts, *restrict parts_j = - * cj->gparts; */ -/* struct gpart *restrict pi, *restrict pj; */ -/* double pix[3]; */ -/* float dx[3], r2; */ -/* const int ti_current = r->e->ti_current; */ -/* #ifdef VECTORIZE */ -/* int icount = 0; */ -/* float r2q[VEC_SIZE] __attribute__((aligned(16))); */ -/* float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); */ -/* struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; */ -/* #endif */ -/* TIMER_TIC */ - -/* /\* Anything to do here? *\/ */ -/* if (ci->ti_end_min > ti_current && cj->ti_end_min > ti_current) return; */ - -/* /\* Get the relative distance between the pairs, wrapping. *\/ */ -/* if (e->s->periodic) */ -/* for (k = 0; k < 3; k++) { */ -/* if (cj->loc[k] - ci->loc[k] < -e->s->dim[k] / 2) */ -/* shift[k] = e->s->dim[k]; */ -/* else if (cj->loc[k] - ci->loc[k] > e->s->dim[k] / 2) */ -/* shift[k] = -e->s->dim[k]; */ -/* } */ - -/* /\* Loop over the parts in ci. *\/ */ -/* for (pid = 0; pid < count_i; pid++) { */ - -/* /\* Get a hold of the ith part in ci. *\/ */ -/* pi = &parts_i[pid]; */ -/* for (k = 0; k < 3; k++) pix[k] = pi->x[k] - shift[k]; */ - -/* /\* Loop over the parts in cj. *\/ */ -/* for (pjd = 0; pjd < count_j; pjd++) { */ - -/* /\* Get a pointer to the jth particle. *\/ */ -/* pj = &parts_j[pjd]; */ - -/* /\* Compute the pairwise distance. *\/ */ -/* r2 = 0.0f; */ -/* for (k = 0; k < 3; k++) { */ -/* dx[k] = pix[k] - pj->x[k]; */ -/* r2 += dx[k] * dx[k]; */ -/* } */ - -/* /\* Compute the interaction. *\/ */ -/* #ifndef VECTORIZE */ - -/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 - * ) */ -/* // message( "interacting particles pi=%lli and pj=%lli with r=%.3e - * in */ -/* // cells %lli/%lli." , pi->part->id , pj->part->id , sqrtf(r2) , ((long - */ -/* // long int)ci) / sizeof(struct cell) , ((long long int)cj) / */ -/* // sizeof(struct cell) ); */ - -/* runner_iact_grav(r2, dx, pi, pj); */ - -/* #else */ - -/* /\* Add this interaction to the queue. *\/ */ -/* r2q[icount] = r2; */ -/* dxq[3 * icount + 0] = dx[0]; */ -/* dxq[3 * icount + 1] = dx[1]; */ -/* dxq[3 * icount + 2] = dx[2]; */ -/* piq[icount] = pi; */ -/* pjq[icount] = pj; */ -/* icount += 1; */ - -/* /\* Flush? *\/ */ -/* if (icount == VEC_SIZE) { */ -/* runner_iact_vec_grav(r2q, dxq, piq, pjq); */ -/* icount = 0; */ -/* } */ - -/* #endif */ - -/* } /\* loop over the parts in cj. *\/ */ - -/* } /\* loop over the parts in ci. *\/ */ - -/* #ifdef VECTORIZE */ -/* /\* Pick up any leftovers. *\/ */ -/* if (icount > 0) */ -/* for (k = 0; k < icount; k++) */ -/* runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); */ -/* #endif */ - -/* TIMER_TOC(timer_dopair_grav); */ -/* } */ - -/* /\** */ -/* * @brief Compute the interactions within a cell. */ -/* * */ -/* * @param r The #runner. */ -/* * @param c The #cell. */ -/* *\/ */ - -/* void runner_doself_grav(struct runner *r, struct cell *restrict c) { */ - -/* int pid, pjd, k, count = c->gcount; */ -/* struct gpart *restrict parts = c->gparts; */ -/* struct gpart *restrict pi, *restrict pj; */ -/* double pix[3] = {0.0, 0.0, 0.0}; */ -/* float dx[3], r2; */ -/* const int ti_current = r->e->ti_current; */ -/* #ifdef VECTORIZE */ -/* int icount = 0; */ -/* float r2q[VEC_SIZE] __attribute__((aligned(16))); */ -/* float dxq[3 * VEC_SIZE] __attribute__((aligned(16))); */ -/* struct gpart *piq[VEC_SIZE], *pjq[VEC_SIZE]; */ -/* #endif */ -/* TIMER_TIC */ - -/* /\* Anything to do here? *\/ */ -/* if (c->ti_end_min > ti_current) return; */ - -/* /\* Loop over every part in c. *\/ */ -/* for (pid = 0; pid < count; pid++) { */ - -/* /\* Get a hold of the ith part in ci. *\/ */ -/* pi = &parts[pid]; */ -/* for (k = 0; k < 3; k++) pix[k] = pi->x[k]; */ - -/* /\* Loop over every other part in c. *\/ */ -/* for (pjd = pid + 1; pjd < count; pjd++) { */ - -/* /\* Get a pointer to the jth particle. *\/ */ -/* pj = &parts[pjd]; */ - -/* /\* Compute the pairwise distance. *\/ */ -/* r2 = 0.0f; */ -/* for (k = 0; k < 3; k++) { */ -/* dx[k] = pix[k] - pj->x[k]; */ -/* r2 += dx[k] * dx[k]; */ -/* } */ - -/* /\* Compute the interaction. *\/ */ -/* #ifndef VECTORIZE */ - -/* // if ( pi->part->id == 3473472412525 || pj->part->id == 3473472412525 - * ) */ -/* // message( "interacting particles pi=%lli and pj=%lli with - * r=%.3e." , */ -/* // pi->part->id , pj->part->id , sqrtf(r2) ); */ - -/* runner_iact_grav(r2, dx, pi, pj); */ - -/* #else */ - -/* /\* Add this interaction to the queue. *\/ */ -/* r2q[icount] = r2; */ -/* dxq[3 * icount + 0] = dx[0]; */ -/* dxq[3 * icount + 1] = dx[1]; */ -/* dxq[3 * icount + 2] = dx[2]; */ -/* piq[icount] = pi; */ -/* pjq[icount] = pj; */ -/* icount += 1; */ - -/* /\* Flush? *\/ */ -/* if (icount == VEC_SIZE) { */ -/* runner_iact_vec_grav(r2q, dxq, piq, pjq); */ -/* icount = 0; */ -/* } */ - -/* #endif */ - -/* } /\* loop over the remaining parts in c. *\/ */ - -/* } /\* loop over the parts in c. *\/ */ - -/* #ifdef VECTORIZE */ -/* /\* Pick up any leftovers. *\/ */ -/* if (icount > 0) */ -/* for (k = 0; k < icount; k++) */ -/* runner_iact_grav(r2q[k], &dxq[3 * k], piq[k], pjq[k]); */ -/* #endif */ - -/* TIMER_TOC(timer_doself_grav); */ -/* } */ - -/* /\** */ -/* * @brief Compute a gravity sub-task. */ -/* * */ -/* * @param r The #runner. */ -/* * @param ci The first #cell. */ -/* * @param cj The second #cell. */ -/* * @param gettimer Flag to record timer or not. */ -/* *\/ */ - -/* void runner_dosub_grav(struct runner *r, struct cell *ci, struct cell *cj, */ -/* int gettimer) { */ - -/* int j, k, periodic = r->e->s->periodic; */ -/* struct space *s = r->e->s; */ - -/* TIMER_TIC */ - -/* /\* Self-interaction? *\/ */ -/* if (cj == NULL) { */ - -/* /\* If the cell is split, recurse. *\/ */ -/* if (ci->split) { */ - -/* /\* Split this task into tasks on its progeny. *\/ */ -/* for (j = 0; j < 8; j++) */ -/* if (ci->progeny[j] != NULL) { */ -/* runner_dosub_grav(r, ci->progeny[j], NULL, 0); */ -/* for (k = j + 1; k < 8; k++) */ -/* if (ci->progeny[k] != NULL) */ -/* runner_dosub_grav(r, ci->progeny[j], ci->progeny[k], 0); */ -/* } */ - -/* } */ - -/* /\* Otherwise, just make a pp task out of it. *\/ */ -/* else */ -/* runner_doself_grav(r, ci); */ - -/* } */ - -/* /\* Nope, pair. *\/ */ -/* else { */ - -/* /\* Get the opening angle theta. *\/ */ -/* float dx[3], theta; */ -/* for (k = 0; k < 3; k++) { */ -/* dx[k] = fabs(ci->loc[k] - cj->loc[k]); */ -/* if (periodic && dx[k] > 0.5 * s->dim[k]) dx[k] = -dx[k] + s->dim[k]; */ -/* if (dx[k] > 0.0f) dx[k] -= ci->h[k]; */ -/* } */ -/* theta = (dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]) / */ -/* (ci->h[0] * ci->h[0] + ci->h[1] * ci->h[1] + ci->h[2] * - * ci->h[2]); */ - -/* /\* Split the interaction? *\/ */ -/* if (theta < const_theta_max * const_theta_max) { */ - -/* /\* Are both ci and cj split? *\/ */ -/* if (ci->split && cj->split) { */ - -/* /\* Split this task into tasks on its progeny. *\/ */ -/* for (j = 0; j < 8; j++) */ -/* if (ci->progeny[j] != NULL) { */ -/* for (k = 0; k < 8; k++) */ -/* if (cj->progeny[k] != NULL) */ -/* runner_dosub_grav(r, ci->progeny[j], cj->progeny[k], 0); */ -/* } */ - -/* } */ - -/* /\* Otherwise, make a pp task out of it. *\/ */ -/* else */ -/* runner_dopair_grav(r, ci, cj); */ - -/* } */ - -/* /\* Otherwise, mm interaction is fine. *\/ */ -/* else */ -/* runner_dograv_mm(r, ci, cj); */ -/* } */ - -/* if (gettimer) TIMER_TOC(timer_dosub_grav); */ -/* } */ -#endif /* SWIFT_RUNNER_DOIACT_GRAV_H */ -- GitLab From ea0c9ca3cce8cf992bd12ec16dd4607bd8c0334a Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 14 Jun 2016 17:43:35 +0100 Subject: [PATCH 51/72] Make sure we have at least 8 cells on a side when using gravity --- examples/main.c | 4 ++-- src/space.c | 11 +++++++++-- src/space.h | 7 +++++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/examples/main.c b/examples/main.c index 6422cccee..e1df97810 100644 --- a/examples/main.c +++ b/examples/main.c @@ -375,8 +375,8 @@ int main(int argc, char *argv[]) { /* Initialize the space with these data. */ if (myrank == 0) clocks_gettime(&tic); struct space s; - space_init(&s, params, dim, parts, gparts, Ngas, Ngpart, periodic, talking, - dry_run); + space_init(&s, params, dim, parts, gparts, Ngas, Ngpart, periodic, + with_self_gravity, talking, dry_run); if (myrank == 0) { clocks_gettime(&toc); message("space_init took %.3f %s.", clocks_diff(&tic, &toc), diff --git a/src/space.c b/src/space.c index 0af5009c9..19c099742 100644 --- a/src/space.c +++ b/src/space.c @@ -205,6 +205,12 @@ void space_regrid(struct space *s, double cell_max, int verbose) { "Must have at least 3 cells in each spatial dimension when periodicity " "is switched on."); + /* Check if we have enough cells for gravity. */ + if (s->gravity && (cdim[0] < 8 || cdim[1] < 8 || cdim[2] < 8)) + error( + "Must have at least 8 cells in each spatial dimension when gravity " + "is switched on."); + /* In MPI-Land, changing the top-level cell size requires that the * global partition is recomputed and the particles redistributed. * Be prepared to do that. */ @@ -1415,8 +1421,8 @@ struct cell *space_getcell(struct space *s) { void space_init(struct space *s, const struct swift_params *params, double dim[3], struct part *parts, struct gpart *gparts, - size_t Npart, size_t Ngpart, int periodic, int verbose, - int dry_run) { + size_t Npart, size_t Ngpart, int periodic, int gravity, + int verbose, int dry_run) { /* Clean-up everything */ bzero(s, sizeof(struct space)); @@ -1426,6 +1432,7 @@ void space_init(struct space *s, const struct swift_params *params, s->dim[1] = dim[1]; s->dim[2] = dim[2]; s->periodic = periodic; + s->gravity = gravity; s->nr_parts = Npart; s->size_parts = Npart; s->parts = parts; diff --git a/src/space.h b/src/space.h index d53c0f2a5..fdd90393e 100644 --- a/src/space.h +++ b/src/space.h @@ -96,6 +96,9 @@ struct space { /* Is the space periodic? */ int periodic; + /* Are we doing gravity? */ + int gravity; + /* General-purpose lock for this space. */ swift_lock_type lock; @@ -139,8 +142,8 @@ int space_getsid(struct space *s, struct cell **ci, struct cell **cj, double *shift); void space_init(struct space *s, const struct swift_params *params, double dim[3], struct part *parts, struct gpart *gparts, - size_t Npart, size_t Ngpart, int periodic, int verbose, - int dry_run); + size_t Npart, size_t Ngpart, int periodic, int gravity, + int verbose, int dry_run); void space_map_cells_pre(struct space *s, int full, void (*fun)(struct cell *c, void *data), void *data); void space_map_parts(struct space *s, -- GitLab From f0728bfb5ea6b4d0b679e98d4de50f991e03715d Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 14 Jun 2016 18:40:40 +0100 Subject: [PATCH 52/72] Modified the mm task to use all the multipoles interacting with one given cell --- src/const.h | 2 +- src/engine.c | 35 +++++++++++++++++++++++++++++------ src/runner.c | 15 +++++---------- src/runner_doiact_grav.h | 39 +++++++++++++++++++-------------------- src/scheduler.c | 3 +-- src/task.c | 15 +++++---------- src/task.h | 4 ++-- 7 files changed, 62 insertions(+), 51 deletions(-) diff --git a/src/const.h b/src/const.h index ba71e3aeb..14a4ea6f6 100644 --- a/src/const.h +++ b/src/const.h @@ -61,6 +61,6 @@ /* External gravity properties */ #define EXTERNAL_POTENTIAL_POINTMASS -//#define SANITY_CHECKS +#define SANITY_CHECKS #endif /* SWIFT_CONST_H */ diff --git a/src/engine.c b/src/engine.c index 438ae251a..f0878af71 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1079,7 +1079,7 @@ void engine_exchange_strays(struct engine *e, size_t offset_parts, } /** - * @brief Constructs the top-level pair tasks for the short-range gravity + * @brief Constructs the top-level tasks for the short-range gravity * interactions. * * All top-cells get a self task. @@ -1110,6 +1110,10 @@ void engine_make_gravity_tasks(struct engine *e) { scheduler_addtask(sched, task_type_self, task_subtype_grav, 0, 0, ci, NULL, 0); + /* Let's also build a task for all the non-neighbouring pm calculations */ + scheduler_addtask(sched, task_type_grav_mm, task_subtype_none, 0, 0, ci, + NULL, 0); + for (int cjd = cid + 1; cjd < nr_cells; ++cjd) { struct cell *cj = &cells[cjd]; @@ -1123,9 +1127,6 @@ void engine_make_gravity_tasks(struct engine *e) { if (cell_are_neighbours(ci, cj)) scheduler_addtask(sched, task_type_pair, task_subtype_grav, 0, 0, ci, cj, 1); - else - scheduler_addtask(sched, task_type_grav_mm, task_subtype_none, 0, 0, ci, - cj, 1); } } } @@ -1289,6 +1290,14 @@ void engine_link_gravity_tasks(struct engine *e) { const int nodeID = e->nodeID; const int nr_tasks = sched->nr_tasks; + /* Add one task gathering all the multipoles */ + struct task *gather = scheduler_addtask( + sched, task_type_grav_gather_m, task_subtype_none, 0, 0, NULL, NULL, 0); + + /* And one task performing the FFT */ + struct task *fft = scheduler_addtask(sched, task_type_grav_fft, + task_subtype_none, 0, 0, NULL, NULL, 0); + for (int k = 0; k < nr_tasks; k++) { /* Get a pointer to the task. */ @@ -1297,11 +1306,21 @@ void engine_link_gravity_tasks(struct engine *e) { /* Skip? */ if (t->skip) continue; + /* Multipole construction */ + if (t->type == task_type_grav_up) { + scheduler_addunlock(sched, t, gather); + scheduler_addunlock(sched, t, fft); + } + /* Long-range interaction */ if (t->type == task_type_grav_mm) { - engine_make_gravity_dependencies(sched, t, t->ci); - engine_make_gravity_dependencies(sched, t, t->cj); + /* Gather the multipoles --> mm interaction --> kick */ + scheduler_addunlock(sched, gather, t); + scheduler_addunlock(sched, t, t->ci->super->kick); + + /* init --> mm interaction */ + scheduler_addunlock(sched, t->ci->super->init, t); } /* Self-interaction? */ @@ -2205,6 +2224,8 @@ void engine_init_particles(struct engine *e) { mask |= 1 << task_type_grav_up; mask |= 1 << task_type_grav_mm; + mask |= 1 << task_type_grav_gather_m; + mask |= 1 << task_type_grav_fft; mask |= 1 << task_type_self; mask |= 1 << task_type_pair; mask |= 1 << task_type_sub; @@ -2342,6 +2363,8 @@ void engine_step(struct engine *e) { mask |= 1 << task_type_grav_up; mask |= 1 << task_type_grav_mm; + mask |= 1 << task_type_grav_gather_m; + mask |= 1 << task_type_grav_fft; mask |= 1 << task_type_self; mask |= 1 << task_type_pair; mask |= 1 << task_type_sub; diff --git a/src/runner.c b/src/runner.c index 772e0478c..bc4fab5b6 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1109,21 +1109,16 @@ void *runner_main(void *data) { case task_type_recv: runner_do_recv_cell(r, ci, 1); break; - /* case task_type_grav_pp: */ - /* if (t->cj == NULL) */ - /* runner_doself_grav(r, t->ci); */ - /* else */ - /* runner_dopair_grav(r, t->ci, t->cj); */ - /* break; */ case task_type_grav_mm: - runner_do_grav_mm(r, t->ci, t->cj); + runner_do_grav_mm(r, t->ci, 1); break; case task_type_grav_up: runner_do_grav_up(r, t->ci); break; - /* case task_type_grav_down: */ - /* runner_dograv_down(r, t->ci); */ - /* break; */ + case task_type_grav_gather_m: + break; + case task_type_grav_fft: + break; case task_type_grav_external: runner_do_grav_external(r, t->ci, 1); break; diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 2a9d12611..b4d06479d 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -444,14 +444,7 @@ static void runner_dosub_grav(struct runner *r, struct cell *ci, } } -static void runner_do_grav_mm(struct runner *r, struct cell *ci, - struct cell *cj) { - -#ifdef SANITY_CHECKS - if (cell_are_neighbours(ci, cj)) { - error("Non-neighbouring cells in mm task !"); - } -#endif +static void runner_do_grav_mm(struct runner *r, struct cell *ci, int timer) { #if ICHECK > 0 for (int pid = 0; pid < ci->gcount; pid++) { @@ -459,24 +452,30 @@ static void runner_do_grav_mm(struct runner *r, struct cell *ci, /* Get a hold of the ith part in ci. */ struct gpart *restrict gp = &ci->gparts[pid]; - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, cj->loc[0], - cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); - } - - for (int pid = 0; pid < cj->gcount; pid++) { - - /* Get a hold of the ith part in ci. */ - struct gpart *restrict gp = &cj->gparts[pid]; - if (gp->id == -ICHECK) message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, ci->loc[0], ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); } #endif - runner_dopair_grav_pm(r, ci, cj); - runner_dopair_grav_pm(r, cj, ci); + /* Recover the list of top-level cells */ + const struct engine *e = r->e; + struct cell *cells = e->s->cells; + const int nr_cells = e->s->nr_cells; + const int ti_current = e->ti_current; + + /* Anything to do here? */ + if (ci->ti_end_min > ti_current) return; + + /* Loop over all the cells and go for a p-m interaction if far enough */ + for (int i = 0; i < nr_cells; ++i) { + + struct cell *cj = &cells[i]; + + if (ci == cj) continue; + + if (!cell_are_neighbours(ci, cj)) runner_dopair_grav_pm(r, ci, cj); + } } #endif /* SWIFT_RUNNER_DOIACT_GRAV_H */ diff --git a/src/scheduler.c b/src/scheduler.c index 6dac16b40..3549e107c 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -520,10 +520,9 @@ void scheduler_splittasks(struct scheduler *s) { /* Get a handle on the cells involved. */ struct cell *ci = t->ci; - struct cell *cj = t->cj; /* Safety thing */ - if (ci->gcount == 0 || cj->gcount == 0) t->type = task_type_none; + if (ci->gcount == 0) t->type = task_type_none; } /* gravity interaction? */ diff --git a/src/task.c b/src/task.c index 8b0f0de8a..68e3f4ee9 100644 --- a/src/task.c +++ b/src/task.c @@ -47,10 +47,11 @@ /* Task type names. */ const char *taskID_names[task_type_count] = { - "none", "sort", "self", "pair", "sub", - "init", "ghost", "drift", "kick", "kick_fixdt", - "send", "recv", "grav_mm", "grav_up", "grav_external", - "part_sort", "gpart_sort", "split_cell", "rewait"}; + "none", "sort", "self", "pair", "sub", + "init", "ghost", "drift", "kick", "kick_fixdt", + "send", "recv", "grav_gather_m", "grav_fft", "grav_mm", + "grav_up", "grav_external", "part_sort", "gpart_sort", "split_cell", + "rewait"}; const char *subtaskID_names[task_type_count] = {"none", "density", "force", "grav"}; @@ -151,7 +152,6 @@ void task_unlock(struct task *t) { case task_type_grav_mm: cell_gunlocktree(ci); - cell_gunlocktree(cj); break; default: break; @@ -252,12 +252,7 @@ int task_lock(struct task *t) { break; case task_type_grav_mm: - if (ci->ghold || cj->ghold) return 0; if (cell_glocktree(ci) != 0) return 0; - if (cell_glocktree(cj) != 0) { - cell_gunlocktree(ci); - return 0; - } default: break; diff --git a/src/task.h b/src/task.h index bd0209d91..9f3429518 100644 --- a/src/task.h +++ b/src/task.h @@ -45,10 +45,10 @@ enum task_types { task_type_kick_fixdt, task_type_send, task_type_recv, - /* task_type_grav_pp, */ + task_type_grav_gather_m, + task_type_grav_fft, task_type_grav_mm, task_type_grav_up, - /* task_type_grav_down, */ task_type_grav_external, task_type_part_sort, task_type_gpart_sort, -- GitLab From 01f51f70e80953031006d3164cf608512e18f6d3 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 14 Jun 2016 19:08:17 +0100 Subject: [PATCH 53/72] Post-merge fixes --- src/engine.c | 35 ++++++++++++++++++++++++++++++----- src/partition.c | 3 +-- src/runner.c | 4 ++++ src/task.c | 5 ++++- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/engine.c b/src/engine.c index c18f9012d..ad2b5ef6a 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1265,6 +1265,23 @@ void engine_count_and_link_tasks(struct engine *e) { } } +/** + * @brief Creates the dependency network for the gravity tasks of a given cell. + * + * @param sched The #scheduler. + * @param gravity The gravity task to link. + * @param c The cell. + */ +static inline void engine_make_gravity_dependencies(struct scheduler *sched, + struct task *gravity, + struct cell *c) { + + /* init --> gravity --> kick */ + /* grav_up --> gravity ( --> kick) */ + scheduler_addunlock(sched, c->super->init, gravity); + scheduler_addunlock(sched, c->super->grav_up, gravity); + scheduler_addunlock(sched, gravity, c->super->kick); +} /** * @brief Creates all the task dependencies for the gravity @@ -1285,6 +1302,8 @@ void engine_link_gravity_tasks(struct engine *e) { struct task *fft = scheduler_addtask(sched, task_type_grav_fft, task_subtype_none, 0, 0, NULL, NULL, 0); + scheduler_addunlock(sched, gather, fft); + for (int k = 0; k < nr_tasks; k++) { /* Get a pointer to the task. */ @@ -1296,7 +1315,6 @@ void engine_link_gravity_tasks(struct engine *e) { /* Multipole construction */ if (t->type == task_type_grav_up) { scheduler_addunlock(sched, t, gather); - scheduler_addunlock(sched, t, fft); } /* Long-range interaction */ @@ -1332,15 +1350,22 @@ void engine_link_gravity_tasks(struct engine *e) { } - /* Otherwise, sub interaction? */ - else if (t->type == task_type_sub && t->subtype == task_subtype_grav) { + /* Otherwise, sub-self interaction? */ + else if (t->type == task_type_sub_self && t->subtype == task_subtype_grav) { + + if (t->ci->nodeID == nodeID) { + engine_make_gravity_dependencies(sched, t, t->ci); + } + } + + /* Otherwise, sub-pair interaction? */ + else if (t->type == task_type_sub_pair && t->subtype == task_subtype_grav) { if (t->ci->nodeID == nodeID) { engine_make_gravity_dependencies(sched, t, t->ci); } - if (t->cj != NULL && t->cj->nodeID == nodeID && - t->ci->super != t->cj->super) { + if (t->cj->nodeID == nodeID && t->ci->super != t->cj->super) { engine_make_gravity_dependencies(sched, t, t->cj); } diff --git a/src/partition.c b/src/partition.c index dbec9f7eb..6df437826 100644 --- a/src/partition.c +++ b/src/partition.c @@ -504,8 +504,7 @@ static void repart_edge_metis(int partweights, int bothweights, int nodeID, } /* Pair? */ - else if (t->type == task_type_pair || - (t->type == task_type_sub_pair)) { + else if (t->type == task_type_pair || (t->type == task_type_sub_pair)) { /* In-cell pair? */ if (ci == cj) { /* Add weight to vertex for ci. */ diff --git a/src/runner.c b/src/runner.c index ecbabb83c..f382b52df 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1087,6 +1087,8 @@ void *runner_main(void *data) { runner_dosub_self1_density(r, ci, 1); else if (t->subtype == task_subtype_force) runner_dosub_self2_force(r, ci, 1); + else if (t->subtype == task_subtype_grav) + runner_dosub_grav(r, ci, cj, 1); else error("Unknown task subtype."); break; @@ -1095,6 +1097,8 @@ void *runner_main(void *data) { runner_dosub_pair1_density(r, ci, cj, t->flags, 1); else if (t->subtype == task_subtype_force) runner_dosub_pair2_force(r, ci, cj, t->flags, 1); + else if (t->subtype == task_subtype_grav) + runner_dosub_grav(r, ci, cj, 1); else error("Unknown task subtype."); break; diff --git a/src/task.c b/src/task.c index 8cbbc1bd9..f3aa87400 100644 --- a/src/task.c +++ b/src/task.c @@ -142,7 +142,6 @@ void task_unlock(struct task *t) { } break; - case task_type_grav_mm: cell_gunlocktree(ci); break; @@ -218,6 +217,10 @@ int task_lock(struct task *t) { } break; + case task_type_grav_mm: + cell_glocktree(ci); + break; + default: break; } -- GitLab From f9e7f06126ddf9b5029e6f9f7ee36120d7069692 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 16 Jun 2016 11:02:18 +0100 Subject: [PATCH 54/72] First attempt at applying the long-range cutoff --- doc/Makefile.am | 18 ++++++++++++++++++ examples/Makefile.am | 1 - src/Makefile.am | 1 - src/engine.c | 3 ++- src/runner_doiact_grav.h | 23 +++++++++++++++++++---- src/tools.c | 16 +++++++++++++--- src/tools.h | 2 +- 7 files changed, 53 insertions(+), 11 deletions(-) diff --git a/doc/Makefile.am b/doc/Makefile.am index 1736a4ad8..2d7f38d99 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,3 +1,21 @@ +# This file is part of SWIFT. +# Copyright (c) 2012 pedro.gonnet@durham.ac.uk +# matthieu.schaller@durham.ac.uk. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Add the source directory and debug to CFLAGS doxyfile.stamp: if HAVE_DOXYGEN diff --git a/examples/Makefile.am b/examples/Makefile.am index 6ddb07fb7..95383c4b0 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,4 +1,3 @@ - # This file is part of SWIFT. # Copyright (c) 2012 Pedro Gonnet (pedro.gonnet@durham.ac.uk), # Matthieu Schaller (matthieu.schaller@durham.ac.uk). diff --git a/src/Makefile.am b/src/Makefile.am index a1ea5b0c8..af9d64410 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,3 @@ - # This file is part of SWIFT. # Copyright (c) 2012 Pedro Gonnet (pedro.gonnet@durham.ac.uk), # Matthieu Schaller (matthieu.schaller@durham.ac.uk). diff --git a/src/engine.c b/src/engine.c index ad2b5ef6a..ec50e7cb1 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2441,7 +2441,8 @@ void engine_step(struct engine *e) { /* Check the gravity accelerations */ struct gpart *temp = malloc(s->nr_gparts * sizeof(struct gpart)); memcpy(temp, s->gparts, s->nr_gparts * sizeof(struct gpart)); - gravity_n2(temp, s->nr_gparts, e->physical_constants); + const double rlr = const_gravity_a_smooth * s->cells[0].h[0]; + gravity_n2(temp, s->nr_gparts, e->physical_constants, rlr); file = fopen("grav_brute.dat", "w"); for (size_t k = 0; k < s->nr_gparts; ++k) { fprintf(file, "%lld %f %f %f %e %e %e\n", temp[k].id, temp[k].x[0], diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index b4d06479d..cf41c735e 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -72,7 +72,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( struct gpart *restrict gparts = ci->gparts; const struct multipole multi = cj->multipole; const int ti_current = e->ti_current; - const float rlr_inv = 1.f; + const float rlr_inv = 1. / (const_gravity_a_smooth * ci->super->h[0]); TIMER_TIC; @@ -138,7 +138,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( struct gpart *restrict gparts_i = ci->gparts; struct gpart *restrict gparts_j = cj->gparts; const int ti_current = e->ti_current; - const float rlr_inv = 1.f; + const float rlr_inv = 1. / (const_gravity_a_smooth * ci->super->h[0]); TIMER_TIC; @@ -230,7 +230,9 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( const int gcount = c->gcount; struct gpart *restrict gparts = c->gparts; const int ti_current = e->ti_current; - const float rlr_inv = 1.f; + const float rlr_inv = 1. / (const_gravity_a_smooth * c->super->h[0]); + + // message("rlr_inv= %f", rlr_inv); TIMER_TIC; @@ -463,18 +465,31 @@ static void runner_do_grav_mm(struct runner *r, struct cell *ci, int timer) { struct cell *cells = e->s->cells; const int nr_cells = e->s->nr_cells; const int ti_current = e->ti_current; + const double max_d = const_gravity_a_smooth * const_gravity_r_cut * ci->h[0]; + const double max_d2 = max_d * max_d; + const double pos_i[3] = {ci->loc[0], ci->loc[1], ci->loc[2]}; + + // message("max_d: %f", max_d); /* Anything to do here? */ if (ci->ti_end_min > ti_current) return; - /* Loop over all the cells and go for a p-m interaction if far enough */ + /* Loop over all the cells and go for a p-m interaction if far enough but not + * too far */ for (int i = 0; i < nr_cells; ++i) { struct cell *cj = &cells[i]; if (ci == cj) continue; + const double dx[3] = {cj->loc[0] - pos_i[0], // x + cj->loc[1] - pos_i[1], // y + cj->loc[2] - pos_i[2]}; // z + const double r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; + if (!cell_are_neighbours(ci, cj)) runner_dopair_grav_pm(r, ci, cj); + + if (r2 > max_d2) continue; } } diff --git a/src/tools.c b/src/tools.c index 743b28228..b5150ee53 100644 --- a/src/tools.c +++ b/src/tools.c @@ -491,7 +491,14 @@ void shuffle_particles(struct part *parts, const int count) { * @brief gcount The number of particles. */ void gravity_n2(struct gpart *gparts, const int gcount, - const struct phys_const *constants) { + const struct phys_const *constants, float rlr) { + + const float rlr_inv = 0.; // 1. / rlr; + const float max_d = const_gravity_r_cut * rlr; + const float max_d2 = max_d * max_d; + + message("rlr_inv= %f", rlr_inv); + message("max_d: %f", max_d); /* Reset everything */ for (int pid = 0; pid < gcount; pid++) { @@ -518,8 +525,11 @@ void gravity_n2(struct gpart *gparts, const int gcount, gpi->x[2] - gpj->x[2]}; // z const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; - /* Apply the gravitational acceleration. */ - runner_iact_grav_pp(0.f, r2, dx, gpi, gpj); + if (r2 < max_d2 || 1) { + + /* Apply the gravitational acceleration. */ + runner_iact_grav_pp(rlr_inv, r2, dx, gpi, gpj); + } } } diff --git a/src/tools.h b/src/tools.h index 0e6098020..38c0bb5e5 100644 --- a/src/tools.h +++ b/src/tools.h @@ -42,6 +42,6 @@ void pairs_n2(double *dim, struct part *__restrict__ parts, int N, double random_uniform(double a, double b); void shuffle_particles(struct part *parts, const int count); void gravity_n2(struct gpart *gparts, const int gcount, - const struct phys_const *constants); + const struct phys_const *constants, float rlr); #endif /* SWIFT_TOOL_H */ -- GitLab From d5b0d5b5153c9c009f2da11a1e5e68bb65f1671a Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 16 Jun 2016 19:18:19 +0100 Subject: [PATCH 55/72] Added unit test for long-range gravity forces --- tests/testKernelGrav.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/tests/testKernelGrav.c b/tests/testKernelGrav.c index c05d15bcb..42ce6066b 100644 --- a/tests/testKernelGrav.c +++ b/tests/testKernelGrav.c @@ -17,14 +17,16 @@ * along with this program. If not, see . * ******************************************************************************/ +#include "const.h" #include "kernel_gravity.h" +#include "kernel_long_gravity.h" #include #include #include #include -#define numPoints (1 << 6) +#define numPoints (1 << 7) /** * @brief The Gadget-2 gravity kernel function @@ -54,7 +56,7 @@ float gadget(float r, float h) { int main() { const float h = 3.f; - const float r_max = 5.f; + const float r_max = 6.f; for (int k = 1; k < numPoints; ++k) { @@ -82,5 +84,29 @@ int main() { } printf("\nAll values are consistent\n"); + + /* Now test the long range function */ + const float a_smooth = const_gravity_a_smooth; + + for (int k = 1; k < numPoints; ++k) { + + const float r = (r_max * k) / numPoints; + + const float u = r / a_smooth; + + float swift_w; + kernel_long_grav_eval(u, &swift_w); + + float gadget_w = erfc(u / 2) + u * exp(-u * u / 4) / sqrt(M_PI); + + printf("%2d: r= %f r_lr= %f u= %f Ws(r)= %f Wg(r)= %f\n", k, r, a_smooth, u, + swift_w, gadget_w); + + if (fabsf(gadget_w - swift_w) > 2e-7) { + printf("Invalid value ! Gadget= %e, SWIFT= %e\n", gadget_w, swift_w); + return 1; + } + } + return 0; } -- GitLab From 50c3e8250ef2143e6f175b6cde1dc347449c4aa3 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 29 Jun 2016 21:42:32 +0100 Subject: [PATCH 56/72] Long range forces OK --- src/engine.c | 5 +++-- src/gravity/Default/gravity.h | 2 +- src/gravity/Default/gravity_iact.h | 17 +++++++++++------ src/runner_doiact_grav.h | 6 ++++-- src/tools.c | 2 +- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/engine.c b/src/engine.c index 5d8dd1ac1..727f9fa8f 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1343,10 +1343,11 @@ static inline void engine_make_gravity_dependencies(struct scheduler *sched, struct cell *c) { /* init --> gravity --> kick */ - /* grav_up --> gravity ( --> kick) */ scheduler_addunlock(sched, c->super->init, gravity); - scheduler_addunlock(sched, c->super->grav_up, gravity); scheduler_addunlock(sched, gravity, c->super->kick); + + /* grav_up --> gravity ( --> kick) */ + scheduler_addunlock(sched, c->super->grav_up, gravity); } /** diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h index 7349ad8e2..e3a181ceb 100644 --- a/src/gravity/Default/gravity.h +++ b/src/gravity/Default/gravity.h @@ -77,7 +77,7 @@ gravity_compute_timestep_self(const struct phys_const* const phys_const, */ __attribute__((always_inline)) INLINE static void gravity_first_init_gpart( struct gpart* gp) { - gp->epsilon = 0.1; // MATTHIEU + gp->epsilon = 0.; // MATTHIEU } /** diff --git a/src/gravity/Default/gravity_iact.h b/src/gravity/Default/gravity_iact.h index 2b3dfc855..048d47e73 100644 --- a/src/gravity/Default/gravity_iact.h +++ b/src/gravity/Default/gravity_iact.h @@ -147,14 +147,19 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pm( /* Apply the gravitational acceleration. */ const float r = sqrtf(r2); const float ir = 1.f / r; + const float u = r * rlr_inv; const float mrinv3 = multi->mass * ir * ir * ir; + /* Get long-range correction */ + float f_lr; + kernel_long_grav_eval(u, &f_lr); + #if const_gravity_multipole_order < 2 /* 0th and 1st order terms */ - gp->a_grav[0] += mrinv3 * dx[0]; - gp->a_grav[1] += mrinv3 * dx[1]; - gp->a_grav[2] += mrinv3 * dx[2]; + gp->a_grav[0] += mrinv3 * f_lr * dx[0]; + gp->a_grav[1] += mrinv3 * f_lr * dx[1]; + gp->a_grav[2] += mrinv3 * f_lr * dx[2]; gp->mass_interacted += multi->mass; #elif const_gravity_multipole_order == 2 @@ -178,9 +183,9 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pm( const float qRR = qRx * dx[0] + qRy * dx[1] + qRz * dx[2]; const float C = D1 + 0.5f * D2 * q + 0.5f * D3 * qRR; - gp->a_grav[0] -= C * dx[0] + D2 * qRx; - gp->a_grav[1] -= C * dx[1] + D2 * qRy; - gp->a_grav[2] -= C * dx[2] + D2 * qRz; + gp->a_grav[0] -= f_lr * (C * dx[0] + D2 * qRx); + gp->a_grav[1] -= f_lr * (C * dx[1] + D2 * qRy); + gp->a_grav[2] -= f_lr * (C * dx[2] + D2 * qRz); gp->mass_interacted += multi->mass; #else diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index cf41c735e..f6bced124 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -76,6 +76,8 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( TIMER_TIC; +// message("rlr_inv= %f", rlr_inv); + #ifdef SANITY_CHECKS if (gcount == 0) error("Empty cell!"); // MATTHIEU sanity check @@ -487,9 +489,9 @@ static void runner_do_grav_mm(struct runner *r, struct cell *ci, int timer) { cj->loc[2] - pos_i[2]}; // z const double r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; - if (!cell_are_neighbours(ci, cj)) runner_dopair_grav_pm(r, ci, cj); - if (r2 > max_d2) continue; + + if (!cell_are_neighbours(ci, cj)) runner_dopair_grav_pm(r, ci, cj); } } diff --git a/src/tools.c b/src/tools.c index f655e5e14..a60c78510 100644 --- a/src/tools.c +++ b/src/tools.c @@ -496,7 +496,7 @@ void shuffle_particles(struct part *parts, const int count) { void gravity_n2(struct gpart *gparts, const int gcount, const struct phys_const *constants, float rlr) { - const float rlr_inv = 0.; // 1. / rlr; + const float rlr_inv = 1. / rlr; const float max_d = const_gravity_r_cut * rlr; const float max_d2 = max_d * max_d; -- GitLab From c9b3f3f5ebe23a389f944ccb7011f230d93392d9 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 29 Jun 2016 23:12:13 +0100 Subject: [PATCH 57/72] Attach the hierarchical tasks at the right level --- src/engine.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine.c b/src/engine.c index 727f9fa8f..79bcd3ec2 100644 --- a/src/engine.c +++ b/src/engine.c @@ -130,7 +130,7 @@ void engine_make_gravity_hierarchical_tasks(struct engine *e, struct cell *c, const int is_fixdt = (e->policy & engine_policy_fixdt) == engine_policy_fixdt; /* Is this the super-cell? */ - if (super == NULL && (c->grav != NULL || (c->gcount > 0 && !c->split))) { + if (super == NULL && (c->grav != NULL || (c->gcount > 0 && c->split))) { /* This is the super cell, i.e. the first with gravity tasks attached. */ super = c; @@ -192,7 +192,7 @@ void engine_make_hydro_hierarchical_tasks(struct engine *e, struct cell *c, const int is_fixdt = (e->policy & engine_policy_fixdt) == engine_policy_fixdt; /* Is this the super-cell? */ - if (super == NULL && (c->density != NULL || (c->count > 0 && !c->split))) { + if (super == NULL && (c->density != NULL || (c->count > 0 && c->split))) { /* This is the super cell, i.e. the first with density tasks attached. */ super = c; -- GitLab From 8d3bf0c410de3aabf54633c5696b727998652b0b Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 30 Jun 2016 14:32:03 +0100 Subject: [PATCH 58/72] Post-merge fixes --- src/engine.c | 10 +++++----- src/runner.c | 4 ++-- src/space.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/engine.c b/src/engine.c index 7f4361d07..1dd6b62ae 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2504,11 +2504,11 @@ void engine_step(struct engine *e) { FILE *file = fopen("grav_swift.dat", "w"); for (size_t k = 0; k < s->nr_gparts; ++k) { - fprintf(file, "%lld %f %f %f %e %e %e\n", s->gparts[k].id, + fprintf(file, "%lld %f %f %f %e %e %e\n", s->gparts[k].id_or_neg_offset, s->gparts[k].x[0], s->gparts[k].x[1], s->gparts[k].x[2], s->gparts[k].a_grav[0], s->gparts[k].a_grav[1], s->gparts[k].a_grav[2]); - if (s->gparts[k].id == -1) + if (s->gparts[k].id_or_neg_offset == 1) message("interacting mass= %f (%f)", s->gparts[k].mass_interacted, s->gparts[k].mass_interacted + s->gparts[k].mass); } @@ -2521,9 +2521,9 @@ void engine_step(struct engine *e) { gravity_n2(temp, s->nr_gparts, e->physical_constants, rlr); file = fopen("grav_brute.dat", "w"); for (size_t k = 0; k < s->nr_gparts; ++k) { - fprintf(file, "%lld %f %f %f %e %e %e\n", temp[k].id, temp[k].x[0], - temp[k].x[1], temp[k].x[2], temp[k].a_grav[0], temp[k].a_grav[1], - temp[k].a_grav[2]); + fprintf(file, "%lld %f %f %f %e %e %e\n", temp[k].id_or_neg_offset, + temp[k].x[0], temp[k].x[1], temp[k].x[2], temp[k].a_grav[0], + temp[k].a_grav[1], temp[k].a_grav[2]); } fclose(file); diff --git a/src/runner.c b/src/runner.c index 88df1824f..e4d2a0a82 100644 --- a/src/runner.c +++ b/src/runner.c @@ -414,8 +414,8 @@ void runner_do_init(struct runner *r, struct cell *c, int timer) { /* Get ready for a density calculation */ gravity_init_part(gp); - if (gp->id == -ICHECK) - message("id=%lld a=[%f %f %f]\n", gp->id, gp->a_grav[0], + if (gp->id_or_neg_offset == ICHECK) + message("id=%lld a=[%f %f %f]\n", gp->id_or_neg_offset, gp->a_grav[0], gp->a_grav[1], gp->a_grav[2]); } } diff --git a/src/space.c b/src/space.c index 12147cf29..62915f912 100644 --- a/src/space.c +++ b/src/space.c @@ -1427,7 +1427,8 @@ struct cell *space_getcell(struct space *s) { * @param Npart The number of Gas particles in the space. * @param Ngpart The number of Gravity particles in the space. * @param periodic flag whether the domain is periodic or not. - * @param verbose Print messages to stdout or not + * @param gravity flag whether we are doing gravity or not. + * @param verbose Print messages to stdout or not. * @param dry_run If 1, just initialise stuff, don't do anything with the parts. * * Makes a grid of edge length > r_max and fills the particles -- GitLab From ee15a02ee6ffc8793cfb065b7303ae891116637c Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 30 Jun 2016 14:44:26 +0100 Subject: [PATCH 59/72] Uniform debugging #defines --- doc/Makefile.am | 4 +-- src/cell.c | 2 +- src/const.h | 1 - src/runner_doiact_grav.h | 67 ++++++++++++++++++++++------------------ 4 files changed, 40 insertions(+), 34 deletions(-) diff --git a/doc/Makefile.am b/doc/Makefile.am index 0470bda78..dc88489ca 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,6 +1,6 @@ # This file is part of SWIFT. -# Copyright (c) 2012 pedro.gonnet@durham.ac.uk -# matthieu.schaller@durham.ac.uk. +# Copyright (c) 2012 Pedro Gonnet (pedro.gonnet@durham.ac.uk), +# Matthieu Schaller (matthieu.schaller@durham.ac.uk). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/src/cell.c b/src/cell.c index d1952ff7e..6ed91aa5a 100644 --- a/src/cell.c +++ b/src/cell.c @@ -685,7 +685,7 @@ void cell_clean_links(struct cell *c, void *data) { int cell_are_neighbours(const struct cell *restrict ci, const struct cell *restrict cj) { -#ifdef SANITY_CHECKS +#ifdef SWIFT_DEBUG_CHECKS if (ci->h[0] != cj->h[0]) error("Cells of different size !"); #endif diff --git a/src/const.h b/src/const.h index c5b053c30..ca89b61f7 100644 --- a/src/const.h +++ b/src/const.h @@ -63,6 +63,5 @@ /* Are we debugging ? */ //#define SWIFT_DEBUG_CHECKS -#define SANITY_CHECKS #endif /* SWIFT_CONST_H */ diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index f6bced124..38094389c 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -25,7 +25,7 @@ #include "gravity.h" #include "part.h" -#define ICHECK -1 +#define ICHECK 1000 /** * @brief Compute the recursive upward sweep, i.e. construct the @@ -78,7 +78,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( // message("rlr_inv= %f", rlr_inv); -#ifdef SANITY_CHECKS +#ifdef SWIFT_DEBUG_CHECKS if (gcount == 0) error("Empty cell!"); // MATTHIEU sanity check if (multi.mass == 0.0) // MATTHIEU sanity check @@ -94,9 +94,10 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( /* Get a hold of the ith part in ci. */ struct gpart *restrict gp = &gparts[pid]; - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, cj->loc[0], - cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); + if (gp->id_or_neg_offset == ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", + gp->id_or_neg_offset, cj->loc[0], cj->loc[1], cj->loc[2], + cj->h[0], cj->gcount); } #endif @@ -144,7 +145,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( TIMER_TIC; -#ifdef SANITY_CHECKS +#ifdef SWIFT_DEBUG_CHECKS if (ci->h[0] != cj->h[0]) // MATTHIEU sanity check error("Non matching cell sizes !! h_i=%f h_j=%f", ci->h[0], cj->h[0]); #endif @@ -158,9 +159,10 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( /* Get a hold of the ith part in ci. */ struct gpart *restrict gp = &gparts_i[pid]; - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, cj->loc[0], - cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); + if (gp->id_or_neg_offset == ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", + gp->id_or_neg_offset, cj->loc[0], cj->loc[1], cj->loc[2], + cj->h[0], cj->gcount); } for (int pid = 0; pid < gcount_j; pid++) { @@ -168,9 +170,10 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( /* Get a hold of the ith part in ci. */ struct gpart *restrict gp = &gparts_j[pid]; - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count=%d", gp->id, ci->loc[0], - ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); + if (gp->id_or_neg_offset == ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count=%d", + gp->id_or_neg_offset, ci->loc[0], ci->loc[1], ci->loc[2], + ci->h[0], ci->gcount); } #endif @@ -238,7 +241,7 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( TIMER_TIC; -#ifdef SANITY_CHECKS +#ifdef SWIFT_DEBUG_CHECKS if (c->gcount == 0) // MATTHIEU sanity check error("Empty cell !"); #endif @@ -252,9 +255,10 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( /* Get a hold of the ith part in ci. */ struct gpart *restrict gp = &gparts[pid]; - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, c->loc[0], - c->loc[1], c->loc[2], c->h[0], c->gcount); + if (gp->id_or_neg_offset == ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", + gp->id_or_neg_offset, c->loc[0], c->loc[1], c->loc[2], c->h[0], + c->gcount); } #endif @@ -314,7 +318,7 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( static void runner_dopair_grav(struct runner *r, struct cell *ci, struct cell *cj) { -#ifdef SANITY_CHECKS +#ifdef SWIFT_DEBUG_CHECKS const int gcount_i = ci->gcount; const int gcount_j = cj->gcount; @@ -343,24 +347,26 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, #endif #if ICHECK > 0 - for (int pid = 0; pid < gcount_i; pid++) { + for (int pid = 0; pid < ci->gcount; pid++) { /* Get a hold of the ith part in ci. */ struct gpart *restrict gp = &ci->gparts[pid]; - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, cj->loc[0], - cj->loc[1], cj->loc[2], cj->h[0], cj->gcount); + if (gp->id_or_neg_offset == ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", + gp->id_or_neg_offset, cj->loc[0], cj->loc[1], cj->loc[2], + cj->h[0], cj->gcount); } - for (int pid = 0; pid < gcount_j; pid++) { + for (int pid = 0; pid < cj->gcount; pid++) { /* Get a hold of the ith part in ci. */ struct gpart *restrict gp = &cj->gparts[pid]; - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, ci->loc[0], - ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); + if (gp->id_or_neg_offset == ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", + gp->id_or_neg_offset, ci->loc[0], ci->loc[1], ci->loc[2], + ci->h[0], ci->gcount); } #endif @@ -397,7 +403,7 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, static void runner_doself_grav(struct runner *r, struct cell *c) { -#ifdef SANITY_CHECKS +#ifdef SWIFT_DEBUG_CHECKS /* Early abort? */ if (c->gcount == 0) error("Empty cell !"); @@ -439,7 +445,7 @@ static void runner_dosub_grav(struct runner *r, struct cell *ci, } else { -#ifdef SANITY_CHECKS +#ifdef SWIFT_DEBUG_CHECKS if (!cell_are_neighbours(ci, cj)) error("Non-neighbouring cells in pair task !"); #endif @@ -456,9 +462,10 @@ static void runner_do_grav_mm(struct runner *r, struct cell *ci, int timer) { /* Get a hold of the ith part in ci. */ struct gpart *restrict gp = &ci->gparts[pid]; - if (gp->id == -ICHECK) - message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id, ci->loc[0], - ci->loc[1], ci->loc[2], ci->h[0], ci->gcount); + if (gp->id_or_neg_offset == ICHECK) + message("id=%lld loc=[ %f %f %f ] size= %f count= %d", + gp->id_or_neg_offset, ci->loc[0], ci->loc[1], ci->loc[2], + ci->h[0], ci->gcount); } #endif -- GitLab From 50468e0795a88957144451d6baac0aa9707756c6 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Fri, 1 Jul 2016 21:09:27 +0100 Subject: [PATCH 60/72] No commented out debugging messages --- src/runner_doiact_grav.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 38094389c..59910c135 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -25,7 +25,7 @@ #include "gravity.h" #include "part.h" -#define ICHECK 1000 +#define ICHECK -1000 /** * @brief Compute the recursive upward sweep, i.e. construct the @@ -76,8 +76,6 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( TIMER_TIC; -// message("rlr_inv= %f", rlr_inv); - #ifdef SWIFT_DEBUG_CHECKS if (gcount == 0) error("Empty cell!"); // MATTHIEU sanity check @@ -237,8 +235,6 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( const int ti_current = e->ti_current; const float rlr_inv = 1. / (const_gravity_a_smooth * c->super->h[0]); - // message("rlr_inv= %f", rlr_inv); - TIMER_TIC; #ifdef SWIFT_DEBUG_CHECKS @@ -478,8 +474,6 @@ static void runner_do_grav_mm(struct runner *r, struct cell *ci, int timer) { const double max_d2 = max_d * max_d; const double pos_i[3] = {ci->loc[0], ci->loc[1], ci->loc[2]}; - // message("max_d: %f", max_d); - /* Anything to do here? */ if (ci->ti_end_min > ti_current) return; -- GitLab From c8eaa44f8a56f04a6760ef0655df6f7bdbebc8f4 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Fri, 1 Jul 2016 21:30:05 +0100 Subject: [PATCH 61/72] Added treatment of timers in the gravity interaction functions. --- src/runner.c | 6 +++--- src/runner_doiact_grav.h | 38 ++++++++++++++++++++++++++++---------- src/timers.h | 5 +++-- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/runner.c b/src/runner.c index e4d2a0a82..1682916c5 100644 --- a/src/runner.c +++ b/src/runner.c @@ -60,7 +60,7 @@ /* Orientation of the cell pairs */ const double runner_shift[13][3] = { {5.773502691896258e-01, 5.773502691896258e-01, 5.773502691896258e-01}, - {7.071067811865475e-01, 7.071067811865475e-01, 0.0}, + {7.01067811865475e-01, 7.071067811865475e-01, 0.0}, {5.773502691896258e-01, 5.773502691896258e-01, -5.773502691896258e-01}, {7.071067811865475e-01, 0.0, 7.071067811865475e-01}, {1.0, 0.0, 0.0}, @@ -1063,7 +1063,7 @@ void *runner_main(void *data) { else if (t->subtype == task_subtype_force) runner_doself2_force(r, ci); else if (t->subtype == task_subtype_grav) - runner_doself_grav(r, ci); + runner_doself_grav(r, ci, 1); else error("Unknown task subtype."); break; @@ -1073,7 +1073,7 @@ void *runner_main(void *data) { else if (t->subtype == task_subtype_force) runner_dopair2_force(r, ci, cj); else if (t->subtype == task_subtype_grav) - runner_dopair_grav(r, ci, cj); + runner_dopair_grav(r, ci, cj, 1); else error("Unknown task subtype."); break; diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 59910c135..ae6607ecd 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -117,7 +117,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( runner_iact_grav_pm(rlr_inv, r2, dx, gp, &multi); } - TIMER_TOC(TIMER_DOPAIR); // MATTHIEU + TIMER_TOC(timer_dopair_grav_pm); } /** @@ -215,7 +215,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( } } - TIMER_TOC(TIMER_DOPAIR); // MATTHIEU + TIMER_TOC(timer_dopair_grav_pp); } /** @@ -298,7 +298,7 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( } } - TIMER_TOC(TIMER_DOSELF); // MATTHIEU + TIMER_TOC(timer_doself_grav_pp); } /** @@ -308,11 +308,12 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( * @param r The #runner. * @param ci The first #cell. * @param cj The other #cell. + * @param gettimer Are we timing this ? * * @todo Use a local cache for the particles. */ static void runner_dopair_grav(struct runner *r, struct cell *ci, - struct cell *cj) { + struct cell *cj, int gettimer) { #ifdef SWIFT_DEBUG_CHECKS @@ -366,6 +367,8 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, } #endif + TIMER_TIC; + /* Are both cells split ? */ if (ci->split && cj->split) { @@ -378,7 +381,7 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, if (cell_are_neighbours(ci->progeny[j], cj->progeny[k])) { /* Recurse */ - runner_dopair_grav(r, ci->progeny[j], cj->progeny[k]); + runner_dopair_grav(r, ci->progeny[j], cj->progeny[k], 0); } else { @@ -395,9 +398,20 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, /* Compute the interactions at this level directly. */ runner_dopair_grav_pp(r, ci, cj); } + + if (gettimer) TIMER_TOC(timer_dosub_pair_grav); } -static void runner_doself_grav(struct runner *r, struct cell *c) { +/** + * @brief Computes the interaction of all the particles in a cell + * + * @param r The #runner. + * @param c The first #cell. + * @param gettimer Are we timing this ? + * + * @todo Use a local cache for the particles. + */ +static void runner_doself_grav(struct runner *r, struct cell *c, int gettimer) { #ifdef SWIFT_DEBUG_CHECKS @@ -405,6 +419,8 @@ static void runner_doself_grav(struct runner *r, struct cell *c) { if (c->gcount == 0) error("Empty cell !"); #endif + TIMER_TIC; + /* If the cell is split, interact each progeny with itself, and with each of its siblings. */ if (c->split) { @@ -412,12 +428,12 @@ static void runner_doself_grav(struct runner *r, struct cell *c) { for (int j = 0; j < 8; j++) { if (c->progeny[j] != NULL) { - runner_doself_grav(r, c->progeny[j]); + runner_doself_grav(r, c->progeny[j], 0); for (int k = j + 1; k < 8; k++) { if (c->progeny[k] != NULL) { - runner_dopair_grav(r, c->progeny[j], c->progeny[k]); + runner_dopair_grav(r, c->progeny[j], c->progeny[k], 0); } } } @@ -429,6 +445,8 @@ static void runner_doself_grav(struct runner *r, struct cell *c) { runner_doself_grav_pp(r, c); } + + if (gettimer) TIMER_TOC(timer_dosub_self_grav); } static void runner_dosub_grav(struct runner *r, struct cell *ci, @@ -437,7 +455,7 @@ static void runner_dosub_grav(struct runner *r, struct cell *ci, /* Is this a single cell? */ if (cj == NULL) { - runner_doself_grav(r, ci); + runner_doself_grav(r, ci, 1); } else { @@ -446,7 +464,7 @@ static void runner_dosub_grav(struct runner *r, struct cell *ci, error("Non-neighbouring cells in pair task !"); #endif - runner_dopair_grav(r, ci, cj); + runner_dopair_grav(r, ci, cj, 1); } } diff --git a/src/timers.h b/src/timers.h index c48961b39..aa8455397 100644 --- a/src/timers.h +++ b/src/timers.h @@ -37,10 +37,11 @@ enum { timer_dosort, timer_doself_density, timer_doself_force, - timer_doself_grav, + timer_doself_grav_pp, timer_dopair_density, timer_dopair_force, - timer_dopair_grav, + timer_dopair_grav_pm, + timer_dopair_grav_pp, timer_dograv_external, timer_dosub_self_density, timer_dosub_self_force, -- GitLab From 03a2b590d24b514a6da16034e3065b30ff3052cd Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Fri, 1 Jul 2016 21:49:04 +0100 Subject: [PATCH 62/72] Added files for the FFT calculation --- src/Makefile.am | 7 ++++--- src/runner.c | 2 ++ src/runner_doiact_fft.c | 35 +++++++++++++++++++++++++++++++++++ src/runner_doiact_fft.h | 26 ++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 src/runner_doiact_fft.c create mode 100644 src/runner_doiact_fft.h diff --git a/src/Makefile.am b/src/Makefile.am index af9d64410..ebdf9d81f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,12 +42,13 @@ 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_hydro.c tools.c part.c partition.c clocks.c parser.c \ - physical_constants.c potentials.c hydro_properties.c + physical_constants.c potentials.c hydro_properties.c \ + runner_doiact_fft.c # Include files for distribution, not installation. nobase_noinst_HEADERS = approx_math.h atomic.h cycle.h error.h inline.h kernel_hydro.h kernel_gravity.h \ - kernel_long_gravity.h vector.h runner_doiact.h runner_doiact_grav.h units.h intrinsics.h \ - minmax.h kick.h timestep.h drift.h \ + kernel_long_gravity.h vector.h runner_doiact.h runner_doiact_grav.h runner_doiact_fft.h \ + units.h intrinsics.h minmax.h kick.h timestep.h drift.h \ gravity.h gravity_io.h \ gravity/Default/gravity.h gravity/Default/gravity_iact.h gravity/Default/gravity_io.h \ gravity/Default/gravity_debug.h gravity/Default/gravity_part.h \ diff --git a/src/runner.c b/src/runner.c index 1682916c5..9bfa13ce8 100644 --- a/src/runner.c +++ b/src/runner.c @@ -89,6 +89,7 @@ const char runner_flip[27] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* Import the gravity loop functions. */ #include "runner_doiact_grav.h" +#include "runner_doiact_fft.h" /** * @brief Calculate gravity acceleration from external potential @@ -1129,6 +1130,7 @@ void *runner_main(void *data) { case task_type_grav_gather_m: break; case task_type_grav_fft: + runner_do_grav_fft(r); break; case task_type_grav_external: runner_do_grav_external(r, t->ci, 1); diff --git a/src/runner_doiact_fft.c b/src/runner_doiact_fft.c new file mode 100644 index 000000000..f7407caf0 --- /dev/null +++ b/src/runner_doiact_fft.c @@ -0,0 +1,35 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + ******************************************************************************/ + +/* Config parameters. */ +#include "../config.h" + +/* Some standard headers. */ +#include + +/* This object's header. */ +#include "runner_doiact_fft.h" + +/* Local includes. */ +#include "runner.h" + +void runner_do_grav_fft(struct runner *r) { + + +} diff --git a/src/runner_doiact_fft.h b/src/runner_doiact_fft.h new file mode 100644 index 000000000..263662383 --- /dev/null +++ b/src/runner_doiact_fft.h @@ -0,0 +1,26 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + ******************************************************************************/ +#ifndef SWIFT_RUNNER_DOIACT_FFT_H +#define SWIFT_RUNNER_DOIACT_FFT_H + +struct runner; + +void runner_do_grav_fft(struct runner *r); + +#endif /* SWIFT_RUNNER_DOIACT_FFT_H */ -- GitLab From f03c87cfabd19a5b83481d29e637aa6c716bef53 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 6 Jul 2016 10:21:21 +0300 Subject: [PATCH 63/72] Include the library --- src/runner_doiact_fft.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/runner_doiact_fft.c b/src/runner_doiact_fft.c index f7407caf0..6333ecd71 100644 --- a/src/runner_doiact_fft.c +++ b/src/runner_doiact_fft.c @@ -23,6 +23,10 @@ /* Some standard headers. */ #include +#ifdef HAVE_FFTW +#include +#endif + /* This object's header. */ #include "runner_doiact_fft.h" -- GitLab From 17f83e5838202571d339d95f5feb4e968454046d Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 6 Jul 2016 10:38:50 +0300 Subject: [PATCH 64/72] Post-merge fixes --- src/engine.c | 8 ++++---- src/runner.c | 4 ++-- src/runner_doiact_fft.c | 5 +---- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/engine.c b/src/engine.c index 4c3fd9e2c..1f3913e16 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1731,12 +1731,13 @@ void engine_maketasks(struct engine *e) { /* Loop through the proxy's incoming cells and add the recv tasks. */ for (int k = 0; k < p->nr_cells_in; k++) - engine_addtasks_recv(e, p->cells_in[k], NULL, NULL); + engine_addtasks_recv(e, p->cells_in[k], NULL, NULL, NULL); /* Loop through the proxy's outgoing cells and add the send tasks. */ for (int k = 0; k < p->nr_cells_out; k++) - engine_addtasks_send(e, p->cells_out[k], p->cells_in[0]); + engine_addtasks_send(e, p->cells_out[k], p->cells_in[0], NULL, NULL, + NULL); } } #endif @@ -1869,8 +1870,7 @@ int engine_marktasks(struct engine *e) { continue; /* Set the sort flags. */ - if (t->type == task_type_pair && - t->subtype != task_subtype_grav) { + if (t->type == task_type_pair && t->subtype != task_subtype_grav) { if (!(ci->sorted & (1 << t->flags))) { ci->sorts->flags |= (1 << t->flags); ci->sorts->skip = 0; diff --git a/src/runner.c b/src/runner.c index 9ef51240a..c58e94645 100644 --- a/src/runner.c +++ b/src/runner.c @@ -88,8 +88,8 @@ const char runner_flip[27] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, #include "runner_doiact.h" /* Import the gravity loop functions. */ -#include "runner_doiact_grav.h" #include "runner_doiact_fft.h" +#include "runner_doiact_grav.h" /** * @brief Calculate gravity acceleration from external potential @@ -1155,7 +1155,7 @@ void *runner_main(void *data) { case task_type_grav_gather_m: break; case task_type_grav_fft: - runner_do_grav_fft(r); + runner_do_grav_fft(r); break; case task_type_grav_external: runner_do_grav_external(r, t->ci, 1); diff --git a/src/runner_doiact_fft.c b/src/runner_doiact_fft.c index 6333ecd71..e735b2b99 100644 --- a/src/runner_doiact_fft.c +++ b/src/runner_doiact_fft.c @@ -33,7 +33,4 @@ /* Local includes. */ #include "runner.h" -void runner_do_grav_fft(struct runner *r) { - - -} +void runner_do_grav_fft(struct runner *r) {} -- GitLab From 6c8d4731197897a8cf868fd8766925d44717a99d Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 14 Jul 2016 12:56:57 +0100 Subject: [PATCH 65/72] Get FFTW version --- src/common_io.c | 3 +++ src/version.c | 23 +++++++++++++++++++++++ src/version.h | 3 ++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/common_io.c b/src/common_io.c index 971fe6b01..fcb6ed286 100644 --- a/src/common_io.c +++ b/src/common_io.c @@ -314,6 +314,9 @@ void writeCodeDescription(hid_t h_file) { writeAttribute_s(h_grpcode, "Git Branch", git_branch()); writeAttribute_s(h_grpcode, "Git Revision", git_revision()); writeAttribute_s(h_grpcode, "HDF5 library version", hdf5_version()); +#ifdef HAVE_FFTW + writeAttribute_s(h_grpcode, "FFTW library version", fftw3_version()); +#endif #ifdef WITH_MPI writeAttribute_s(h_grpcode, "MPI library", mpi_version()); #ifdef HAVE_METIS diff --git a/src/version.c b/src/version.c index ab22c0d9a..122a11f64 100644 --- a/src/version.c +++ b/src/version.c @@ -33,6 +33,10 @@ #include #endif +#ifdef HAVE_FFTW +#include +#endif + /* Some standard headers. */ #include #include @@ -238,6 +242,22 @@ const char *metis_version(void) { return version; } +/** + * @brief return the FFTW version used when SWIFT was built. + * + * @result description of the FFTW version. + */ +const char *fftw3_version(void) { + + static char version[256] = {0}; +#if defined(HAVE_FFTW) + sprintf(version, "%s", "3.x (details not available)"); +#else + sprintf(version, "Unknown version"); +#endif + return version; +} + /** * @brief Prints a greeting message to the standard output containing code * version and revision number @@ -259,6 +279,9 @@ void greetings(void) { #ifdef HAVE_HDF5 printf(" HDF5 library version: %s\n", hdf5_version()); #endif +#ifdef HAVE_FFTW + printf(" FFTW library version: %s\n", fftw3_version()); +#endif #ifdef WITH_MPI printf(" MPI library: %s\n", mpi_version()); #ifdef HAVE_METIS diff --git a/src/version.h b/src/version.h index 4b6b38d22..0d568f312 100644 --- a/src/version.h +++ b/src/version.h @@ -27,8 +27,9 @@ const char* git_branch(void); const char* compiler_name(void); const char* compiler_version(void); const char* mpi_version(void); -const char* hdf5_version(void); const char* metis_version(void); +const char* hdf5_version(void); +const char* fftw3_version(void); void greetings(void); #endif /* SWIFT_VERSION_H */ -- GitLab From 0bdc3a3cf95b539a5f094a88bf5f333152bf366d Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 18 Jul 2016 14:59:52 +0100 Subject: [PATCH 66/72] Test for the FFT --- .gitignore | 1 + tests/Makefile.am | 10 ++- tests/testFFT.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+), 3 deletions(-) create mode 100644 tests/testFFT.c diff --git a/.gitignore b/.gitignore index ea50fa7fe..f7ae5cbb8 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,7 @@ tests/testKernel tests/testKernelGrav tests/testParser tests/parser_output.yml +tests/testFFT theory/latex/swift.pdf theory/kernel/kernels.pdf diff --git a/tests/Makefile.am b/tests/Makefile.am index e7fdec264..b06e40e66 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -18,15 +18,17 @@ AM_CFLAGS = -I../src $(HDF5_CPPFLAGS) -DTIMER -AM_LDFLAGS = ../src/.libs/libswiftsim.a $(HDF5_LDFLAGS) $(HDF5_LIBS) +AM_LDFLAGS = ../src/.libs/libswiftsim.a $(HDF5_LDFLAGS) $(HDF5_LIBS) $(FFTW_LIBS) # List of programs and scripts to run in the test suite TESTS = testGreetings testReading.sh testSingle testPair.sh testPairPerturbed.sh \ - test27cells.sh test27cellsPerturbed.sh testParser.sh testKernel testKernelGrav + test27cells.sh test27cellsPerturbed.sh testParser.sh testKernel testKernelGrav \ + testFFT # List of test programs to compile check_PROGRAMS = testGreetings testReading testSingle testTimeIntegration \ - testSPHStep testPair test27cells testParser testKernel testKernelGrav + testSPHStep testPair test27cells testParser testKernel testKernelGrav \ + testFFT # Sources for the individual programs testGreetings_SOURCES = testGreetings.c @@ -49,6 +51,8 @@ testKernel_SOURCES = testKernel.c testKernelGrav_SOURCES = testKernelGrav.c +testFFT_SOURCES = testFFT.c + # Files necessary for distribution EXTRA_DIST = testReading.sh makeInput.py testPair.sh testPairPerturbed.sh \ test27cells.sh test27cellsPerturbed.sh tolerance.dat testParser.sh \ diff --git a/tests/testFFT.c b/tests/testFFT.c new file mode 100644 index 000000000..5a2786104 --- /dev/null +++ b/tests/testFFT.c @@ -0,0 +1,191 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (C) 2015 Matthieu Schaller (matthieu.schaller@durham.ac.uk). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + ******************************************************************************/ + +/* Some standard headers. */ +#include +#include + +#include + +/* Includes. */ +#include "swift.h" + +const double G = 1.; + +const size_t N = 16; +const size_t PMGRID = 8; + +// const double asmth = 2. * M_PI * const_gravity_a_smooth / boxSize; +// const double asmth2 = asmth * asmth; +// const double fact = G / (M_PI * boxSize) * (1. / (2. * boxSize / PMGRID)); + +int main() { + + /* Initialize CPU frequency, this also starts time. */ + unsigned long long cpufreq = 0; + clocks_set_cpufreq(cpufreq); + + /* Simulation properties */ + const size_t count = N * N * N; + const double boxSize = 1.; + + /* Create some particles */ + struct gpart* gparts = malloc(count * sizeof(struct gpart)); + bzero(gparts, count * sizeof(struct gpart)); + for (size_t i = 0; i < N; ++i) { + for (size_t j = 0; j < N; ++j) { + for (size_t k = 0; k < N; ++k) { + + struct gpart* gp = &gparts[i * N * N + j * N + k]; + + gp->x[0] = i * boxSize / N + boxSize / (2 * N); + gp->x[1] = j * boxSize / N + boxSize / (2 * N); + gp->x[2] = k * boxSize / N + boxSize / (2 * N); + + gp->mass = 1. / count; + + gp->id_or_neg_offset = i * N * N + j * N + k; + } + } + } + + /* Properties of the mesh */ + const size_t meshmin[3] = {0, 0, 0}; + const size_t meshmax[3] = {PMGRID - 1, PMGRID - 1, PMGRID - 1}; + + const size_t dimx = meshmax[0] - meshmin[0] + 2; + const size_t dimy = meshmax[1] - meshmin[1] + 2; + const size_t dimz = meshmax[2] - meshmin[2] + 2; + + const double fac = PMGRID / boxSize; + const size_t PMGRID2 = 2 * (PMGRID / 2 + 1); + + /* message("dimx=%zd dimy=%zd dimz=%zd", dimx, dimy, dimz); */ + + /* Allocate and empty the workspace mesh */ + const size_t workspace_size = (dimx + 4) * (dimy + 4) * (dimz + 4); + double* workspace = fftw_malloc(workspace_size * sizeof(double)); + bzero(workspace, workspace_size * sizeof(double)); + + /* Do CIC with the particles */ + for (size_t pid = 0; pid < count; ++pid) { + + const struct gpart* const gp = &gparts[pid]; + + const size_t slab_x = + (fac * gp->x[0] >= PMGRID) ? PMGRID - 1 : fac * gp->x[0]; + const size_t slab_y = + (fac * gp->x[1] >= PMGRID) ? PMGRID - 1 : fac * gp->x[1]; + const size_t slab_z = + (fac * gp->x[2] >= PMGRID) ? PMGRID - 1 : fac * gp->x[2]; + + const double dx = fac * gp->x[0] - (double)slab_x; + const double dy = fac * gp->x[1] - (double)slab_y; + const double dz = fac * gp->x[2] - (double)slab_z; + + const size_t slab_xx = slab_x + 1; + const size_t slab_yy = slab_y + 1; + const size_t slab_zz = slab_z + 1; + + workspace[(slab_x * dimy + slab_y) * dimz + slab_z] += + gp->mass * (1.0 - dx) * (1.0 - dy) * (1.0 - dz); + workspace[(slab_x * dimy + slab_yy) * dimz + slab_z] += + gp->mass * (1.0 - dx) * dy * (1.0 - dz); + workspace[(slab_x * dimy + slab_y) * dimz + slab_zz] += + gp->mass * (1.0 - dx) * (1.0 - dy) * dz; + workspace[(slab_x * dimy + slab_yy) * dimz + slab_zz] += + gp->mass * (1.0 - dx) * dy * dz; + workspace[(slab_xx * dimy + slab_y) * dimz + slab_z] += + gp->mass * (dx) * (1.0 - dy) * (1.0 - dz); + workspace[(slab_xx * dimy + slab_yy) * dimz + slab_z] += + gp->mass * (dx)*dy * (1.0 - dz); + workspace[(slab_xx * dimy + slab_y) * dimz + slab_zz] += + gp->mass * (dx) * (1.0 - dy) * dz; + workspace[(slab_xx * dimy + slab_yy) * dimz + slab_zz] += + gp->mass * (dx)*dy * dz; + } + + /* for(size_t i = 0 ; i < dimx*dimy*dimz; ++i) */ + /* message("workspace[%zd] = %f", i, workspace[i]); */ + + /* Prepare the force grid */ + const size_t fft_size = workspace_size; + double* forcegrid = fftw_malloc(fft_size * sizeof(double)); + bzero(forcegrid, fft_size * sizeof(double)); + + const size_t sendmin = 0, recvmin = 0; + const size_t sendmax = PMGRID, recvmax = PMGRID; + + memcpy(forcegrid, workspace + (sendmin - meshmin[0]) * dimy * dimz, + (sendmax - sendmin + 1) * dimy * dimz * sizeof(double)); + + /* for (size_t i = 0; i < fft_size; ++i) */ + /* if (forcegrid[i] != workspace[i]) error("wrong"); */ + + /* Prepare the density grid */ + double* rhogrid = fftw_malloc(fft_size * sizeof(double)); + bzero(rhogrid, fft_size * sizeof(double)); + + /* Now get the density */ + for (size_t slab_x = recvmin; slab_x <= recvmax; slab_x++) { + + const size_t slab_xx = slab_x % PMGRID; + + for (size_t slab_y = recvmin; slab_y <= recvmax; slab_y++) { + + const size_t slab_yy = slab_y % PMGRID; + + for (size_t slab_z = recvmin; slab_z <= recvmax; slab_z++) { + + const size_t slab_zz = slab_z % PMGRID; + + rhogrid[PMGRID * PMGRID2 * slab_xx + PMGRID2 * slab_yy + slab_zz] += + forcegrid[((slab_x - recvmin) * dimy + (slab_y - recvmin)) * dimz + + (slab_z - recvmin)]; + } + } + } + + /* for (size_t i = 0; i < 640; i++) { */ + /* if (rhogrid[i] != workspace[i]) { */ + /* message("rhogrid[%zd]= %f workspace[%zd]= %f forcegrid[%zd]= %f", i, */ + /* rhogrid[i], i, workspace[i], i, forcegrid[i]); */ + /* } */ + /* } */ + + + /* FFT of the density field */ + fftw_complex* fftgrid = fftw_malloc(fft_size * sizeof(fftw_complex)); + fftw_plan plan_forward = fftw_plan_dft_r2c_3d(PMGRID, PMGRID, PMGRID, rhogrid, fftgrid, FFTW_ESTIMATE); + fftw_execute(plan_forward); + + + for(size_t i = 0; i < 640; i++) { + message("workspace[%zd]= %f", i, fftgrid[i][0]); + } + + + /* Clean-up */ + fftw_destroy_plan(plan_forward); + fftw_free(forcegrid); + fftw_free(rhogrid); + fftw_free(workspace); + free(gparts); + return 0; +} -- GitLab From 8ff6cc7c22ee6128671e973dd7dc635ed463b761 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sun, 31 Jul 2016 13:00:47 +0100 Subject: [PATCH 67/72] Update the Makefiles --- src/Makefile.am | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 70e1dc93d..4aa7278ba 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -48,13 +48,14 @@ include_HEADERS = space.h runner.h queue.h task.h lock.h cell.h part.h const.h \ 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_hydro.c kernel_gravity.c tools.c part.c partition.c clocks.c parser.c \ - physical_constants.c potentials.c hydro_properties.c + kernel_hydro.c tools.c part.c partition.c clocks.c parser.c \ + physical_constants.c potentials.c hydro_properties.c \ + runner_doiact_fft.c # Include files for distribution, not installation. nobase_noinst_HEADERS = approx_math.h atomic.h cycle.h error.h inline.h kernel_hydro.h kernel_gravity.h \ - vector.h runner_doiact.h runner_doiact_grav.h runner_doiact_fft.h units.h intrinsics.h minmax.h \ - kick.h timestep.h drift.h adiabatic_index.h io_properties.h \ + kernel_long_gravity.h vector.h runner_doiact.h runner_doiact_grav.h runner_doiact_fft.h \ + units.h intrinsics.h minmax.h kick.h timestep.h drift.h adiabatic_index.h io_properties.h \ gravity.h gravity_io.h \ gravity/Default/gravity.h gravity/Default/gravity_iact.h gravity/Default/gravity_io.h \ gravity/Default/gravity_debug.h gravity/Default/gravity_part.h \ -- GitLab From af3f90f058b651f3db23b07416d354274e77d9b7 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sun, 31 Jul 2016 14:23:53 +0100 Subject: [PATCH 68/72] Post-merge fixes --- src/cell.c | 4 ++-- src/engine.c | 2 +- src/runner_doiact_grav.h | 38 +++++++++++++++++++------------------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/cell.c b/src/cell.c index 9907a3747..05782c1c1 100644 --- a/src/cell.c +++ b/src/cell.c @@ -721,11 +721,11 @@ int cell_are_neighbours(const struct cell *restrict ci, const struct cell *restrict cj) { #ifdef SWIFT_DEBUG_CHECKS - if (ci->h[0] != cj->h[0]) error("Cells of different size !"); + if (ci->width[0] != cj->width[0]) error("Cells of different size !"); #endif /* Maximum allowed distance */ - const double min_dist = 1.2 * ci->h[0]; /* 1.2 accounts for rounding errors */ + const double min_dist = 1.2 * ci->width[0]; /* 1.2 accounts for rounding errors */ /* (Manhattan) Distance between the cells */ for (int k = 0; k < 3; k++) { diff --git a/src/engine.c b/src/engine.c index ce1acfec4..8420248d9 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2646,7 +2646,7 @@ void engine_step(struct engine *e) { /* Check the gravity accelerations */ struct gpart *temp = malloc(s->nr_gparts * sizeof(struct gpart)); memcpy(temp, s->gparts, s->nr_gparts * sizeof(struct gpart)); - const double rlr = const_gravity_a_smooth * s->cells[0].h[0]; + const double rlr = const_gravity_a_smooth * s->cells[0].width[0]; gravity_n2(temp, s->nr_gparts, e->physical_constants, rlr); file = fopen("grav_brute.dat", "w"); for (size_t k = 0; k < s->nr_gparts; ++k) { diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index ae6607ecd..907178681 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -72,7 +72,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( struct gpart *restrict gparts = ci->gparts; const struct multipole multi = cj->multipole; const int ti_current = e->ti_current; - const float rlr_inv = 1. / (const_gravity_a_smooth * ci->super->h[0]); + const float rlr_inv = 1. / (const_gravity_a_smooth * ci->super->width[0]); TIMER_TIC; @@ -95,7 +95,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( if (gp->id_or_neg_offset == ICHECK) message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id_or_neg_offset, cj->loc[0], cj->loc[1], cj->loc[2], - cj->h[0], cj->gcount); + cj->width[0], cj->gcount); } #endif @@ -139,13 +139,13 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( struct gpart *restrict gparts_i = ci->gparts; struct gpart *restrict gparts_j = cj->gparts; const int ti_current = e->ti_current; - const float rlr_inv = 1. / (const_gravity_a_smooth * ci->super->h[0]); + const float rlr_inv = 1. / (const_gravity_a_smooth * ci->super->width[0]); TIMER_TIC; #ifdef SWIFT_DEBUG_CHECKS - if (ci->h[0] != cj->h[0]) // MATTHIEU sanity check - error("Non matching cell sizes !! h_i=%f h_j=%f", ci->h[0], cj->h[0]); + if (ci->width[0] != cj->width[0]) // MATTHIEU sanity check + error("Non matching cell sizes !! h_i=%f h_j=%f", ci->width[0], cj->width[0]); #endif /* Anything to do here? */ @@ -160,7 +160,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( if (gp->id_or_neg_offset == ICHECK) message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id_or_neg_offset, cj->loc[0], cj->loc[1], cj->loc[2], - cj->h[0], cj->gcount); + cj->width[0], cj->gcount); } for (int pid = 0; pid < gcount_j; pid++) { @@ -171,7 +171,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( if (gp->id_or_neg_offset == ICHECK) message("id=%lld loc=[ %f %f %f ] size= %f count=%d", gp->id_or_neg_offset, ci->loc[0], ci->loc[1], ci->loc[2], - ci->h[0], ci->gcount); + ci->width[0], ci->gcount); } #endif @@ -233,7 +233,7 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( const int gcount = c->gcount; struct gpart *restrict gparts = c->gparts; const int ti_current = e->ti_current; - const float rlr_inv = 1. / (const_gravity_a_smooth * c->super->h[0]); + const float rlr_inv = 1. / (const_gravity_a_smooth * c->super->width[0]); TIMER_TIC; @@ -253,7 +253,7 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( if (gp->id_or_neg_offset == ICHECK) message("id=%lld loc=[ %f %f %f ] size= %f count= %d", - gp->id_or_neg_offset, c->loc[0], c->loc[1], c->loc[2], c->h[0], + gp->id_or_neg_offset, c->loc[0], c->loc[1], c->loc[2], c->width[0], c->gcount); } #endif @@ -324,8 +324,8 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, if (gcount_i == 0 || gcount_j == 0) error("Empty cell !"); /* Bad stuff will happen if cell sizes are different */ - if (ci->h[0] != cj->h[0]) - error("Non matching cell sizes !! h_i=%f h_j=%f", ci->h[0], cj->h[0]); + if (ci->width[0] != cj->width[0]) + error("Non matching cell sizes !! h_i=%f h_j=%f", ci->width[0], cj->width[0]); /* Sanity check */ if (ci == cj) @@ -336,10 +336,10 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, /* Are the cells direct neighbours? */ if (!cell_are_neighbours(ci, cj)) error( - "Non-neighbouring cells ! ci->x=[%f %f %f] ci->h=%f cj->loc=[%f %f %f] " - "cj->h=%f", - ci->loc[0], ci->loc[1], ci->loc[2], ci->h[0], cj->loc[0], cj->loc[1], - cj->loc[2], cj->h[0]); + "Non-neighbouring cells ! ci->x=[%f %f %f] ci->width=%f cj->loc=[%f %f %f] " + "cj->width=%f", + ci->loc[0], ci->loc[1], ci->loc[2], ci->width[0], cj->loc[0], cj->loc[1], + cj->loc[2], cj->width[0]); #endif @@ -352,7 +352,7 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, if (gp->id_or_neg_offset == ICHECK) message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id_or_neg_offset, cj->loc[0], cj->loc[1], cj->loc[2], - cj->h[0], cj->gcount); + cj->width[0], cj->gcount); } for (int pid = 0; pid < cj->gcount; pid++) { @@ -363,7 +363,7 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, if (gp->id_or_neg_offset == ICHECK) message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id_or_neg_offset, ci->loc[0], ci->loc[1], ci->loc[2], - ci->h[0], ci->gcount); + ci->width[0], ci->gcount); } #endif @@ -479,7 +479,7 @@ static void runner_do_grav_mm(struct runner *r, struct cell *ci, int timer) { if (gp->id_or_neg_offset == ICHECK) message("id=%lld loc=[ %f %f %f ] size= %f count= %d", gp->id_or_neg_offset, ci->loc[0], ci->loc[1], ci->loc[2], - ci->h[0], ci->gcount); + ci->width[0], ci->gcount); } #endif @@ -488,7 +488,7 @@ static void runner_do_grav_mm(struct runner *r, struct cell *ci, int timer) { struct cell *cells = e->s->cells; const int nr_cells = e->s->nr_cells; const int ti_current = e->ti_current; - const double max_d = const_gravity_a_smooth * const_gravity_r_cut * ci->h[0]; + const double max_d = const_gravity_a_smooth * const_gravity_r_cut * ci->width[0]; const double max_d2 = max_d * max_d; const double pos_i[3] = {ci->loc[0], ci->loc[1], ci->loc[2]}; -- GitLab From 765a58c647b2b3af6982297d6d479a71b9c058e0 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sun, 31 Jul 2016 22:12:43 +0100 Subject: [PATCH 69/72] Potential forces don't contain Newton's constant any more. --- src/cell.c | 3 ++- src/potentials.c | 4 ++-- src/potentials.h | 16 +++++++++++----- src/runner_doiact_grav.h | 20 ++++++++++++-------- tests/testFFT.c | 14 ++++++-------- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/cell.c b/src/cell.c index 05782c1c1..8a8cf4d41 100644 --- a/src/cell.c +++ b/src/cell.c @@ -725,7 +725,8 @@ int cell_are_neighbours(const struct cell *restrict ci, #endif /* Maximum allowed distance */ - const double min_dist = 1.2 * ci->width[0]; /* 1.2 accounts for rounding errors */ + const double min_dist = + 1.2 * ci->width[0]; /* 1.2 accounts for rounding errors */ /* (Manhattan) Distance between the cells */ for (int k = 0; k < 3; k++) { diff --git a/src/potentials.c b/src/potentials.c index 6818d8a23..5cbe05e00 100644 --- a/src/potentials.c +++ b/src/potentials.c @@ -47,7 +47,7 @@ void potential_init(const struct swift_params* parameter_file, potential->point_mass.mass = parser_get_param_double(parameter_file, "PointMass:mass"); potential->point_mass.timestep_mult = - parser_get_param_double(parameter_file, "PointMass:timestep_mult"); + parser_get_param_float(parameter_file, "PointMass:timestep_mult"); #endif /* EXTERNAL_POTENTIAL_POINTMASS */ @@ -61,7 +61,7 @@ void potential_init(const struct swift_params* parameter_file, parser_get_param_double(parameter_file, "IsothermalPotential:position_z"); potential->isothermal_potential.vrot = parser_get_param_double(parameter_file, "IsothermalPotential:vrot"); - potential->isothermal_potential.timestep_mult = parser_get_param_double( + potential->isothermal_potential.timestep_mult = parser_get_param_float( parameter_file, "IsothermalPotential:timestep_mult"); #endif /* EXTERNAL_POTENTIAL_ISOTHERMALPOTENTIAL */ diff --git a/src/potentials.h b/src/potentials.h index 1ae9519a9..5373cc1f3 100644 --- a/src/potentials.h +++ b/src/potentials.h @@ -42,7 +42,7 @@ struct external_potential { struct { double x, y, z; double mass; - double timestep_mult; + float timestep_mult; } point_mass; #endif @@ -50,7 +50,7 @@ struct external_potential { struct { double x, y, z; double vrot; - double timestep_mult; + float timestep_mult; } isothermal_potential; #endif }; @@ -95,6 +95,8 @@ external_gravity_isothermalpotential_timestep( * @brief Computes the gravitational acceleration of a particle due to a point * mass * + * Note that the accelerations are multiplied by Newton's G constant later on. + * * @param potential The #external_potential used in the run. * @param phys_const The physical constants in internal units. * @param g Pointer to the g-particle data. @@ -104,15 +106,19 @@ external_gravity_isothermalpotential(const struct external_potential* potential, const struct phys_const* const phys_const, struct gpart* g) { + const float G_newton = phys_const->const_newton_G; + const float dx = g->x[0] - potential->isothermal_potential.x; const float dy = g->x[1] - potential->isothermal_potential.y; const float dz = g->x[2] - potential->isothermal_potential.z; const float rinv2 = 1.f / (dx * dx + dy * dy + dz * dz); const double vrot = potential->isothermal_potential.vrot; - g->a_grav[0] += -vrot * vrot * rinv2 * dx; - g->a_grav[1] += -vrot * vrot * rinv2 * dy; - g->a_grav[2] += -vrot * vrot * rinv2 * dz; + const double term = -vrot * vrot * rinv2 / G_newton; + + g->a_grav[0] += term * dx; + g->a_grav[1] += term * dy; + g->a_grav[2] += term * dz; // error(" %f %f %f %f", vrot, rinv2, dx, g->a_grav[0]); } diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 907178681..a220ad179 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -145,7 +145,8 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( #ifdef SWIFT_DEBUG_CHECKS if (ci->width[0] != cj->width[0]) // MATTHIEU sanity check - error("Non matching cell sizes !! h_i=%f h_j=%f", ci->width[0], cj->width[0]); + error("Non matching cell sizes !! h_i=%f h_j=%f", ci->width[0], + cj->width[0]); #endif /* Anything to do here? */ @@ -253,8 +254,8 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( if (gp->id_or_neg_offset == ICHECK) message("id=%lld loc=[ %f %f %f ] size= %f count= %d", - gp->id_or_neg_offset, c->loc[0], c->loc[1], c->loc[2], c->width[0], - c->gcount); + gp->id_or_neg_offset, c->loc[0], c->loc[1], c->loc[2], + c->width[0], c->gcount); } #endif @@ -325,7 +326,8 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, /* Bad stuff will happen if cell sizes are different */ if (ci->width[0] != cj->width[0]) - error("Non matching cell sizes !! h_i=%f h_j=%f", ci->width[0], cj->width[0]); + error("Non matching cell sizes !! h_i=%f h_j=%f", ci->width[0], + cj->width[0]); /* Sanity check */ if (ci == cj) @@ -336,10 +338,11 @@ static void runner_dopair_grav(struct runner *r, struct cell *ci, /* Are the cells direct neighbours? */ if (!cell_are_neighbours(ci, cj)) error( - "Non-neighbouring cells ! ci->x=[%f %f %f] ci->width=%f cj->loc=[%f %f %f] " + "Non-neighbouring cells ! ci->x=[%f %f %f] ci->width=%f cj->loc=[%f %f " + "%f] " "cj->width=%f", - ci->loc[0], ci->loc[1], ci->loc[2], ci->width[0], cj->loc[0], cj->loc[1], - cj->loc[2], cj->width[0]); + ci->loc[0], ci->loc[1], ci->loc[2], ci->width[0], cj->loc[0], + cj->loc[1], cj->loc[2], cj->width[0]); #endif @@ -488,7 +491,8 @@ static void runner_do_grav_mm(struct runner *r, struct cell *ci, int timer) { struct cell *cells = e->s->cells; const int nr_cells = e->s->nr_cells; const int ti_current = e->ti_current; - const double max_d = const_gravity_a_smooth * const_gravity_r_cut * ci->width[0]; + const double max_d = + const_gravity_a_smooth * const_gravity_r_cut * ci->width[0]; const double max_d2 = max_d * max_d; const double pos_i[3] = {ci->loc[0], ci->loc[1], ci->loc[2]}; diff --git a/tests/testFFT.c b/tests/testFFT.c index 5a2786104..7ff29dac3 100644 --- a/tests/testFFT.c +++ b/tests/testFFT.c @@ -134,14 +134,14 @@ int main() { memcpy(forcegrid, workspace + (sendmin - meshmin[0]) * dimy * dimz, (sendmax - sendmin + 1) * dimy * dimz * sizeof(double)); - + /* for (size_t i = 0; i < fft_size; ++i) */ /* if (forcegrid[i] != workspace[i]) error("wrong"); */ /* Prepare the density grid */ double* rhogrid = fftw_malloc(fft_size * sizeof(double)); bzero(rhogrid, fft_size * sizeof(double)); - + /* Now get the density */ for (size_t slab_x = recvmin; slab_x <= recvmax; slab_x++) { @@ -169,18 +169,16 @@ int main() { /* } */ /* } */ - /* FFT of the density field */ fftw_complex* fftgrid = fftw_malloc(fft_size * sizeof(fftw_complex)); - fftw_plan plan_forward = fftw_plan_dft_r2c_3d(PMGRID, PMGRID, PMGRID, rhogrid, fftgrid, FFTW_ESTIMATE); + fftw_plan plan_forward = fftw_plan_dft_r2c_3d(PMGRID, PMGRID, PMGRID, rhogrid, + fftgrid, FFTW_ESTIMATE); fftw_execute(plan_forward); - - for(size_t i = 0; i < 640; i++) { + for (size_t i = 0; i < 640; i++) { message("workspace[%zd]= %f", i, fftgrid[i][0]); } - - + /* Clean-up */ fftw_destroy_plan(plan_forward); fftw_free(forcegrid); -- GitLab From e3691f706c6bae571cd742759017273b2774c3ff Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sun, 31 Jul 2016 23:13:56 +0100 Subject: [PATCH 70/72] task_overlap() can now deal with gravity tasks --- src/task.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++------- src/task.h | 11 ++++ 2 files changed, 156 insertions(+), 22 deletions(-) diff --git a/src/task.c b/src/task.c index 4769aa660..e9404ab00 100644 --- a/src/task.c +++ b/src/task.c @@ -59,7 +59,7 @@ const char *subtaskID_names[task_type_count] = {"none", "density", "force", /** * @brief Computes the overlap between the parts array of two given cells. */ -size_t task_cell_overlap(const struct cell *ci, const struct cell *cj) { +size_t task_cell_overlap_part(const struct cell *ci, const struct cell *cj) { if (ci == NULL || cj == NULL) return 0; if (ci->parts <= cj->parts && ci->parts + ci->count >= cj->parts + cj->count) { @@ -71,6 +71,95 @@ size_t task_cell_overlap(const struct cell *ci, const struct cell *cj) { return 0; } +/** + * @brief Computes the overlap between the gparts array of two given cells. + */ +size_t task_cell_overlap_gpart(const struct cell *ci, const struct cell *cj) { + if (ci == NULL || cj == NULL) return 0; + if (ci->gparts <= cj->gparts && + ci->gparts + ci->gcount >= cj->gparts + cj->gcount) { + return cj->gcount; + } else if (cj->gparts <= ci->gparts && + cj->gparts + cj->gcount >= ci->gparts + ci->gcount) { + return ci->gcount; + } + return 0; +} + +/** + * @brief Returns the #task_actions for a given task. + * + * @param t The #task. + */ +enum task_actions task_acts_on(const struct task *t) { + + switch (t->type) { + + case task_type_none: + return task_action_none; + break; + + case task_type_sort: + case task_type_ghost: + return task_action_part; + break; + + case task_type_self: + case task_type_pair: + case task_type_sub_self: + case task_type_sub_pair: + switch (t->subtype) { + + case task_subtype_density: + case task_subtype_force: + return task_action_part; + break; + + case task_subtype_grav: + return task_action_gpart; + break; + + default: + error("Unknow task_action for task"); + return task_action_none; + break; + } + break; + + case task_type_init: + case task_type_drift: + case task_type_kick: + case task_type_kick_fixdt: + case task_type_send: + case task_type_recv: + return task_action_all; + break; + + case task_type_grav_gather_m: + case task_type_grav_fft: + case task_type_grav_mm: + case task_type_grav_up: + return task_action_multipole; + break; + + case task_type_grav_external: + return task_action_gpart; + break; + + case task_type_part_sort: + case task_type_gpart_sort: + case task_type_split_cell: + case task_type_rewait: + return task_action_none; + break; + + default: + error("Unknow task_action for task"); + return task_action_none; + break; + } +} + /** * @brief Compute the Jaccard similarity of the data used by two * different tasks. @@ -79,29 +168,63 @@ size_t task_cell_overlap(const struct cell *ci, const struct cell *cj) { * @param tb The second #task. */ float task_overlap(const struct task *ta, const struct task *tb) { + + if (ta == NULL || tb == NULL) return 0.f; + + const enum task_actions ta_act = task_acts_on(ta); + const enum task_actions tb_act = task_acts_on(tb); + /* First check if any of the two tasks are of a type that don't use cells. */ - if (ta == NULL || tb == NULL || ta->type == task_type_none || - ta->type == task_type_part_sort || ta->type == task_type_gpart_sort || - ta->type == task_type_split_cell || ta->type == task_type_rewait || - tb->type == task_type_none || tb->type == task_type_part_sort || - tb->type == task_type_gpart_sort || tb->type == task_type_split_cell || - tb->type == task_type_rewait) - return 0.0f; - - /* Compute the union of the cell data. */ - size_t size_union = 0; - if (ta->ci != NULL) size_union += ta->ci->count; - if (ta->cj != NULL) size_union += ta->cj->count; - if (tb->ci != NULL) size_union += tb->ci->count; - if (tb->cj != NULL) size_union += tb->cj->count; - - /* Compute the intersection of the cell data. */ - const size_t size_intersect = - task_cell_overlap(ta->ci, tb->ci) + task_cell_overlap(ta->ci, tb->cj) + - task_cell_overlap(ta->cj, tb->ci) + task_cell_overlap(ta->cj, tb->cj); - - return ((float)size_intersect) / (size_union - size_intersect); + if (ta_act == task_action_none || tb_act == task_action_none) return 0.f; + + const int ta_part = (ta_act == task_action_part || ta_act == task_action_all); + const int ta_gpart = + (ta_act == task_action_gpart || ta_act == task_action_all); + const int tb_part = (tb_act == task_action_part || tb_act == task_action_all); + const int tb_gpart = + (tb_act == task_action_gpart || tb_act == task_action_all); + + /* In the case where both tasks act on parts */ + if (ta_part && tb_part) { + + /* Compute the union of the cell data. */ + size_t size_union = 0; + if (ta->ci != NULL) size_union += ta->ci->count; + if (ta->cj != NULL) size_union += ta->cj->count; + if (tb->ci != NULL) size_union += tb->ci->count; + if (tb->cj != NULL) size_union += tb->cj->count; + + /* Compute the intersection of the cell data. */ + const size_t size_intersect = task_cell_overlap_part(ta->ci, tb->ci) + + task_cell_overlap_part(ta->ci, tb->cj) + + task_cell_overlap_part(ta->cj, tb->ci) + + task_cell_overlap_part(ta->cj, tb->cj); + + return ((float)size_intersect) / (size_union - size_intersect); + } + + /* In the case where both tasks act on gparts */ + else if (ta_gpart && tb_gpart) { + + /* Compute the union of the cell data. */ + size_t size_union = 0; + if (ta->ci != NULL) size_union += ta->ci->gcount; + if (ta->cj != NULL) size_union += ta->cj->gcount; + if (tb->ci != NULL) size_union += tb->ci->gcount; + if (tb->cj != NULL) size_union += tb->cj->gcount; + + /* Compute the intersection of the cell data. */ + const size_t size_intersect = task_cell_overlap_gpart(ta->ci, tb->ci) + + task_cell_overlap_gpart(ta->ci, tb->cj) + + task_cell_overlap_gpart(ta->cj, tb->ci) + + task_cell_overlap_gpart(ta->cj, tb->cj); + + return ((float)size_intersect) / (size_union - size_intersect); + } + + /* Else, no overlap */ + return 0.f; } /** diff --git a/src/task.h b/src/task.h index 581af55e5..ee49568b1 100644 --- a/src/task.h +++ b/src/task.h @@ -70,6 +70,16 @@ enum task_subtypes { task_subtype_count }; +/* The kind of action the task perform */ +enum task_actions { + task_action_none, + task_action_part, + task_action_gpart, + task_action_all, + task_action_multipole, + task_action_count +}; + extern const char *subtaskID_names[]; /* Data of a task. */ @@ -102,5 +112,6 @@ int task_lock(struct task *t); void task_print_mask(unsigned int mask); void task_print_submask(unsigned int submask); void task_do_rewait(struct task *t); +enum task_actions task_acts_on(const struct task *t); #endif /* SWIFT_TASK_H */ -- GitLab From 87947e648d8125c5f185dd071d9c8a04c484e947 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sun, 31 Jul 2016 23:38:52 +0100 Subject: [PATCH 71/72] Get ready for merge --- src/engine.c | 41 ++---------------------------- src/gravity/Default/gravity.h | 2 -- src/gravity/Default/gravity_iact.h | 5 ---- src/gravity/Default/gravity_part.h | 2 -- 4 files changed, 2 insertions(+), 48 deletions(-) diff --git a/src/engine.c b/src/engine.c index 8420248d9..580a6515b 100644 --- a/src/engine.c +++ b/src/engine.c @@ -131,7 +131,7 @@ void engine_make_gravity_hierarchical_tasks(struct engine *e, struct cell *c, const int is_fixdt = (e->policy & engine_policy_fixdt) == engine_policy_fixdt; /* Is this the super-cell? */ - if (super == NULL && (c->grav != NULL || (c->gcount > 0 && c->split))) { + if (super == NULL && (c->grav != NULL || (!c->split && c->gcount > 0))) { /* This is the super cell, i.e. the first with gravity tasks attached. */ super = c; @@ -193,7 +193,7 @@ void engine_make_hydro_hierarchical_tasks(struct engine *e, struct cell *c, const int is_fixdt = (e->policy & engine_policy_fixdt) == engine_policy_fixdt; /* Is this the super-cell? */ - if (super == NULL && (c->density != NULL || (c->count > 0 && c->split))) { + if (super == NULL && (c->density != NULL || (c->count > 0 && !c->split))) { /* This is the super cell, i.e. the first with density tasks attached. */ super = c; @@ -2499,7 +2499,6 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs) { void engine_step(struct engine *e) { double snapshot_drift_time = 0.; - struct space *s = e->s; TIMER_TIC2; @@ -2628,42 +2627,6 @@ void engine_step(struct engine *e) { TIMER_TOC2(timer_step); - /* Check that the multipoles are correct */ - space_map_cells_pre(s, 1, cell_check_multipole, NULL); - - FILE *file = fopen("grav_swift.dat", "w"); - for (size_t k = 0; k < s->nr_gparts; ++k) { - fprintf(file, "%lld %f %f %f %e %e %e\n", s->gparts[k].id_or_neg_offset, - s->gparts[k].x[0], s->gparts[k].x[1], s->gparts[k].x[2], - s->gparts[k].a_grav[0], s->gparts[k].a_grav[1], - s->gparts[k].a_grav[2]); - if (s->gparts[k].id_or_neg_offset == 1) - message("interacting mass= %f (%f)", s->gparts[k].mass_interacted, - s->gparts[k].mass_interacted + s->gparts[k].mass); - } - fclose(file); - - /* Check the gravity accelerations */ - struct gpart *temp = malloc(s->nr_gparts * sizeof(struct gpart)); - memcpy(temp, s->gparts, s->nr_gparts * sizeof(struct gpart)); - const double rlr = const_gravity_a_smooth * s->cells[0].width[0]; - gravity_n2(temp, s->nr_gparts, e->physical_constants, rlr); - file = fopen("grav_brute.dat", "w"); - for (size_t k = 0; k < s->nr_gparts; ++k) { - fprintf(file, "%lld %f %f %f %e %e %e\n", temp[k].id_or_neg_offset, - temp[k].x[0], temp[k].x[1], temp[k].x[2], temp[k].a_grav[0], - temp[k].a_grav[1], temp[k].a_grav[2]); - } - fclose(file); - - free(temp); - - double mass = 0.f; - for (int i = 0; i < s->nr_cells; ++i) mass += s->cells[i].multipole.mass; - message("Total mass: %f", mass); - - error("done"); - clocks_gettime(&time2); e->wallclock_time = (float)clocks_diff(&time1, &time2); diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h index 47c3d1d81..5903ce138 100644 --- a/src/gravity/Default/gravity.h +++ b/src/gravity/Default/gravity.h @@ -99,8 +99,6 @@ __attribute__((always_inline)) INLINE static void gravity_init_gpart( gp->a_grav[0] = 0.f; gp->a_grav[1] = 0.f; gp->a_grav[2] = 0.f; - - gp->mass_interacted = 0.f; } /** diff --git a/src/gravity/Default/gravity_iact.h b/src/gravity/Default/gravity_iact.h index 048d47e73..aa285ce32 100644 --- a/src/gravity/Default/gravity_iact.h +++ b/src/gravity/Default/gravity_iact.h @@ -85,13 +85,11 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp( gpi->a_grav[0] -= fidx[0]; gpi->a_grav[1] -= fidx[1]; gpi->a_grav[2] -= fidx[2]; - gpi->mass_interacted += mj; const float fjdx[3] = {fj * dx[0], fj * dx[1], fj * dx[2]}; gpj->a_grav[0] += fjdx[0]; gpj->a_grav[1] += fjdx[1]; gpj->a_grav[2] += fjdx[2]; - gpj->mass_interacted += mi; } /** @@ -134,7 +132,6 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp_nonsym( gpi->a_grav[0] -= fdx[0]; gpi->a_grav[1] -= fdx[1]; gpi->a_grav[2] -= fdx[2]; - gpi->mass_interacted += mj; } /** @@ -161,7 +158,6 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pm( gp->a_grav[1] += mrinv3 * f_lr * dx[1]; gp->a_grav[2] += mrinv3 * f_lr * dx[2]; - gp->mass_interacted += multi->mass; #elif const_gravity_multipole_order == 2 /* Terms up to 2nd order (quadrupole) */ @@ -187,7 +183,6 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pm( gp->a_grav[1] -= f_lr * (C * dx[1] + D2 * qRy); gp->a_grav[2] -= f_lr * (C * dx[2] + D2 * qRz); - gp->mass_interacted += multi->mass; #else #error "Multipoles of order >2 not yet implemented." #endif diff --git a/src/gravity/Default/gravity_part.h b/src/gravity/Default/gravity_part.h index 3001dd040..77e654342 100644 --- a/src/gravity/Default/gravity_part.h +++ b/src/gravity/Default/gravity_part.h @@ -46,8 +46,6 @@ struct gpart { /* Particle time of end of time-step. */ int ti_end; - double mass_interacted; - /* Particle ID. If negative, it is the negative offset of the #part with which this gpart is linked. */ long long id_or_neg_offset; -- GitLab From 3411dd0fde6fad5a19722fbc3ddc7d7d7a376875 Mon Sep 17 00:00:00 2001 From: "Peter W. Draper" Date: Mon, 1 Aug 2016 17:58:59 +0100 Subject: [PATCH 72/72] Fix merge issues and FFTW include files --- src/cell.c | 5 +++-- src/runner_doiact_fft.c | 2 +- src/version.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cell.c b/src/cell.c index d25b9829b..7df55ce04 100644 --- a/src/cell.c +++ b/src/cell.c @@ -792,7 +792,9 @@ void cell_check_multipole(struct cell *c, void *data) { error("Multipole I_yz are different (%12.15e vs. %12.15e)", ma.I_yz, mb.I_yz); } -======= +} + +/* * @brief Frees up the memory allocated for this #cell */ void cell_clean(struct cell *c) { @@ -802,5 +804,4 @@ void cell_clean(struct cell *c) { /* Recurse */ for (int k = 0; k < 8; k++) if (c->progeny[k]) cell_clean(c->progeny[k]); ->>>>>>> master } diff --git a/src/runner_doiact_fft.c b/src/runner_doiact_fft.c index e735b2b99..076ec2578 100644 --- a/src/runner_doiact_fft.c +++ b/src/runner_doiact_fft.c @@ -24,7 +24,7 @@ #include #ifdef HAVE_FFTW -#include +#include #endif /* This object's header. */ diff --git a/src/version.c b/src/version.c index 122a11f64..68a051fa0 100644 --- a/src/version.c +++ b/src/version.c @@ -34,7 +34,7 @@ #endif #ifdef HAVE_FFTW -#include +#include #endif /* Some standard headers. */ -- GitLab