/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2016 Matthieu Schaller (schaller@strw.leidenuniv.nl).
* 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 .
*
******************************************************************************/
#ifndef SWIFT_ADIABATIC_INDEX_H
#define SWIFT_ADIABATIC_INDEX_H
/**
* @file adiabatic_index.h
* @brief Defines the adiabatic index (polytropix index) \f$\gamma\f$ of the
* problem and (fast) mathematical functions involving it.
*/
/* Config parameters. */
#include
/* Some standard headers. */
#include
/* Local headers. */
#include "cbrt.h"
#include "error.h"
#include "inline.h"
/* First define some constants */
#if defined(HYDRO_GAMMA_5_3)
#define hydro_gamma 1.66666666666666667f
#define hydro_gamma_minus_one 0.66666666666666667f
#define hydro_gamma_plus_one 2.66666666666666667f
#define hydro_one_over_gamma_minus_one 1.5f
#define hydro_gamma_plus_one_over_two_gamma 0.8f
#define hydro_gamma_minus_one_over_two_gamma 0.2f
#define hydro_gamma_minus_one_over_gamma_plus_one 0.25f
#define hydro_two_over_gamma_plus_one 0.75f
#define hydro_two_over_gamma_minus_one 3.f
#define hydro_gamma_minus_one_over_two 0.33333333333333333f
#define hydro_two_gamma_over_gamma_minus_one 5.f
#define hydro_one_over_gamma 0.6f
#elif defined(HYDRO_GAMMA_7_5)
#define hydro_gamma 1.4f
#define hydro_gamma_minus_one 0.4f
#define hydro_gamma_plus_one 2.4f
#define hydro_one_over_gamma_minus_one 2.5f
#define hydro_gamma_plus_one_over_two_gamma 0.857142857f
#define hydro_gamma_minus_one_over_two_gamma 0.142857143f
#define hydro_gamma_minus_one_over_gamma_plus_one 0.166666667f
#define hydro_two_over_gamma_plus_one 0.833333333
#define hydro_two_over_gamma_minus_one 5.f
#define hydro_gamma_minus_one_over_two 0.2f
#define hydro_two_gamma_over_gamma_minus_one 7.f
#define hydro_one_over_gamma 0.714285714f
#elif defined(HYDRO_GAMMA_4_3)
#define hydro_gamma 1.33333333333333333f
#define hydro_gamma_minus_one 0.33333333333333333f
#define hydro_gamma_plus_one 2.33333333333333333f
#define hydro_one_over_gamma_minus_one 3.f
#define hydro_gamma_plus_one_over_two_gamma 0.875f
#define hydro_gamma_minus_one_over_two_gamma 0.125f
#define hydro_gamma_minus_one_over_gamma_plus_one 0.142857143f
#define hydro_two_over_gamma_plus_one 0.857142857f
#define hydro_two_over_gamma_minus_one 6.f
#define hydro_gamma_minus_one_over_two 0.166666666666666666f
#define hydro_two_gamma_over_gamma_minus_one 8.f
#define hydro_one_over_gamma 0.75f
#elif defined(HYDRO_GAMMA_2_1)
#define hydro_gamma 2.f
#define hydro_gamma_minus_one 1.f
#define hydro_gamma_plus_one 3.f
#define hydro_one_over_gamma_minus_one 1.f
#define hydro_gamma_plus_one_over_two_gamma 0.75f
#define hydro_gamma_minus_one_over_two_gamma 0.25f
#define hydro_gamma_minus_one_over_gamma_plus_one 0.33333333333333333f
#define hydro_two_over_gamma_plus_one 0.66666666666666666f
#define hydro_two_over_gamma_minus_one 2.f
#define hydro_gamma_minus_one_over_two 0.5f
#define hydro_two_gamma_over_gamma_minus_one 4.f
#define hydro_one_over_gamma 0.5f
#else
#error "An adiabatic index needs to be chosen in const.h !"
#endif
/**
* @brief Returns the argument to the power given by the adiabatic index
*
* Computes \f$x^\gamma\f$.
*/
__attribute__((always_inline, const)) INLINE static float pow_gamma(float x) {
#if defined(HYDRO_GAMMA_5_3)
#ifdef WITH_ICBRTF
const float icbrt = icbrtf(x); /* x^(-1/3) */
return icbrt * x * x; /* x^(5/3) */
#else
const float cbrt = cbrtf(x); /* x^(1/3) */
return cbrt * cbrt * x; /* x^(5/3) */
#endif // WITH_ICBRTF
#elif defined(HYDRO_GAMMA_7_5)
return powf(x, 1.4f); /* x^(7/5) */
#elif defined(HYDRO_GAMMA_4_3)
#ifdef WITH_ICBRTF
const float icbrt = icbrtf(x); /* x^(-1/3) */
return icbrt * icbrt * x * x; /* x^(4/3) */
#else
return cbrtf(x) * x; /* x^(4/3) */
#endif // WITH_ICBRTF
#elif defined(HYDRO_GAMMA_2_1)
return x * x;
#else
error("The adiabatic index is not defined !");
return 0.f;
#endif
}
/**
* @brief Returns the argument to the power given by the adiabatic index minus
* one
*
* Computes \f$x^{(\gamma-1)}\f$.
*/
__attribute__((always_inline, const)) INLINE static float pow_gamma_minus_one(
float x) {
#if defined(HYDRO_GAMMA_5_3)
#ifdef WITH_ICBRTF
const float icbrt = icbrtf(x); /* x^(-1/3) */
return x * icbrt; /* x^(2/3) */
#else
const float cbrt = cbrtf(x); /* x^(1/3) */
return cbrt * cbrt; /* x^(2/3) */
#endif // WITH_ICBRTF
#elif defined(HYDRO_GAMMA_7_5)
return powf(x, 0.4f); /* x^(2/5) */
#elif defined(HYDRO_GAMMA_4_3)
#ifdef WITH_ICBRTF
const float icbrt = icbrtf(x); /* x^(-1/3) */
return x * icbrt * icbrt; /* x^(1/3) */
#else
return cbrtf(x); /* x^(1/3) */
#endif // WITH_ICBRTF
#elif defined(HYDRO_GAMMA_2_1)
return x;
#else
error("The adiabatic index is not defined !");
return 0.f;
#endif
}
/**
* @brief Returns one over the argument to the power given by the adiabatic
* index minus one
*
* Computes \f$x^{-(\gamma-1)}\f$.
*/
__attribute__((always_inline, const)) INLINE static float
pow_minus_gamma_minus_one(float x) {
#if defined(HYDRO_GAMMA_5_3)
#ifdef WITH_ICBRTF
const float icbrt = icbrtf(x); /* x^(-1/3) */
return icbrt * icbrt; /* x^(-2/3) */
#else
const float cbrt_inv = 1.f / cbrtf(x); /* x^(-1/3) */
return cbrt_inv * cbrt_inv; /* x^(-2/3) */
#endif // WITH_ICBRTF
#elif defined(HYDRO_GAMMA_7_5)
return powf(x, -0.4f); /* x^(-2/5) */
#elif defined(HYDRO_GAMMA_4_3)
#ifdef WITH_ICBRTF
return icbrtf(x); /* x^(-1/3) */
#else
return 1.f / cbrtf(x); /* x^(-1/3) */
#endif // WITH_ICBRTF
#elif defined(HYDRO_GAMMA_2_1)
return 1.f / x;
#else
error("The adiabatic index is not defined !");
return 0.f;
#endif
}
/**
* @brief Returns one over the argument to the power given by the adiabatic
* index
*
* Computes \f$x^{-\gamma}\f$.
*
* @param x Argument
* @return One over the argument to the power given by the adiabatic index
*/
__attribute__((always_inline, const)) INLINE static float pow_minus_gamma(
float x) {
#if defined(HYDRO_GAMMA_5_3)
#ifdef WITH_ICBRTF
const float icbrt = icbrtf(x); /* x^(-1/3) */
const float icbrt2 = icbrt * icbrt; /* x^(-2/3) */
return icbrt * icbrt2 * icbrt2; /* x^(-5/3) */
#else
const float cbrt_inv = 1.f / cbrtf(x); /* x^(-1/3) */
const float cbrt_inv2 = cbrt_inv * cbrt_inv; /* x^(-2/3) */
return cbrt_inv * cbrt_inv2 * cbrt_inv2; /* x^(-5/3) */
#endif // WITH_ICBRTF
#elif defined(HYDRO_GAMMA_7_5)
return powf(x, -1.4f); /* x^(-7/5) */
#elif defined(HYDRO_GAMMA_4_3)
#ifdef WITH_ICBRTF
const float cbrt_inv = icbrtf(x); /* x^(-1/3) */
#else
const float cbrt_inv = 1.f / cbrtf(x); /* x^(-1/3) */
#endif // WITH_ICBRTF
const float cbrt_inv2 = cbrt_inv * cbrt_inv; /* x^(-2/3) */
return cbrt_inv2 * cbrt_inv2; /* x^(-4/3) */
#elif defined(HYDRO_GAMMA_2_1)
const float inv = 1.f / x;
return inv * inv;
#else
error("The adiabatic index is not defined !");
return 0.f;
#endif
}
/**
* @brief Return the argument to the power given by two divided by the adiabatic
* index minus one
*
* Computes \f$x^{\frac{2}{\gamma - 1}}\f$.
*
* @param x Argument
* @return Argument to the power two divided by the adiabatic index minus one
*/
__attribute__((always_inline, const)) INLINE static float
pow_two_over_gamma_minus_one(float x) {
#if defined(HYDRO_GAMMA_5_3)
return x * x * x; /* x^3 */
#elif defined(HYDRO_GAMMA_7_5)
const float x2 = x * x;
const float x3 = x2 * x;
return x2 * x3;
#elif defined(HYDRO_GAMMA_4_3)
const float x3 = x * x * x; /* x^3 */
return x3 * x3; /* x^6 */
#elif defined(HYDRO_GAMMA_2_1)
return x * x; /* x^2 */
#else
error("The adiabatic index is not defined !");
return 0.f;
#endif
}
/**
* @brief Return the argument to the power given by two times the adiabatic
* index divided by the adiabatic index minus one
*
* Computes \f$x^{\frac{2\gamma}{\gamma - 1}}\f$.
*
* @param x Argument
* @return Argument to the power two times the adiabatic index divided by the
* adiabatic index minus one
*/
__attribute__((always_inline, const)) INLINE static float
pow_two_gamma_over_gamma_minus_one(float x) {
#if defined(HYDRO_GAMMA_5_3)
const float x2 = x * x;
const float x3 = x2 * x;
return x2 * x3;
#elif defined(HYDRO_GAMMA_7_5)
const float x2 = x * x;
const float x4 = x2 * x2;
return x4 * x2 * x;
#elif defined(HYDRO_GAMMA_4_3)
const float x2 = x * x;
const float x4 = x2 * x2;
return x4 * x4; /* x^8 */
#elif defined(HYDRO_GAMMA_2_1)
const float x2 = x * x;
return x2 * x2; /* x^4 */
#else
error("The adiabatic index is not defined !");
return 0.f;
#endif
}
/**
* @brief Return the argument to the power given by the adiabatic index minus
* one divided by two times the adiabatic index
*
* Computes \f$x^{\frac{\gamma - 1}{2\gamma}}\f$.
*
* @param x Argument
* @return Argument to the power the adiabatic index minus one divided by two
* times the adiabatic index
*/
__attribute__((always_inline, const)) INLINE static float
pow_gamma_minus_one_over_two_gamma(float x) {
#if defined(HYDRO_GAMMA_5_3)
return powf(x, 0.2f); /* x^0.2 */
#elif defined(HYDRO_GAMMA_7_5)
return powf(x, hydro_gamma_minus_one_over_two_gamma);
#elif defined(HYDRO_GAMMA_4_3)
return powf(x, 0.125f); /* x^0.125 */
#elif defined(HYDRO_GAMMA_2_1)
return powf(x, 0.25f); /* x^0.25 */
#else
error("The adiabatic index is not defined !");
return 0.f;
#endif
}
/**
* @brief Return the inverse argument to the power given by the adiabatic index
* plus one divided by two times the adiabatic index
*
* Computes \f$x^{-\frac{\gamma + 1}{2\gamma}}\f$.
*
* @param x Argument
* @return Inverse argument to the power the adiabatic index plus one divided by
* two times the adiabatic index
*/
__attribute__((always_inline, const)) INLINE static float
pow_minus_gamma_plus_one_over_two_gamma(float x) {
#if defined(HYDRO_GAMMA_5_3)
return powf(x, -0.8f); /* x^-0.8 */
#elif defined(HYDRO_GAMMA_7_5)
return powf(x, -hydro_gamma_plus_one_over_two_gamma);
#elif defined(HYDRO_GAMMA_4_3)
return powf(x, -0.875f); /* x^-0.875 */
#elif defined(HYDRO_GAMMA_2_1)
return powf(x, -0.75f); /* x^-0.75 */
#else
error("The adiabatic index is not defined !");
return 0.f;
#endif
}
/**
* @brief Return the argument to the power one over the adiabatic index
*
* Computes \f$x^{\frac{1}{\gamma}}\f$.
*
* @param x Argument
* @return Argument to the power one over the adiabatic index
*/
__attribute__((always_inline, const)) INLINE static float pow_one_over_gamma(
float x) {
#if defined(HYDRO_GAMMA_5_3)
return powf(x, hydro_one_over_gamma); /* x^(3/5) */
#elif defined(HYDRO_GAMMA_7_5)
return powf(x, hydro_one_over_gamma);
#elif defined(HYDRO_GAMMA_4_3)
return powf(x, hydro_one_over_gamma); /* x^(3/4) */
#elif defined(HYDRO_GAMMA_2_1)
return sqrtf(x); /* x^(1/2) */
#else
error("The adiabatic index is not defined !");
return 0.f;
#endif
}
/**
* @brief Return the argument to the power three adiabatic index minus two.
*
* Computes \f$x^{3\gamma - 2}\f$.
*
* @param x Argument
*/
__attribute__((always_inline, const)) INLINE static float
pow_three_gamma_minus_two(float x) {
#if defined(HYDRO_GAMMA_5_3)
return x * x * x; /* x^(3) */
#elif defined(HYDRO_GAMMA_7_5)
return powf(x, 2.2f); /* x^(11/5) */
#elif defined(HYDRO_GAMMA_4_3)
return x * x; /* x^(2) */
#elif defined(HYDRO_GAMMA_2_1)
return x * x * x * x; /* x^(4) */
#else
error("The adiabatic index is not defined !");
return 0.f;
#endif
}
/**
* @brief Return the argument to the power three adiabatic index minus five over
* two.
*
* Computes \f$x^{(3\gamma - 5)/2}\f$.
*
* @param x Argument
*/
__attribute__((always_inline, const)) INLINE static float
pow_three_gamma_minus_five_over_two(float x) {
#if defined(HYDRO_GAMMA_5_3)
return 1.f; /* x^(0) */
#elif defined(HYDRO_GAMMA_7_5)
return powf(x, -0.4f); /* x^(-2/5) */
#elif defined(HYDRO_GAMMA_4_3)
return 1.f / sqrtf(x); /* x^(-1/2) */
#elif defined(HYDRO_GAMMA_2_1)
return sqrtf(x); /* x^(1/2) */
#else
error("The adiabatic index is not defined !");
return 0.f;
#endif
}
/**
* @brief Return the argument to the power three (adiabatic index - 1).
*
* Computes \f$x^{3(\gamma - 1)}\f$.
*
* @param x Argument
*/
__attribute__((always_inline, const)) INLINE static float
pow_three_gamma_minus_one(float x) {
#if defined(HYDRO_GAMMA_5_3)
return x * x; /* x^(2) */
#elif defined(HYDRO_GAMMA_7_5)
return powf(x, 1.2f); /* x^(6/5) */
#elif defined(HYDRO_GAMMA_4_3)
return x; /* x^(1) */
#elif defined(HYDRO_GAMMA_2_1)
return x * x * x; /* x^(3) */
#else
error("The adiabatic index is not defined !");
return 0.f;
#endif
}
#endif /* SWIFT_ADIABATIC_INDEX_H */