/******************************************************************************* * 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 */