diff --git a/src/runner.c b/src/runner.c index c06068c357e8bd1efe6c0278a9a94f48099b2fef..8f9707346bc87188835a4dedc184d2e3afc28f7e 100644 --- a/src/runner.c +++ b/src/runner.c @@ -71,8 +71,7 @@ const double runner_shift[13][3] = { {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}, -}; + {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, @@ -720,6 +719,148 @@ void runner_do_drift(struct runner *r, struct cell *c, int timer) { if (timer) TIMER_TOC(timer_drift); } +void runner_do_drift_mapper(void *map_data, int num_elements, + void *extra_data) { + + struct engine *e = (struct engine *)extra_data; + struct cell *cells = (struct cell *)map_data; + const double timeBase = e->timeBase; + const double dt = (e->ti_current - e->ti_old) * timeBase; + const int ti_old = e->ti_old; + const int ti_current = e->ti_current; + + for (int ind = 0; ind < num_elements; ind++) { + struct cell *c = &cells[ind]; + if (c == NULL) continue; + + struct part *const parts = c->parts; + struct xpart *const xparts = c->xparts; + struct gpart *const 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; + double mom[3] = {0.0, 0.0, 0.0}; + double ang_mom[3] = {0.0, 0.0, 0.0}; + +#ifdef TASK_VERBOSE + OUT; +#endif + + /* No children? */ + if (!c->split) { + + /* Loop over all the g-particles in the cell */ + const int nr_gparts = c->gcount; + for (size_t k = 0; k < nr_gparts; k++) { + + /* Get a handle on the gpart. */ + struct gpart *const gp = &gparts[k]; + + /* Drift... */ + drift_gpart(gp, dt, timeBase, ti_old, ti_current); + + /* Compute (square of) motion since last cell construction */ + const float dx2 = gp->x_diff[0] * gp->x_diff[0] + + gp->x_diff[1] * gp->x_diff[1] + + gp->x_diff[2] * gp->x_diff[2]; + dx2_max = fmaxf(dx2_max, dx2); + } + + /* Loop over all the particles in the cell (more work for these !) */ + const size_t nr_parts = c->count; + for (size_t k = 0; k < nr_parts; k++) { + + /* Get a handle on the part. */ + struct part *const p = &parts[k]; + struct xpart *const xp = &xparts[k]; + + /* Drift... */ + drift_part(p, xp, dt, timeBase, ti_old, ti_current); + + /* Compute (square of) motion since last cell construction */ + const float dx2 = xp->x_diff[0] * xp->x_diff[0] + + xp->x_diff[1] * xp->x_diff[1] + + xp->x_diff[2] * xp->x_diff[2]; + dx2_max = fmaxf(dx2_max, dx2); + + /* Maximal smoothing length */ + h_max = fmaxf(p->h, h_max); + + /* Now collect quantities for statistics */ + + const float half_dt = + (ti_current - (p->ti_begin + p->ti_end) / 2) * timeBase; + const double x[3] = {p->x[0], p->x[1], p->x[2]}; + const float v[3] = {xp->v_full[0] + p->a_hydro[0] * half_dt, + xp->v_full[1] + p->a_hydro[1] * half_dt, + xp->v_full[2] + p->a_hydro[2] * half_dt}; + const float m = p->mass; + + /* Collect mass */ + mass += m; + + /* Collect momentum */ + mom[0] += m * v[0]; + mom[1] += m * v[1]; + mom[2] += m * v[2]; + + /* Collect angular momentum */ + ang_mom[0] += m * (x[1] * v[2] - x[2] * v[1]); + ang_mom[1] += m * (x[2] * v[0] - x[0] * v[2]); + ang_mom[2] += m * (x[0] * v[1] - x[1] * v[0]); + + /* Collect energies. */ + e_kin += 0.5 * m * (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + e_pot += 0.; + e_int += m * hydro_get_internal_energy(p, half_dt); + } + + /* Now, get the maximal particle motion from its square */ + dx_max = sqrtf(dx2_max); + } + + /* Otherwise, aggregate data from children. */ + else { + + /* Loop over the progeny and collect their data. */ + for (int k = 0; k < 8; k++) + if (c->progeny[k] != NULL) { + struct cell *cp = c->progeny[k]; + + /* Recurse. */ + runner_do_drift_mapper(cp, 1, e); + + dx_max = fmaxf(dx_max, cp->dx_max); + h_max = fmaxf(h_max, cp->h_max); + mass += cp->mass; + e_kin += cp->e_kin; + e_int += cp->e_int; + e_pot += cp->e_pot; + mom[0] += cp->mom[0]; + mom[1] += cp->mom[1]; + mom[2] += cp->mom[2]; + ang_mom[0] += cp->ang_mom[0]; + ang_mom[1] += cp->ang_mom[1]; + ang_mom[2] += cp->ang_mom[2]; + } + } + + /* Store the values */ + c->h_max = h_max; + c->dx_max = dx_max; + c->mass = mass; + c->e_kin = e_kin; + c->e_int = e_int; + c->e_pot = e_pot; + c->mom[0] = mom[0]; + c->mom[1] = mom[1]; + c->mom[2] = mom[2]; + c->ang_mom[0] = ang_mom[0]; + c->ang_mom[1] = ang_mom[1]; + c->ang_mom[2] = ang_mom[2]; + } +} + /** * @brief Kick particles in momentum space and collect statistics (fixed * time-step case)