/******************************************************************************* * This file is part of SWIFT. * Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk) * 2016 Matthieu Schaller (schaller@strw.leidenuniv.nl) * * 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 /* Config */ #include /* Local includes */ #include "active.h" #include "inline.h" #include "multipole.h" #include "timers.h" /* Avoid cyclic inclusions. */ struct runner; struct cell; void runner_do_grav_down(struct runner *r, struct cell *c, int timer); void runner_dopair_grav_pp(struct runner *r, struct cell *ci, struct cell *cj, const int symmetric, const int allow_mpole); void runner_doself_recursive_grav(struct runner *r, struct cell *c, int gettimer); void runner_dopair_recursive_grav(struct runner *r, struct cell *ci, struct cell *cj, int gettimer); void runner_dopair_grav_mm(struct runner *r, struct cell *restrict ci, struct cell *restrict cj); void runner_dopair_grav_mm_progenies(struct runner *r, const long long flags, struct cell *restrict ci, struct cell *restrict cj); void runner_do_grav_long_range(struct runner *r, struct cell *ci, int timer); /* Internal functions (for unit tests and debugging) */ void runner_doself_grav_pp(struct runner *r, struct cell *c); void runner_dopair_grav_pp(struct runner *r, struct cell *ci, struct cell *cj, const int symmetric, const int allow_mpole); /** * @brief Computes the interaction of the field tensor in a cell with the * multipole of another cell. * * Defined here to enable inlining while this function is called from * runner_doiact_grav.c and runner_doiact_long_range_grav.c. * * @param r The #runner. * @param ci The #cell with field tensor to interact. * @param cj The #cell with the multipole. */ static INLINE void runner_dopair_grav_mm_nonsym(struct runner *r, struct cell *restrict ci, struct cell *restrict cj) { /* Some constants */ const struct engine *e = r->e; const struct gravity_props *props = e->gravity_properties; const int periodic = e->mesh->periodic; const double dim[3] = {e->mesh->dim[0], e->mesh->dim[1], e->mesh->dim[2]}; const float r_s_inv = e->mesh->r_s_inv; TIMER_TIC; /* Anything to do here? */ if (!cell_is_active_gravity_mm(ci, e) || ci->nodeID != engine_rank) return; /* Short-cut to the multipole */ const struct multipole *multi_j = &cj->grav.multipole->m_pole; #ifdef SWIFT_DEBUG_CHECKS if (ci == cj) error("Interacting a cell with itself using M2L"); if (multi_j->num_gpart == 0) error("Multipole does not seem to have been set."); if (ci->grav.multipole->pot.ti_init != e->ti_current) error("ci->grav tensor not initialised."); if (cj->grav.ti_old_multipole != e->ti_current) error( "Undrifted multipole cj->grav.ti_old_multipole=%lld cj->nodeID=%d " "ci->nodeID=%d e->ti_current=%lld", cj->grav.ti_old_multipole, cj->nodeID, ci->nodeID, e->ti_current); #endif #ifndef SWIFT_TASKS_WITHOUT_ATOMICS /* Lock the multipoles * Note we impose a hierarchy to solve the dining philosopher problem */ if (ci < cj) { lock_lock(&ci->grav.mlock); lock_lock(&cj->grav.mlock); } else { lock_lock(&cj->grav.mlock); lock_lock(&ci->grav.mlock); } #endif /* Let's interact at this level */ gravity_M2L_nonsym(&ci->grav.multipole->pot, multi_j, ci->grav.multipole->CoM, cj->grav.multipole->CoM, props, periodic, dim, r_s_inv); #ifndef SWIFT_TASKS_WITHOUT_ATOMICS /* Unlock the multipoles */ if (lock_unlock(&ci->grav.mlock) != 0) error("Failed to unlock multipole"); if (lock_unlock(&cj->grav.mlock) != 0) error("Failed to unlock multipole"); #endif TIMER_TOC(timer_dopair_grav_mm); } #endif /* SWIFT_RUNNER_DOIACT_GRAV_H */