Merge branch 'master' of bitbucket.org:glavaux/cosmotool

This commit is contained in:
Guilhem Lavaux 2015-02-10 13:55:57 +01:00
commit 622c575265
18 changed files with 326 additions and 104 deletions

View File

@ -22,11 +22,13 @@ option(INTERNAL_HDF5 "Build internal version of HDF5" OFF)
option(INTERNAL_NETCDF "Build internal version of NETCDF" OFF) option(INTERNAL_NETCDF "Build internal version of NETCDF" OFF)
option(INTERNAL_BOOST "Build internal version of BOOST" OFF) option(INTERNAL_BOOST "Build internal version of BOOST" OFF)
IF(BUILD_SHARED_LIBS AND BUILD_STATIC_LIBS) IF(NOT BUILD_SHARED_LIBS AND BUILD_STATIC_LIBS)
SET(CosmoTool_local CosmoTool_static) SET(CosmoTool_local CosmoTool_static)
ELSE(BUILD_SHARED_LIBS AND BUILD_STATIC_LIBS) ELSE(NOT BUILD_SHARED_LIBS AND BUILD_STATIC_LIBS)
SET(CosmoTool_local CosmoTool) SET(CosmoTool_local CosmoTool)
ENDIF(BUILD_SHARED_LIBS AND BUILD_STATIC_LIBS) ENDIF(NOT BUILD_SHARED_LIBS AND BUILD_STATIC_LIBS)
MESSAGE(STATUS "Using the target ${CosmoTool_local} to build python module")
include(${CMAKE_SOURCE_DIR}/external/external_build.cmake) include(${CMAKE_SOURCE_DIR}/external/external_build.cmake)
@ -40,11 +42,10 @@ ENDIF(EXISTS ${NETCDFCPP_INCLUDE_PATH}/netcdf AND ${NETCDFCPP_LIBRARY} MATCHES "
find_program(CYTHON cython) find_program(CYTHON cython)
set(HDF5_FIND_COMPONENTS HL CXX)
if(HDF5_ROOTDIR) if(HDF5_ROOTDIR)
SET(ENV{HDF5_ROOT} ${HDF5_ROOTDIR}) SET(ENV{HDF5_ROOT} ${HDF5_ROOTDIR})
endif(HDF5_ROOTDIR) endif(HDF5_ROOTDIR)
include(FindHDF5) find_package(HDF5 COMPONENTS HL CXX)
set(NETCDF_FIND_REQUIRED TRUE) set(NETCDF_FIND_REQUIRED TRUE)

View File

@ -41,3 +41,13 @@ Timing
.. autofunction:: time_block .. autofunction:: time_block
.. autofunction:: timeit .. autofunction:: timeit
.. autofunction:: timeit_quiet .. autofunction:: timeit_quiet
Cosmology
^^^^^^^^^
Power spectrum
--------------
.. autoclass:: CosmologyPower
:members:

View File

@ -100,7 +100,7 @@ if (INTERNAL_NETCDF)
CONFIGURE_COMMAND ${NETCDF_SOURCE_DIR}/configure CONFIGURE_COMMAND ${NETCDF_SOURCE_DIR}/configure
--prefix=${NETCDF_BIN_DIR} --libdir=${NETCDF_BIN_DIR}/lib --prefix=${NETCDF_BIN_DIR} --libdir=${NETCDF_BIN_DIR}/lib
--enable-netcdf-4 --with-pic --disable-shared --disable-dap --enable-netcdf-4 --with-pic --disable-shared --disable-dap
--disable-cdmremote --disable-rpc --disable-cdmremote --disable-rpc --enable-cxx-4
--disable-examples ${EXTRA_NC_FLAGS} CC=${CMAKE_C_COMPILER} --disable-examples ${EXTRA_NC_FLAGS} CC=${CMAKE_C_COMPILER}
CXX=${CMAKE_CXX_COMPILER} CXX=${CMAKE_CXX_COMPILER}
BUILD_IN_SOURCE 1 BUILD_IN_SOURCE 1
@ -110,7 +110,7 @@ if (INTERNAL_NETCDF)
SET(EXTRA_NC_FLAGS CPPFLAGS=${CONFIGURE_CPP_FLAGS} LDFLAGS=${CONFIGURE_CPP_LDFLAGS}) SET(EXTRA_NC_FLAGS CPPFLAGS=${CONFIGURE_CPP_FLAGS} LDFLAGS=${CONFIGURE_CPP_LDFLAGS})
SET(cosmotool_DEPS ${cosmotool_DEPS} netcdf) SET(cosmotool_DEPS ${cosmotool_DEPS} netcdf)
SET(NETCDF_LIBRARY ${NETCDF_BIN_DIR}/lib/libnetcdf.a CACHE STRING "NetCDF lib" FORCE) SET(NETCDF_LIBRARY ${NETCDF_BIN_DIR}/lib/libnetcdf.a CACHE STRING "NetCDF lib" FORCE)
SET(NETCDFCPP_LIBRARY ${NETCDF_BIN_DIR}/lib/libnetcdf_c++.a CACHE STRING "NetCDF-C++ lib" FORCE) SET(NETCDFCPP_LIBRARY ${NETCDF_BIN_DIR}/lib/libnetcdf_c++4.a CACHE STRING "NetCDF-C++ lib" FORCE)
SET(NETCDF_INCLUDE_PATH ${NETCDF_BIN_DIR}/include CACHE STRING "NetCDF include" FORCE) SET(NETCDF_INCLUDE_PATH ${NETCDF_BIN_DIR}/include CACHE STRING "NetCDF include" FORCE)
SET(NETCDFCPP_INCLUDE_PATH ${NETCDF_INCLUDE_PATH} CACHE STRING "NetCDF C++ include path" FORCE) SET(NETCDFCPP_INCLUDE_PATH ${NETCDF_INCLUDE_PATH} CACHE STRING "NetCDF C++ include path" FORCE)

View File

@ -49,11 +49,21 @@ cdef extern from "cosmopower.hpp" namespace "CosmoTool":
double power(double) double power(double)
cdef class CosmologyPower: cdef class CosmologyPower:
"""CosmologyPower(**cosmo)
CosmologyPower manages and compute power spectra computation according to different
approximation given in the litterature.
Keyword arguments:
omega_B_0 (float): relative baryon density
omega_M_0 (float): relative matter density
h (float): Hubble constant relative to 100 km/s/Mpc
ns (float): power law of the large scale inflation spectrum
"""
cdef CosmoPower power cdef CosmoPower power
def __init__(self,**cosmo): def __init__(self,**cosmo):
self.power = CosmoPower() self.power = CosmoPower()
self.power.OMEGA_B = cosmo['omega_B_0'] self.power.OMEGA_B = cosmo['omega_B_0']
self.power.OMEGA_C = cosmo['omega_M_0']-cosmo['omega_B_0'] self.power.OMEGA_C = cosmo['omega_M_0']-cosmo['omega_B_0']
@ -66,11 +76,26 @@ cdef class CosmologyPower:
self.power.updateCosmology() self.power.updateCosmology()
def normalize(self,s8): def normalize(self,s8):
"""normalize(self, sigma8)
Compute the normalization of the power spectrum using sigma8.
Arguments:
sigma8 (float): standard deviation of density field smoothed at 8 Mpc/h
"""
self.power.SIGMA8 = s8 self.power.SIGMA8 = s8
self.power.normalize() self.power.normalize()
def setFunction(self,funcname): def setFunction(self,funcname):
"""setFunction(self, funcname)
Choose an approximation to use for the computation of the power spectrum
Arguments:
funcname (str): the name of the approximation. It can be either
EFSTATHIOU, HU_WIGGLES, HU_BARYON, BARDEEN or SUGIYAMA.
"""
cdef CosmoFunction f cdef CosmoFunction f
f = POWER_EFSTATHIOU f = POWER_EFSTATHIOU
@ -93,6 +118,19 @@ cdef class CosmologyPower:
return self.power.power(k) * self.power.h**3 return self.power.power(k) * self.power.h**3
def compute(self, k): def compute(self, k):
"""compute(self, k)
Compute the power spectrum for mode which length k.
Arguments:
k (float): Mode for which to evaluate the power spectrum.
It can be a scalar or a numpy array.
The units must be in 'h Mpc^{-1}'.
Returns:
a scalar or a numpy array depending on the type of the k argument
"""
cdef np.ndarray out cdef np.ndarray out
cdef double kval cdef double kval
cdef tuple i cdef tuple i

View File

@ -808,7 +808,25 @@ def spherical_projection(int Nside,
npx.ndarray[DTYPE_t, ndim=3] density not None, npx.ndarray[DTYPE_t, ndim=3] density not None,
DTYPE_t min_distance, DTYPE_t min_distance,
DTYPE_t max_distance, int progress=1, int integrator_id=0, DTYPE_t[:] shifter = None, int booster=-1): DTYPE_t max_distance, int progress=1, int integrator_id=0, DTYPE_t[:] shifter = None, int booster=-1):
"""
spherical_projection(Nside, density, min_distance, max_distance, progress=1, integrator_id=0, shifter=None, booster=-1)
Keyword arguments:
progress (int): show progress if it is equal to 1
integrator_id (int): specify the order of integration along the line of shift
shifter (DTYPE_t array): this is an array of size 3. It specifies the amount of shift to apply to the center, in unit of voxel
booster (int): what is the frequency of refreshment of the progress bar. Small number decreases performance by locking the GIL.
Arguments:
Nside (int): Nside of the returned map
density (NxNxN array): this is the density field, expressed as a cubic array
min_distance (float): lower bound of the integration
max_distance (float): upper bound of the integration
Returns:
an healpix map, as a 1-dimensional array.
"""
import healpy as hp import healpy as hp
import progressbar as pb import progressbar as pb
cdef int i cdef int i

View File

@ -1,7 +1,7 @@
### ###
### BORG code is from J. Jasche ### BORG code is from J. Jasche
### ###
import StringIO import io
import numpy as np import numpy as np
from numpy import * from numpy import *
import os.path import os.path
@ -154,9 +154,11 @@ def get_grid_values(xx,data, ranges):
def get_mean_density(fdir, smin, step): def get_mean_density(fdir, smin, step):
""" estimate ensemble mean """ estimate ensemble mean
""" """
print '-'*60 import progressbar as pb
print 'Get 3D ensemble mean density field'
print '-'*60 print('-'*60)
print('Get 3D ensemble mean density field')
print('-'*60)
fname0 = fdir + 'initial_density_'+str(0)+'.dat' fname0 = fdir + 'initial_density_'+str(0)+'.dat'
fname1 = fdir + 'final_density_'+str(0)+'.dat' fname1 = fdir + 'final_density_'+str(0)+'.dat'
@ -208,16 +210,20 @@ def get_mean_density(fdir, smin, step):
def get_mean_density_fdir(fdir,init,steps): def get_mean_density_fdir(fdir,init,steps):
""" estimate ensemble mean """ estimate ensemble mean
""" """
print '-'*60 import progressbar as pb
print 'Get 3D ensemble mean density field'
print '-'*60 print('-'*60)
print('Get 3D ensemble mean density field')
print('-'*60)
fname0,fname1=build_filelist(fdir) fname0,fname1=build_filelist(fdir)
fname0=fname0[init::steps] fname0=fname0[init::steps]
fname1=fname1[init::steps] fname1=fname1[init::steps]
MEAN0,ranges=read_borg_vol(fname0[0]) borg=read_borg_vol(fname0[0])
MEAN0 = borg.density
RANGES0 = borg.ranges
MEAN0=MEAN0*0.; MEAN0=MEAN0*0.;
VAR0=copy(MEAN0) VAR0=copy(MEAN0)
MEAN1=copy(MEAN0) MEAN1=copy(MEAN0)
@ -225,21 +231,23 @@ def get_mean_density_fdir(fdir,init,steps):
norm0=0. norm0=0.
norm1=0. norm1=0.
for fn in fname0: for fn in pb.ProgressBar(len(fname0))(fname0):
auxdata0,auxranges0=read_borg_vol(fn) auxborg=read_borg_vol(fn)
auxdata0 = auxborg.density
MEAN0+=auxdata0 MEAN0+=auxdata0
VAR0+=auxdata0**2. VAR0+=auxdata0**2.
norm0+=1. norm0+=1.
del auxranges0
del auxdata0 del auxdata0
del auxborg
for fn in fname1: for fn in pb.ProgressBar(len(fname1))(fname1):
auxdata1,auxranges1=read_borg_vol(fn) auxborg1=read_borg_vol(fn)
auxdata1 = auxborg1.density
MEAN1+=auxdata1 MEAN1+=auxdata1
VAR1+=auxdata1**2. VAR1+=auxdata1**2.
norm1+=1. norm1+=1.
del auxranges1
del auxdata1 del auxdata1
del auxborg1
MEAN0/=norm0 MEAN0/=norm0
VAR0/=norm0 VAR0/=norm0

View File

@ -4,7 +4,7 @@ import numpy as np
def cicParticles(particles, L, N): def cicParticles(particles, L, N):
if type(N) not in [int,long]: if type(N) not in [int,int]:
raise TypeError("N must be a numeric type") raise TypeError("N must be a numeric type")
def shifted(i, t): def shifted(i, t):
@ -14,7 +14,7 @@ def cicParticles(particles, L, N):
i =[] i =[]
r = [] r = []
for d in xrange(3): for d in range(3):
q = ne.evaluate('(p%L)*N/L', local_dict={'p':particles[d], 'L':L, 'N':N }) q = ne.evaluate('(p%L)*N/L', local_dict={'p':particles[d], 'L':L, 'N':N })
o = np.empty(q.size, dtype=np.int64) o = np.empty(q.size, dtype=np.int64)
o[:] = np.floor(q) o[:] = np.floor(q)

View File

@ -163,8 +163,8 @@ class CIC_CL(object):
# 2 dimensions # 2 dimensions
translator['ndim'] = ndim translator['ndim'] = ndim
translator['centered'] = '1' if centered else '0' translator['centered'] = '1' if centered else '0'
looperVariables = ','.join(['id%d' % d for d in xrange(ndim)]) looperVariables = ','.join(['id%d' % d for d in range(ndim)])
looperFor = '\n'.join(['for (int id{dim}=0; id{dim} < 2; id{dim}++) {{'.format(dim=d) for d in xrange(ndim)]) looperFor = '\n'.join(['for (int id{dim}=0; id{dim} < 2; id{dim}++) {{'.format(dim=d) for d in range(ndim)])
looperForEnd = '}' * ndim looperForEnd = '}' * ndim
kern = pragmas + CIC_PREKERNEL.format(**translator) + (CIC_KERNEL % {'looperVariables': looperVariables, 'looperFor': looperFor, 'looperForEnd':looperForEnd}) kern = pragmas + CIC_PREKERNEL.format(**translator) + (CIC_KERNEL % {'looperVariables': looperVariables, 'looperFor': looperFor, 'looperForEnd':looperForEnd})

View File

@ -27,7 +27,7 @@ def readGrafic(filename):
BoxSize = delta * Nx * h BoxSize = delta * Nx * h
checkPoint = 4*Ny*Nz checkPoint = 4*Ny*Nz
for i in xrange(Nx): for i in range(Nx):
checkPoint = struct.unpack("I", f.read(4))[0] checkPoint = struct.unpack("I", f.read(4))[0]
if checkPoint != 4*Ny*Nz: if checkPoint != 4*Ny*Nz:
raise ValueError("Invalid unformatted access") raise ValueError("Invalid unformatted access")
@ -57,7 +57,7 @@ def writeGrafic(filename, field, BoxSize, scalefac, **cosmo):
cosmo['omega_M_0'], cosmo['omega_lambda_0'], 100*cosmo['h'], checkPoint)) cosmo['omega_M_0'], cosmo['omega_lambda_0'], 100*cosmo['h'], checkPoint))
checkPoint = 4*Ny*Nz checkPoint = 4*Ny*Nz
field = field.reshape(field.shape, order='F') field = field.reshape(field.shape, order='F')
for i in xrange(Nx): for i in range(Nx):
f.write(struct.pack("I", checkPoint)) f.write(struct.pack("I", checkPoint))
f.write(field[i].astype(np.float32).tostring()) f.write(field[i].astype(np.float32).tostring())
f.write(struct.pack("I", checkPoint)) f.write(struct.pack("I", checkPoint))
@ -73,7 +73,7 @@ def writeWhitePhase(filename, field):
field = field.reshape(field.shape, order='F') field = field.reshape(field.shape, order='F')
checkPoint = struct.pack("I", 4*Nx*Ny) checkPoint = struct.pack("I", 4*Nx*Ny)
for i in xrange(Nx): for i in range(Nx):
f.write(checkPoint) f.write(checkPoint)
f.write(field[i].astype(np.float32).tostring()) f.write(field[i].astype(np.float32).tostring())
f.write(checkPoint) f.write(checkPoint)
@ -87,7 +87,7 @@ def readWhitePhase(filename):
checkPoint_ref = 4*Ny*Nz checkPoint_ref = 4*Ny*Nz
for i in xrange(Nx): for i in range(Nx):
if struct.unpack("I", f.read(4))[0] != checkPoint_ref: if struct.unpack("I", f.read(4))[0] != checkPoint_ref:
raise ValueError("Invalid unformatted access") raise ValueError("Invalid unformatted access")

View File

@ -14,7 +14,7 @@ def time_block(name):
yield yield
te = time.time() te = time.time()
print ('%s %2.2f sec' % (name, te-ts)) print('%s %2.2f sec' % (name, te-ts))
def timeit(method): def timeit(method):
"""This decorator add a timing request for each call to the decorated function. """This decorator add a timing request for each call to the decorated function.
@ -28,7 +28,7 @@ def timeit(method):
result = method(*args, **kw) result = method(*args, **kw)
te = time.time() te = time.time()
print ('%r (%r, %r) %2.2f sec' % (method.__name__, args, kw, te-ts)) print('%r (%r, %r) %2.2f sec' % (method.__name__, args, kw, te-ts))
return result return result
return timed return timed
@ -46,7 +46,7 @@ def timeit_quiet(method):
result = method(*args, **kw) result = method(*args, **kw)
te = time.time() te = time.time()
print ('%r %2.2f sec' % (method.__name__, te-ts)) print('%r %2.2f sec' % (method.__name__, te-ts))
return result return result
return timed return timed

View File

@ -1,3 +1,4 @@
#include "openmp.hpp"
#include "omptl/algorithm" #include "omptl/algorithm"
#include <cassert> #include <cassert>
#include "yorick.hpp" #include "yorick.hpp"
@ -53,7 +54,7 @@ void computeInterpolatedField(MyTree *tree1, double boxsize, int Nres, double cx
{ {
double pz = (rz)*boxsize/Nres-cz; double pz = (rz)*boxsize/Nres-cz;
cout << format("[%d] %d / %d") % omp_get_thread_num() % rz % Nres << endl; cout << format("[%d] %d / %d") % smp_get_thread_id() % rz % Nres << endl;
for (int ry = 0; ry < Nres; ry++) for (int ry = 0; ry < Nres; ry++)
{ {
double py = (ry)*boxsize/Nres-cy; double py = (ry)*boxsize/Nres-cy;

View File

@ -38,10 +38,37 @@ knowledge of the CeCILL license and that you accept its terms.
using namespace std; using namespace std;
struct MyStruct
{
int a;
double b;
char c;
};
struct MyStruct2
{
MyStruct base;
int d;
};
CTOOL_STRUCT_TYPE(MyStruct, hdf5t_MyStruct,
((int, a))
((double, b))
((char, c))
)
CTOOL_STRUCT_TYPE(MyStruct2, hdf5t_MyStruct2,
((MyStruct, base))
((int, d))
)
int main() int main()
{ {
typedef boost::multi_array<float, 2> array_type; typedef boost::multi_array<float, 2> array_type;
typedef boost::multi_array<float, 3> array3_type; typedef boost::multi_array<float, 3> array3_type;
typedef boost::multi_array<MyStruct, 1> array_mys_type;
typedef boost::multi_array<MyStruct2, 1> array_mys2_type;
typedef boost::multi_array<std::complex<double>, 2> arrayc_type; typedef boost::multi_array<std::complex<double>, 2> arrayc_type;
typedef array_type::index index; typedef array_type::index index;
@ -53,13 +80,27 @@ int main()
array_type B; array_type B;
array3_type C(boost::extents[2][3][4]); array3_type C(boost::extents[2][3][4]);
arrayc_type D, E; arrayc_type D, E;
array_mys_type F(boost::extents[10]), G;
array_mys2_type H(boost::extents[10]);
int values = 0; int values = 0;
for (index i = 0; i != 2; i++) for (index i = 0; i != 2; i++)
for (index j = 0; j != 3; j++) for (index j = 0; j != 3; j++)
A[i][j] = values++; A[i][j] = values++;
for (index i = 0; i != 10; i++)
{
F[i].a = i;
F[i].b = double(i)/4.;
F[i].c = 'r'+i;
H[i].base = F[i];
H[i].d = 2*i;
}
std::cout << " c = " << ((char *)&F[1])[offsetof(MyStruct, c)] << endl;
CosmoTool::hdf5_write_array(g, "test_data", A); CosmoTool::hdf5_write_array(g, "test_data", A);
CosmoTool::hdf5_write_array(g, "test_struct", F);
CosmoTool::hdf5_write_array(g, "test_struct2", H);
CosmoTool::hdf5_read_array(g, "test_data", B); CosmoTool::hdf5_read_array(g, "test_data", B);
@ -95,5 +136,12 @@ int main()
abort(); abort();
} }
CosmoTool::hdf5_read_array(g, "test_struct", G);
for (index i = 0; i != 10; i++)
if (G[i].a != F[i].a || G[i].b != F[i].b || G[i].c != F[i].c) {
std::cout << "Invalid struct content" << endl;
abort();
}
return 0; return 0;
} }

View File

@ -1,4 +1,3 @@
add_definitions(-fPIC)
SET(CosmoTool_SRCS SET(CosmoTool_SRCS
fortran.cpp fortran.cpp
@ -6,7 +5,6 @@ SET(CosmoTool_SRCS
load_data.cpp load_data.cpp
loadGadget.cpp loadGadget.cpp
loadRamses.cpp loadRamses.cpp
octTree.cpp
powerSpectrum.cpp powerSpectrum.cpp
miniargs.cpp miniargs.cpp
growthFactor.cpp growthFactor.cpp
@ -76,9 +74,11 @@ if (BUILD_SHARED_LIBS)
target_link_libraries(CosmoTool ${CosmoTool_LIBS}) target_link_libraries(CosmoTool ${CosmoTool_LIBS})
if (BUILD_STATIC_LIBS) if (BUILD_STATIC_LIBS)
add_library(CosmoTool_static STATIC ${CosmoTool_SRCS}) add_library(CosmoTool_static STATIC ${CosmoTool_SRCS})
set_target_properties(CosmoTool_static PROPERTIES COMPILE_FLAGS "${CMAKE_C_COMPILE_OPTIONS_PIC}")
endif(BUILD_STATIC_LIBS) endif(BUILD_STATIC_LIBS)
else (BUILD_SHARED_LIBS) else (BUILD_SHARED_LIBS)
add_library(CosmoTool STATIC ${CosmoTool_SRCS}) add_library(CosmoTool STATIC ${CosmoTool_SRCS})
set_target_properties(CosmoTool PROPERTIES COMPILE_FLAGS "${CMAKE_C_COMPILE_OPTIONS_PIC}")
endif (BUILD_SHARED_LIBS) endif (BUILD_SHARED_LIBS)
install(TARGETS CosmoTool install(TARGETS CosmoTool

View File

@ -44,6 +44,9 @@ knowledge of the CeCILL license and that you accept its terms.
#include <boost/multi_array.hpp> #include <boost/multi_array.hpp>
#include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_floating_point.hpp> #include <boost/type_traits/is_floating_point.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <vector> #include <vector>
#include <H5Cpp.h> #include <H5Cpp.h>
@ -59,7 +62,7 @@ namespace CosmoTool {
template<typename T, class Enable = void> struct get_hdf5_data_type template<typename T, class Enable = void> struct get_hdf5_data_type
{ {
static H5::PredType type() static H5::DataType type()
{ {
BOOST_MPL_ASSERT_MSG(0, Unknown_HDF5_data_type, ()); BOOST_MPL_ASSERT_MSG(0, Unknown_HDF5_data_type, ());
return H5::PredType::NATIVE_DOUBLE; return H5::PredType::NATIVE_DOUBLE;
@ -68,7 +71,7 @@ namespace CosmoTool {
#define HDF5_TYPE(tl, thdf5) \ #define HDF5_TYPE(tl, thdf5) \
template<typename T> struct get_hdf5_data_type<T, typename boost::enable_if<boost::is_same<T, tl> >::type> \ template<typename T> struct get_hdf5_data_type<T, typename boost::enable_if<boost::is_same<T, tl> >::type> \
{ static H5::PredType type() { return H5::PredType::thdf5; }; } { static H5::DataType type() { return H5::PredType::thdf5; }; }
HDF5_TYPE(char , NATIVE_CHAR); HDF5_TYPE(char , NATIVE_CHAR);
HDF5_TYPE(long long , NATIVE_LLONG); HDF5_TYPE(long long , NATIVE_LLONG);
@ -202,6 +205,39 @@ namespace CosmoTool {
hdf5_read_array(fg, data_set_name, data, hdf5_ComplexType<T>::ctype()->type); hdf5_read_array(fg, data_set_name, data, hdf5_ComplexType<T>::ctype()->type);
} }
#define CTOOL_HDF5_NAME(STRUCT) BOOST_PP_CAT(hdf5_,STRUCT)
#define CTOOL_HDF5_INSERT_ELEMENT(r, STRUCT, element) \
{ \
::CosmoTool::get_hdf5_data_type<BOOST_PP_TUPLE_ELEM(2, 0, element)> t; \
position = HOFFSET(STRUCT, BOOST_PP_TUPLE_ELEM(2, 1, element)); \
const char *field_name = BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 1, element)); \
type.insertMember(field_name, position, t.type()); \
}
#define CTOOL_STRUCT_TYPE(STRUCT, TNAME, ATTRIBUTES) \
namespace CosmoTool { \
class TNAME { \
public: \
H5::CompType type; \
\
TNAME() : type(sizeof(STRUCT)) \
{ \
long position; \
BOOST_PP_SEQ_FOR_EACH(CTOOL_HDF5_INSERT_ELEMENT, STRUCT, ATTRIBUTES) \
} \
\
static const TNAME *ctype() \
{ \
static TNAME singleton; \
return &singleton; \
} \
}; \
template<> struct get_hdf5_data_type<STRUCT> { \
static H5::DataType type() { return TNAME::ctype()->type; }; \
}; \
};
}; };
#endif #endif

View File

@ -55,12 +55,20 @@ namespace CosmoTool
typedef octCoordType OctCoords[3]; typedef octCoordType OctCoords[3];
template<class T = void>
struct OctCell struct OctCell
{ {
octPtr numberLeaves; octPtr numberLeaves;
octPtr children[8]; octPtr children[8];
T data;
}; };
template<typename T>
struct OctTree_defaultUpdater {
void operator()(T& d) { }
};
template<typename T_dataUpdater = OctTree_defaultUpdater<void>, class T = void>
class OctTree class OctTree
{ {
public: public:
@ -103,9 +111,10 @@ namespace CosmoTool
protected: protected:
T_dataUpdater updater;
const FCoordinates *particles; const FCoordinates *particles;
octPtr numParticles; octPtr numParticles;
OctCell *cells; OctCell<T> *cells;
float Lbox; float Lbox;
octPtr lastNode; octPtr lastNode;
octPtr numCells; octPtr numCells;
@ -177,4 +186,6 @@ namespace CosmoTool
}; };
#include "octTree.tcc"
#endif #endif

View File

@ -39,8 +39,9 @@ knowledge of the CeCILL license and that you accept its terms.
#include "config.hpp" #include "config.hpp"
#include "octTree.hpp" #include "octTree.hpp"
namespace CosmoTool {
using namespace std; using namespace std;
using namespace CosmoTool;
//#define VERBOSE //#define VERBOSE
@ -59,7 +60,8 @@ static uint32_t mypow(uint32_t i, uint32_t p)
return j*j*i; return j*j*i;
} }
OctTree::OctTree(const FCoordinates *particles, octPtr numParticles, template<typename Updater, typename T>
OctTree<Updater,T>::OctTree(const FCoordinates *particles, octPtr numParticles,
uint32_t maxMeanTreeDepth, uint32_t maxAbsoluteDepth, uint32_t maxMeanTreeDepth, uint32_t maxAbsoluteDepth,
uint32_t threshold) uint32_t threshold)
{ {
@ -94,7 +96,7 @@ OctTree::OctTree(const FCoordinates *particles, octPtr numParticles,
} }
cout << xMin[0] << " " << xMin[1] << " " << xMin[2] << " lNorm=" << lenNorm << endl; cout << xMin[0] << " " << xMin[1] << " " << xMin[2] << " lNorm=" << lenNorm << endl;
cells = new OctCell[numCells]; cells = new OctCell<T>[numCells];
Lbox = (float)(octCoordTypeNorm+1); Lbox = (float)(octCoordTypeNorm+1);
cells[0].numberLeaves = 0; cells[0].numberLeaves = 0;
@ -110,12 +112,14 @@ OctTree::OctTree(const FCoordinates *particles, octPtr numParticles,
//#endif //#endif
} }
OctTree::~OctTree() template<typename Updater, typename T>
OctTree<Updater,T>::~OctTree()
{ {
delete cells; delete cells;
} }
void OctTree::buildTree(uint32_t maxAbsoluteDepth) template<typename Updater, typename T>
void OctTree<Updater,T>::buildTree(uint32_t maxAbsoluteDepth)
{ {
for (octPtr i = 0; i < numParticles; i++) for (octPtr i = 0; i < numParticles; i++)
{ {
@ -129,7 +133,8 @@ void OctTree::buildTree(uint32_t maxAbsoluteDepth)
} }
void OctTree::insertParticle(octPtr node, template<typename Updater, typename T>
void OctTree<Updater,T>::insertParticle(octPtr node,
const OctCoords& icoord, const OctCoords& icoord,
octCoordType halfNodeLength, octCoordType halfNodeLength,
octPtr particleId, octPtr particleId,
@ -208,3 +213,5 @@ void OctTree::insertParticle(octPtr node,
cells[node].children[octPos] = newNode; cells[node].children[octPos] = newNode;
} }
};

44
src/openmp.hpp Normal file
View File

@ -0,0 +1,44 @@
#ifndef __CTOOL_OPENMP_HPP
#define __CTOOL_OPENMP_HPP
#ifdef _OPENMP
#include <omp.h>
#endif
namespace CosmoTool {
static int smp_get_max_threads() {
#ifdef _OPENMP
return omp_get_max_threads();
#else
return 1;
#endif
}
static int smp_get_thread_id() {
#ifdef _OPENMP
return omp_get_thread_num();
#else
return 0;
#endif
}
static int smp_get_num_threads() {
#ifdef _OPENMP
return omp_get_num_threads();
#else
return 1;
#endif
}
static void smp_set_nested(bool n) {
#ifdef _OPENMP
omp_set_nested(n ? 1 : 0);
#endif
}
};
#endif

View File

@ -37,7 +37,7 @@ knowledge of the CeCILL license and that you accept its terms.
#include "config.hpp" #include "config.hpp"
#ifdef NETCDFCPP4 #ifdef NETCDFCPP4
#include <netcdf> #include <netcdf>
using namespace netCDF using namespace netCDF;
#else #else
#include <netcdfcpp.h> #include <netcdfcpp.h>
#endif #endif