mirror of
https://bitbucket.org/cosmicvoids/vide_public.git
synced 2025-07-04 15:21:11 +00:00
281 lines
7.2 KiB
C++
281 lines
7.2 KiB
C++
/*+
|
|
VIDE -- Void IDentification and Examination -- ./c_tools/mock/loaders/sdf_loader.cpp
|
|
Copyright (C) 2010-2014 Guilhem Lavaux
|
|
Copyright (C) 2011-2014 P. M. Sutter
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
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 General Public License along
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+*/
|
|
|
|
|
|
|
|
#include <iostream>
|
|
#include <boost/format.hpp>
|
|
#include <vector>
|
|
#include <cassert>
|
|
#include <string>
|
|
#include "sdfloader_internal.hpp"
|
|
#include "simulation_loader.hpp"
|
|
#include <libsdf/mpmy.h>
|
|
#include <libsdf/SDF.h>
|
|
#include <libsdf/error.h>
|
|
#include <libsdf/cosmo.h>
|
|
|
|
using boost::format;
|
|
|
|
using namespace std;
|
|
using namespace CosmoTool;
|
|
|
|
class SDFLoader: public SimulationLoader
|
|
{
|
|
private:
|
|
int load_flags;
|
|
bool onefile;
|
|
int _num_files;
|
|
double unitMpc;
|
|
SimuData *sdf_header;
|
|
SDF *sdfp;
|
|
SimulationPreprocessor *preproc;
|
|
int num_splitting;
|
|
public:
|
|
SDFLoader(SDF *sdf_file, SimuData *header, int flags, int num_splitting,
|
|
SimulationPreprocessor *p)
|
|
: sdfp(sdf_file), load_flags(flags),
|
|
sdf_header(header), preproc(p)
|
|
{
|
|
this->num_splitting = num_splitting;
|
|
}
|
|
|
|
~SDFLoader()
|
|
{
|
|
delete sdf_header;
|
|
}
|
|
|
|
SimuData *getHeader() {
|
|
return sdf_header;
|
|
}
|
|
|
|
int num_files() {
|
|
return num_splitting;
|
|
}
|
|
|
|
int64_t getStart(int id)
|
|
{
|
|
return sdf_header->TotalNumPart * int64_t(id) / num_splitting;
|
|
}
|
|
|
|
int64_t getNumberInSplit(int id)
|
|
{
|
|
return getStart(id+1)-getStart(id);
|
|
}
|
|
|
|
void rescaleParticles(SimuData *d,
|
|
double rescale_position,
|
|
double rescale_velocity)
|
|
{
|
|
#define INFINITY std::numeric_limits<float>::max()
|
|
float shift = 0.5*d->BoxSize;
|
|
rescale_position /= d->time;
|
|
float min_pos[3] = {INFINITY,INFINITY, INFINITY}, max_pos[3] = {-INFINITY,-INFINITY,-INFINITY};
|
|
|
|
if (d->Pos[0] != 0)
|
|
{
|
|
for (int k = 0; k < 3; k++)
|
|
{
|
|
for (int64_t i = 0; i < d->NumPart; i++)
|
|
{
|
|
d->Pos[k][i] = (d->Pos[k][i]*rescale_position + shift);
|
|
min_pos[k] = std::min(min_pos[k], d->Pos[k][i]);
|
|
max_pos[k] = std::max(max_pos[k], d->Pos[k][i]);
|
|
}
|
|
cout << boost::format("min[%d] = %g, max[%d] = %g") % k % min_pos[k] % k %max_pos[k] << endl;
|
|
}
|
|
}
|
|
if (d->Vel[0] != 0)
|
|
{
|
|
for (int k = 0; k < 3; k++)
|
|
{
|
|
for (int64_t i = 0; i < d->NumPart; i++)
|
|
{
|
|
d->Vel[k][i] *= rescale_velocity;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void enforceBoxSize(SimuData *d)
|
|
{
|
|
for (int k = 0; k < 3; k++)
|
|
{
|
|
for (int64_t i = 0; i < d->NumPart; i++)
|
|
{
|
|
while (d->Pos[k][i]<0)
|
|
d->Pos[k][i] += d->BoxSize;
|
|
while (d->Pos[k][i]>=d->BoxSize)
|
|
d->Pos[k][i] -= d->BoxSize;
|
|
}
|
|
}
|
|
}
|
|
|
|
SimuData *loadFile(int id) {
|
|
SimuData *d;
|
|
int64_t starts[7];
|
|
int nobjs[7];
|
|
int strides[7];
|
|
void *addrs[7];
|
|
const char *names[7];
|
|
int ret;
|
|
|
|
if (id >= num_splitting)
|
|
return 0;
|
|
|
|
d = new SimuData;
|
|
d->BoxSize = sdf_header->BoxSize;
|
|
d->time = sdf_header->time;
|
|
d->Hubble = sdf_header->Hubble;
|
|
d->Omega_M = sdf_header->Omega_M;
|
|
d->Omega_Lambda = sdf_header->Omega_Lambda;
|
|
|
|
d->NumPart = getNumberInSplit(id);
|
|
|
|
int64_t numPartToLoad = getNumberInSplit(id);
|
|
int64_t start = getStart(id);
|
|
int k = 0;
|
|
#define SETUP_READ(name, vec) \
|
|
names[k] = name, starts[k] = start, nobjs[k] = numPartToLoad, strides[k] = sizeof(vec[0]), addrs[k] = vec, k++;
|
|
|
|
if (load_flags & NEED_POSITION)
|
|
{
|
|
const char *name_template[3] = { "x", "y", "z" };
|
|
for (int q = 0; q < 3; q++)
|
|
{
|
|
d->Pos[q] = new float[numPartToLoad];
|
|
SETUP_READ(name_template[q], d->Pos[q]);
|
|
}
|
|
}
|
|
if (load_flags & NEED_VELOCITY)
|
|
{
|
|
const char *name_template[3] = { "vx", "vy", "vz" };
|
|
for (int q = 0; q < 3; q++)
|
|
{
|
|
d->Vel[q] = new float[numPartToLoad];
|
|
SETUP_READ(name_template[q], d->Vel[q]);
|
|
}
|
|
}
|
|
if (load_flags & NEED_GADGET_ID)
|
|
{
|
|
d->Id = new long[numPartToLoad];
|
|
SETUP_READ("ident", d->Id);
|
|
}
|
|
#undef SETUP_READ
|
|
|
|
ret = SDFseekrdvecsarr(sdfp, k, (char**)names, starts, nobjs, addrs, strides);
|
|
if (ret != 0)
|
|
{
|
|
cerr << format("Splitting %d/%d, SDF read failure: %s") % id % num_splitting % SDFerrstring << endl;
|
|
abort();
|
|
}
|
|
|
|
if (load_flags & (NEED_POSITION | NEED_VELOCITY))
|
|
rescaleParticles(d, d->Hubble*1e-5, one_kpc/one_Gyr);
|
|
|
|
enforceBoxSize(d);
|
|
applyTransformations(d);
|
|
basicPreprocessing(d, preproc);
|
|
|
|
return d;
|
|
}
|
|
};
|
|
|
|
SimulationLoader *sdfLoader(const std::string& snapshot, int flags,
|
|
int num_splitting,
|
|
SimulationPreprocessor *p)
|
|
{
|
|
SDF *sdfp;
|
|
int fileversion;
|
|
SimuData *hdr;
|
|
int64_t gnobj;
|
|
|
|
sdfp = SDFopen(0, snapshot.c_str());
|
|
if (sdfp == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
cout << "Loading SDF with artificial splitting " << num_splitting << endl;
|
|
hdr = new SimuData;
|
|
|
|
SDFgetintOrDefault(sdfp, "version", &fileversion, 1);
|
|
double h0;
|
|
if (fileversion == 1)
|
|
{
|
|
SDFgetfloatOrDie(sdfp, "Omega0", &hdr->Omega_M);
|
|
SDFgetfloatOrDie(sdfp, "Lambda_prime", &hdr->Omega_Lambda);
|
|
SDFgetfloatOrDie(sdfp, "H0", &hdr->Hubble);
|
|
hdr->Hubble *= 1000.*(one_kpc/one_Gyr);
|
|
h0 = hdr->Hubble / 100.;
|
|
}
|
|
else
|
|
{
|
|
float Or, Of;
|
|
SDFgetfloatOrDie(sdfp, "Omega0_m", &hdr->Omega_M);
|
|
SDFgetfloatOrDie(sdfp, "Omega0_lambda", &hdr->Omega_Lambda);
|
|
SDFgetfloatOrDie(sdfp, "Omega0_r", &Or);
|
|
SDFgetfloatOrDie(sdfp, "Omega0_fld", &Of);
|
|
|
|
hdr->Omega_M += Or;
|
|
hdr->Omega_Lambda += Of;
|
|
SDFgetfloatOrDie(sdfp, "h_100", &hdr->Hubble);
|
|
hdr->Hubble *= 100.;
|
|
h0 = hdr->Hubble / 100.;
|
|
}
|
|
|
|
if (SDFhasname("R0", sdfp))
|
|
{
|
|
double R0;
|
|
|
|
SDFgetdoubleOrDie(sdfp, "R0", &R0);
|
|
hdr->BoxSize = 2.0*0.001*R0*h0;
|
|
}
|
|
|
|
if (SDFhasname("Rx", sdfp))
|
|
{
|
|
double R0;
|
|
|
|
SDFgetdoubleOrDie(sdfp, "Rx", &R0);
|
|
hdr->BoxSize = 2.0*0.001*R0*h0;
|
|
}
|
|
|
|
if (SDFhasname("redshift", sdfp))
|
|
{
|
|
double redshift;
|
|
|
|
SDFgetdoubleOrDie(sdfp, "redshift", &redshift);
|
|
hdr->time = 1/(1+redshift);
|
|
}
|
|
|
|
if (SDFgetint64(sdfp, "npart", &gnobj))
|
|
{
|
|
gnobj = SDFnrecs("x", sdfp);
|
|
cerr << format("[Warning] No 'npart' found in SDF file '%s', guessing npart=%ld from SDFnrecs") % snapshot % gnobj << endl;
|
|
}
|
|
hdr->NumPart = hdr->TotalNumPart = gnobj;
|
|
|
|
return new SDFLoader(sdfp, hdr, flags, num_splitting, p);
|
|
}
|
|
|
|
|
|
void sdfLoaderInit(int& argc, char **& argv)
|
|
{
|
|
MPMY_Init(&argc, &argv);
|
|
}
|