Skip to content

Commit

Permalink
Merge pull request #52 from MChabanov/eos
Browse files Browse the repository at this point in the history
Eos
  • Loading branch information
jaykalinani authored Jul 26, 2024
2 parents 4490ae4 + 1411563 commit 1213180
Show file tree
Hide file tree
Showing 3 changed files with 257 additions and 6 deletions.
44 changes: 39 additions & 5 deletions EOSX/src/eos_3p_tabulated3d.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include <string>
#include <AMReX.H>

#include "linear_interp_ND.hh"

using namespace std;

namespace EOSX {
Expand All @@ -28,14 +30,18 @@ using namespace amrex;
class eos_3p_tabulated3d : public eos_3p {

public:

linear_interp_uniform_ND_t<double, 3, NTABLES> interp;

CCTK_REAL gamma; // FIXME: get rid of this
range rgeps;

CCTK_INT ntemp, nrho, nye;

CCTK_REAL *logrho, *logtemp, *yes; // FIXME: AMREX_GPU_MANAGED?
CCTK_REAL *alltables;
CCTK_REAL *epstable;
//CCTK_REAL *logrho, *logtemp, *yes; // FIXME: AMREX_GPU_MANAGED?
//CCTK_REAL *alltables;
//CCTK_REAL *epstable;

CCTK_REAL energy_shift;

CCTK_HOST CCTK_DEVICE CCTK_ATTRIBUTE_ALWAYS_INLINE inline void init(
Expand Down Expand Up @@ -191,6 +197,11 @@ public:
CCTK_VINFO("EOS table dimensions: ntemp = %d, nrho = %d, nye = %d", ntemp, nrho, nye);

// Allocate memory for tables

CCTK_REAL *logrho, *logtemp, *yes;
CCTK_REAL *epstable;
CCTK_REAL *alltables;

double* alltables_temp;
if (!(alltables_temp = (double*)The_Managed_Arena()->alloc(npoints * NTABLES * sizeof(double)))) {
CCTK_VError(__LINE__, __FILE__, CCTK_THORNSTRING,
Expand Down Expand Up @@ -280,7 +291,7 @@ public:
// free memory of temporary array
free(alltables_temp);

// allocate epstable; a linear-scale eps table
// allocate epstable; a linear-scale eps table
// that allows us to extrapolate to negative eps
if (!(epstable = (double*)The_Managed_Arena()->alloc(npoints * sizeof(double)))) {
CCTK_VError(__LINE__, __FILE__, CCTK_THORNSTRING,
Expand All @@ -293,7 +304,7 @@ public:
energy_shift = energy_shift * EPSGF;
for(int i=0;i<nrho;i++) {
// rewrite:
//logrho[i] = log(pow(10.0,logrho[i]) * RHOGF);
// logrho[i] = log(pow(10.0,logrho[i]) * RHOGF);
// by using log(a^b*c) = b*log(a)+log(c)
logrho[i] = logrho[i] * log(10.) + log(RHOGF);
}
Expand Down Expand Up @@ -339,6 +350,29 @@ public:

}

auto num_points =
std::array<size_t, 3>{size_t(nrho), size_t(ntemp), size_t(nye)};

auto logrho_ptr = std::unique_ptr<double[]>(new double[nrho]);
auto logtemp_ptr = std::unique_ptr<double[]>(new double[ntemp]);
auto ye_ptr = std::unique_ptr<double[]>(new double[nye]);
auto alltables_ptr = std::unique_ptr<double[]>(new double[npoints*NTABLES]);

for (int i = 0; i < nrho; ++i) logrho_ptr[i] = logrho[i];
for (int i = 0; i < ntemp; ++i) logtemp_ptr[i] = logtemp[i];
for (int i = 0; i < nye; ++i) ye_ptr[i] = yes[i];
for (int i = 0; i < npoints * NTABLES; ++i) alltables_ptr[i] = alltables[i];

free(logrho);
free(logtemp);
free(yes);
free(alltables);
free(epstable);

interp = linear_interp_uniform_ND_t<double, 3, NTABLES>(
std::move(alltables_ptr), std::move(num_points), std::move(logrho_ptr),
std::move(logtemp_ptr), std::move(ye_ptr));

// set up steps, mins, maxes here?

return;
Expand Down
217 changes: 217 additions & 0 deletions EOSX/src/linear_interp_ND.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
/*
* =====================================================================================
*
* Filename: linear_interp_ND.hh
*
* Description: Linear interpolation for arbitrary dimensions
*
* Version: 1.1
* Created: 24/08/2017 10:00:00
* Revision: none
* Compiler: gcc,clang
*
* Author: Elias Roland Most (ERM), [email protected]
* Organization: Goethe University Frankfurt
*
* =====================================================================================
*/

#ifndef linear_interp_ND_INC
#define linear_interp_ND_INC

#include <array>
#include <cassert>
#include <cmath>
#include <iostream>
#include <memory>
#include <algorithm>

template <typename T, size_t dim, int num_vars, bool uniform>
class lintp_ND_t {
public:
using vec_ptr_t = std::unique_ptr<T[]>;

template <int N>
using vec_t = std::array<T, N>;

std::array<T, dim> idx, dx;
int nvars = num_vars;
std::array<size_t, dim> num_points;
std::array<vec_ptr_t, dim> x;
vec_ptr_t y;

private:
// Useful helper for checking conditions on template parameters
// https://stackoverflow.com/questions/28253399/check-traits-for-all-variadic-template-arguments/28253503#28253503
template <bool...>
struct bool_pack;
template <bool... bs>
using all_true = std::is_same<bool_pack<bs..., true>, bool_pack<true, bs...>>;

//! Get nearest table index of input value xin
inline __attribute__((always_inline)) size_t find_index(
size_t const which_dim, T const &xin) const {
if (uniform) {
// shift xin by lowest value
const auto xL = (xin - x[which_dim][0]);

if(xL <= 0) return 0;

auto index = static_cast<int>(xL * idx[which_dim]);

if(index > num_points[which_dim] - 2) return num_points[which_dim] - 2;

return index;

} else {
int lower = 0;
int upper = num_points[which_dim] - 1;
// simple bisection through the table range
while (upper - lower > 1) {
int tmp = lower + (upper - lower) / 2;
if (xin < x[which_dim][tmp])
upper = tmp;
else
lower = tmp;
}
return lower;
}
};

template <typename CI_t, size_t offset>
struct compressed_indexr_t {
template <size_t N = 0>
static inline __attribute__((always_inline)) size_t value(
std::array<size_t, dim> const &index,
std::array<size_t, dim> const &num_points) {
return offset + index[N] +
num_points[N] * CI_t::template value<N + 1>(index, num_points);
}
};

struct compressed_index_t {
template <size_t N = 0>
static inline __attribute__((always_inline)) size_t value(
std::array<size_t, dim> const &index,
std::array<size_t, dim> const &num_points) {
return 0;
}
};

static inline __attribute__((always_inline)) T const linterp1D(
T const &A, T const &B, T const &xA, T const &xB, T const &x) {
const auto lambda = (x - xA) / (xB - xA); // *ideltax;
// return A*(1.-lambda) + B*lambda;
return (B - A) * lambda + A;
}

// Unpack in dimension!
template <typename F_t, size_t which_dim, size_t var, typename CI_t,
typename X1, typename... Xt>
struct recursive_interpolate_single {
static inline __attribute__((always_inline)) T const linterp(
F_t const &F, std::array<size_t, dim> const &index, Xt const &... xin,
X1 const &x1) {
auto const xA = F.x[which_dim][index[which_dim]];
auto const xB = F.x[which_dim][index[which_dim] + 1];

auto const A =
recursive_interpolate_single<F_t, which_dim - 1, var,
compressed_indexr_t<CI_t, 0>,
Xt...>::linterp(F, index, xin...);
auto const B =
recursive_interpolate_single<F_t, which_dim - 1, var,
compressed_indexr_t<CI_t, 1>,
Xt...>::linterp(F, index, xin...);

return linterp1D(A, B, xA, xB, x1);
}
};

// Unpack in dimension!
template <typename F_t, size_t var, typename CI_t, typename X1>
struct recursive_interpolate_single<F_t, 0, var, CI_t, X1> {
static inline __attribute__((always_inline)) T const linterp(
F_t const &F, std::array<size_t, dim> const &index, X1 const &x1) {
constexpr size_t which_dim = 0;

auto const xA = F.x[which_dim][index[which_dim]];
auto const xB = F.x[which_dim][index[which_dim] + 1];

auto const A = F[var + num_vars * compressed_indexr_t<CI_t, 0>::value(
index, F.num_points)];
auto const B = F[var + num_vars * compressed_indexr_t<CI_t, 1>::value(
index, F.num_points)];

return linterp1D(A, B, xA, xB, x1);
}
};

public:
inline T const &operator[](const int i) const { return y[i]; }

inline int size(size_t const which_dim) { return num_points[which_dim]; }

inline T const &xmin(size_t which_dim) { return x[which_dim][0]; };

template <size_t which_dim>
inline T const &xmin() {
return x[which_dim][0];
};

inline T const &xmax(size_t which_dim) {
return x[which_dim][num_points[which_dim] - 1];
};

template <size_t which_dim>
inline T const &xmax() {
return x[which_dim][num_points[which_dim] - 1];
};

template <size_t... vars, typename... Xt>
inline vec_t<sizeof...(vars)> interpolate(Xt const &... xin) const {
static_assert(
all_true<(std::is_convertible<typename std::remove_cv<Xt>::type,
T>::value)...>::value,
"Interpolation points must be compatible with the data type of the "
"arrays.");
static_assert(
sizeof...(Xt) == dim,
"You need to provide the correct number of interpolation points");
static_assert(sizeof...(vars) <= num_vars,
"You are trying to interpolate more variables than this "
"container holds.");

int dir = -1;
auto const index =
std::array<size_t, dim>{(++dir, find_index(dir, xin))...};

return vec_t<sizeof...(vars)>{(
recursive_interpolate_single<decltype(*this), dim - 1, vars,
compressed_index_t,
Xt...>::linterp(*this, index, xin...))...};
};

lintp_ND_t() = default;

template <typename Yt, typename... Xt>
lintp_ND_t(Yt &&__y, std::array<size_t, dim> &&__num_points, Xt &&... __x)
: num_points(std::move(__num_points)), y(std::move(__y)) {
int n = 0;
int tmp[] = {(x[n] = std::forward<Xt>(__x), ++n)...};
(void)tmp;

for (int i = 0; i < dim; ++i) {
dx[i] = x[i][1] - x[i][0];
idx[i] = 1. / dx[i];
};
};
};

template <typename T, size_t dim, int num_vars>
using linear_interp_uniform_ND_t = lintp_ND_t<T, dim, num_vars, true>;

template <typename T, size_t dim, int num_vars>
using linear_interp_ND_t = lintp_ND_t<T, dim, num_vars, false>;

#endif /* ----- #ifndef linear_interp_ND_INC ----- */
2 changes: 1 addition & 1 deletion FishboneMoncriefIDX/param.ccl
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ BOOLEAN use_pressure "Use pressure to set up vector potential, otherwise density

##################################
restricted:
BOOLEAN atmo_type "Matter distribution around torus - atmosphere"
KEYWORD atmo_type "Matter distribution around torus - atmosphere"
{
"isentropic-graded" :: "Graded rho, pressure is set using polytropic EOS"
"free-graded" :: "Graded rho, pressure is using press_min below"
Expand Down

0 comments on commit 1213180

Please sign in to comment.