/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2016 Bert Vandenbroucke (bert.vandenbroucke@gmail.com)
*
* 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
/**
* @brief Initialize variables for the cell wide slope limiter
*
* @param p Particle.
*/
__attribute__((always_inline)) INLINE static void hydro_slope_limit_cell_init(
struct part* p) {
p->primitives.limiter.rho[0] = FLT_MAX;
p->primitives.limiter.rho[1] = -FLT_MAX;
p->primitives.limiter.v[0][0] = FLT_MAX;
p->primitives.limiter.v[0][1] = -FLT_MAX;
p->primitives.limiter.v[1][0] = FLT_MAX;
p->primitives.limiter.v[1][1] = -FLT_MAX;
p->primitives.limiter.v[2][0] = FLT_MAX;
p->primitives.limiter.v[2][1] = -FLT_MAX;
p->primitives.limiter.P[0] = FLT_MAX;
p->primitives.limiter.P[1] = -FLT_MAX;
p->primitives.limiter.maxr = -FLT_MAX;
}
/**
* @brief Collect information for the cell wide slope limiter during the
* neighbour loop
*
* @param pi Particle i.
* @param pj Particle j.
* @param r Distance between particle i and particle j.
*/
__attribute__((always_inline)) INLINE static void
hydro_slope_limit_cell_collect(struct part* pi, const struct part* pj,
float r) {
/* basic slope limiter: collect the maximal and the minimal value for the
* primitive variables among the ngbs */
pi->primitives.limiter.rho[0] =
fmin(pj->primitives.rho, pi->primitives.limiter.rho[0]);
pi->primitives.limiter.rho[1] =
fmax(pj->primitives.rho, pi->primitives.limiter.rho[1]);
pi->primitives.limiter.v[0][0] =
fmin(pj->primitives.v[0], pi->primitives.limiter.v[0][0]);
pi->primitives.limiter.v[0][1] =
fmax(pj->primitives.v[0], pi->primitives.limiter.v[0][1]);
pi->primitives.limiter.v[1][0] =
fmin(pj->primitives.v[1], pi->primitives.limiter.v[1][0]);
pi->primitives.limiter.v[1][1] =
fmax(pj->primitives.v[1], pi->primitives.limiter.v[1][1]);
pi->primitives.limiter.v[2][0] =
fmin(pj->primitives.v[2], pi->primitives.limiter.v[2][0]);
pi->primitives.limiter.v[2][1] =
fmax(pj->primitives.v[2], pi->primitives.limiter.v[2][1]);
pi->primitives.limiter.P[0] =
fmin(pj->primitives.P, pi->primitives.limiter.P[0]);
pi->primitives.limiter.P[1] =
fmax(pj->primitives.P, pi->primitives.limiter.P[1]);
pi->primitives.limiter.maxr = fmax(r, pi->primitives.limiter.maxr);
}
/**
* @brief Apply the cell wide slope limiter to the gradient of a single quantity
*
* This corresponds to equation (B2) in Hopkins (2015).
*
* @param grad Gradient to slope limit
* @param qval Value of the quantity at the cell generator
* @param qmin Minimal value of the quantity among all cell neighbours
* @param qmax Maximal value of the quantity among all cell neighbours
* @param maxr Maximal distance between the generator and all of its neighbours
*/
__attribute__((always_inline)) INLINE static void
hydro_slope_limit_cell_quantity(float* grad, float qval, float qmin, float qmax,
float maxr) {
float gradtrue, gradmax, gradmin, alpha;
gradtrue = sqrtf(grad[0] * grad[0] + grad[1] * grad[1] + grad[2] * grad[2]);
if (gradtrue) {
gradtrue *= maxr;
gradmax = qmax - qval;
gradmin = qval - qmin;
alpha = fmin(1.0f, fmin(gradmax / gradtrue, gradmin / gradtrue));
grad[0] *= alpha;
grad[1] *= alpha;
grad[2] *= alpha;
}
}
/**
* @brief Slope limit cell gradients
*
* @param p Particle.
*/
__attribute__((always_inline)) INLINE static void hydro_slope_limit_cell(
struct part* p) {
hydro_slope_limit_cell_quantity(
p->primitives.gradients.rho, p->primitives.rho,
p->primitives.limiter.rho[0], p->primitives.limiter.rho[1],
p->primitives.limiter.maxr);
hydro_slope_limit_cell_quantity(
p->primitives.gradients.v[0], p->primitives.v[0],
p->primitives.limiter.v[0][0], p->primitives.limiter.v[0][1],
p->primitives.limiter.maxr);
hydro_slope_limit_cell_quantity(
p->primitives.gradients.v[1], p->primitives.v[1],
p->primitives.limiter.v[1][0], p->primitives.limiter.v[1][1],
p->primitives.limiter.maxr);
hydro_slope_limit_cell_quantity(
p->primitives.gradients.v[2], p->primitives.v[2],
p->primitives.limiter.v[2][0], p->primitives.limiter.v[2][1],
p->primitives.limiter.maxr);
hydro_slope_limit_cell_quantity(
p->primitives.gradients.P, p->primitives.P, p->primitives.limiter.P[0],
p->primitives.limiter.P[1], p->primitives.limiter.maxr);
}