2013-03-03 00:42:56 +01:00
|
|
|
/*+
|
2014-05-22 09:38:59 +02:00
|
|
|
This is CosmoTool (./src/loadGadget.cpp) -- Copyright (C) Guilhem Lavaux (2007-2014)
|
2013-03-03 00:42:56 +01:00
|
|
|
|
|
|
|
guilhem.lavaux@gmail.com
|
|
|
|
|
|
|
|
This software is a computer program whose purpose is to provide a toolbox for cosmological
|
|
|
|
data analysis (e.g. filters, generalized Fourier transforms, power spectra, ...)
|
|
|
|
|
|
|
|
This software is governed by the CeCILL license under French law and
|
|
|
|
abiding by the rules of distribution of free software. You can use,
|
|
|
|
modify and/ or redistribute the software under the terms of the CeCILL
|
|
|
|
license as circulated by CEA, CNRS and INRIA at the following URL
|
|
|
|
"http://www.cecill.info".
|
|
|
|
|
|
|
|
As a counterpart to the access to the source code and rights to copy,
|
|
|
|
modify and redistribute granted by the license, users are provided only
|
|
|
|
with a limited warranty and the software's author, the holder of the
|
|
|
|
economic rights, and the successive licensors have only limited
|
|
|
|
liability.
|
|
|
|
|
|
|
|
In this respect, the user's attention is drawn to the risks associated
|
|
|
|
with loading, using, modifying and/or developing or reproducing the
|
|
|
|
software by the user in light of its specific status of free software,
|
|
|
|
that may mean that it is complicated to manipulate, and that also
|
|
|
|
therefore means that it is reserved for developers and experienced
|
|
|
|
professionals having in-depth computer knowledge. Users are therefore
|
|
|
|
encouraged to load and test the software's suitability as regards their
|
|
|
|
requirements in conditions enabling the security of their systems and/or
|
|
|
|
data to be ensured and, more generally, to use and operate it in the
|
|
|
|
same conditions as regards security.
|
|
|
|
|
|
|
|
The fact that you are presently reading this means that you have had
|
|
|
|
knowledge of the CeCILL license and that you accept its terms.
|
|
|
|
+*/
|
2013-03-06 04:39:33 +01:00
|
|
|
|
2011-03-17 19:39:20 +01:00
|
|
|
#include <cmath>
|
2010-09-12 21:09:39 +02:00
|
|
|
#include <iostream>
|
2010-04-23 09:29:10 +02:00
|
|
|
#include <assert.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2015-02-26 10:36:52 +01:00
|
|
|
#include <boost/function.hpp>
|
|
|
|
#include <boost/bind.hpp>
|
2010-04-23 09:29:10 +02:00
|
|
|
#include "load_data.hpp"
|
|
|
|
#include "loadGadget.hpp"
|
|
|
|
#include "fortran.hpp"
|
|
|
|
|
|
|
|
using namespace CosmoTool;
|
2010-09-12 21:09:39 +02:00
|
|
|
using namespace std;
|
2010-04-23 09:29:10 +02:00
|
|
|
|
2012-11-20 22:58:10 +01:00
|
|
|
|
|
|
|
void loadGadgetHeader(UnformattedRead *f, GadgetHeader& h, SimuData *data, int id)
|
2010-04-23 09:29:10 +02:00
|
|
|
{
|
2012-11-20 22:58:10 +01:00
|
|
|
f->beginCheckpoint();
|
2016-02-05 16:53:39 +01:00
|
|
|
for (int i = 0; i < 6; i++)
|
2012-11-20 22:58:10 +01:00
|
|
|
h.npart[i] = f->readInt32();
|
2010-04-23 09:29:10 +02:00
|
|
|
for (int i = 0; i < 6; i++)
|
2012-11-20 22:58:10 +01:00
|
|
|
h.mass[i] = f->readReal64();
|
|
|
|
data->time = h.time = f->readReal64();
|
|
|
|
h.redshift = f->readReal64();
|
|
|
|
h.flag_sfr = f->readInt32();
|
|
|
|
h.flag_feedback = f->readInt32();
|
2010-04-23 09:29:10 +02:00
|
|
|
for (int i = 0; i < 6; i++)
|
2012-11-20 22:58:10 +01:00
|
|
|
h.npartTotal[i] = f->readInt32();
|
|
|
|
h.flag_cooling = f->readInt32();
|
|
|
|
h.num_files = f->readInt32();
|
|
|
|
data->BoxSize = h.BoxSize = f->readReal64();
|
|
|
|
data->Omega_M = h.Omega0 = f->readReal64();
|
|
|
|
data->Omega_Lambda = h.OmegaLambda = f->readReal64();
|
|
|
|
data->Hubble = h.HubbleParam = f->readReal64();
|
2015-02-26 10:36:52 +01:00
|
|
|
(int)f->readInt32(); // stellarage
|
|
|
|
(int)f->readInt32(); // metals
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
|
h.npartTotal[i] |= ((unsigned long)f->readInt32()) << 32;
|
|
|
|
(int)f->readInt32(); // entropy instead of u
|
|
|
|
h.flag_doubleprecision = f->readInt32();
|
|
|
|
|
2012-11-20 22:58:10 +01:00
|
|
|
f->endCheckpoint(true);
|
2010-04-23 09:29:10 +02:00
|
|
|
|
2014-11-28 08:55:07 +01:00
|
|
|
ssize_t NumPart = 0, NumPartTotal = 0;
|
2012-11-20 22:58:10 +01:00
|
|
|
for(int k=0; k<6; k++)
|
|
|
|
{
|
|
|
|
NumPart += h.npart[k];
|
|
|
|
NumPartTotal += (id < 0) ? h.npart[k] : h.npartTotal[k];
|
2010-04-23 09:29:10 +02:00
|
|
|
}
|
2012-11-20 22:58:10 +01:00
|
|
|
data->NumPart = NumPart;
|
|
|
|
data->TotalNumPart = NumPartTotal;
|
2010-04-23 09:29:10 +02:00
|
|
|
}
|
2010-04-27 13:38:00 +02:00
|
|
|
|
2015-02-26 10:36:52 +01:00
|
|
|
template<typename T>
|
|
|
|
T myRead64(UnformattedRead *f) { return f->readReal64(); }
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
T myRead32(UnformattedRead *f) { return f->readReal32(); }
|
|
|
|
|
2016-02-05 16:53:39 +01:00
|
|
|
template<typename T>
|
|
|
|
T myReadI64(UnformattedRead *f) { return f->readInt64(); }
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
T myReadI32(UnformattedRead *f) { return f->readInt32(); }
|
|
|
|
|
|
|
|
struct BlockInfo {
|
|
|
|
int64_t position, size;
|
|
|
|
};
|
|
|
|
|
2012-11-20 22:58:10 +01:00
|
|
|
SimuData *CosmoTool::loadGadgetMulti(const char *fname, int id,
|
|
|
|
int loadflags, int GadgetFormat,
|
|
|
|
SimuFilter filter)
|
2010-04-27 13:38:00 +02:00
|
|
|
{
|
|
|
|
SimuData *data;
|
|
|
|
int p, n;
|
2010-04-27 14:08:46 +02:00
|
|
|
UnformattedRead *f;
|
2010-04-27 13:38:00 +02:00
|
|
|
GadgetHeader h;
|
2011-03-17 19:39:20 +01:00
|
|
|
float velmul;
|
2015-02-26 10:36:52 +01:00
|
|
|
boost::function0<double> readToDouble;
|
|
|
|
boost::function0<float> readToSingle;
|
2016-02-05 16:53:39 +01:00
|
|
|
boost::function0<int64_t> readID;
|
2015-02-26 10:36:52 +01:00
|
|
|
long float_size;
|
2010-04-27 13:38:00 +02:00
|
|
|
|
2016-01-26 22:59:35 +01:00
|
|
|
if (GadgetFormat > 2) {
|
|
|
|
cerr << "Unknown gadget format" << endl;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-04-27 14:08:46 +02:00
|
|
|
if (id >= 0) {
|
2010-08-03 17:24:40 +02:00
|
|
|
int k = snprintf(0, 0, "%s.%d", fname, id)+1;
|
|
|
|
char *out_fname = new char[k];
|
|
|
|
snprintf(out_fname, k, "%s.%d", fname, id);
|
2011-06-06 15:43:38 +02:00
|
|
|
|
2010-04-27 14:08:46 +02:00
|
|
|
f = new UnformattedRead(out_fname);
|
|
|
|
if (f == 0)
|
|
|
|
return 0;
|
|
|
|
|
2014-05-30 11:39:13 +02:00
|
|
|
delete[] out_fname;
|
2010-04-27 14:08:46 +02:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
f = new UnformattedRead(fname);
|
|
|
|
if (f == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-02-05 16:53:39 +01:00
|
|
|
typedef std::map<std::string, BlockInfo> BlockMap;
|
2016-01-26 22:59:35 +01:00
|
|
|
BlockMap blockTable;
|
|
|
|
|
|
|
|
if (GadgetFormat == 2) {
|
|
|
|
int64_t startBlock = 0;
|
|
|
|
char block[5];
|
|
|
|
int32_t blocksize;
|
|
|
|
|
|
|
|
try {
|
|
|
|
while (true) {
|
|
|
|
f->beginCheckpoint();
|
|
|
|
f->readOrderedBuffer(block, 4);
|
|
|
|
block[4] = 0;
|
|
|
|
blocksize = f->readInt32();
|
|
|
|
f->endCheckpoint();
|
2016-02-05 16:53:39 +01:00
|
|
|
blockTable[block].position = f->position();
|
|
|
|
blockTable[block].size = blocksize;
|
2016-01-26 22:59:35 +01:00
|
|
|
f->skip(blocksize);
|
|
|
|
}
|
|
|
|
} catch (EndOfFileException&) {}
|
|
|
|
|
|
|
|
f->seek(startBlock);
|
|
|
|
}
|
|
|
|
|
2010-04-27 13:38:00 +02:00
|
|
|
data = new SimuData;
|
2010-04-27 14:08:46 +02:00
|
|
|
if (data == 0) {
|
|
|
|
delete f;
|
|
|
|
return 0;
|
|
|
|
}
|
2010-04-27 13:38:00 +02:00
|
|
|
|
2014-11-28 08:55:07 +01:00
|
|
|
ssize_t NumPart = 0, NumPartTotal = 0;
|
2016-02-05 16:53:39 +01:00
|
|
|
#define ENSURE2(name,out_sz) { \
|
2016-01-26 22:59:35 +01:00
|
|
|
if (GadgetFormat == 2) { \
|
|
|
|
BlockMap::iterator iter = blockTable.find(name); \
|
2016-02-05 16:53:39 +01:00
|
|
|
int64_t sz; \
|
2016-01-26 22:59:35 +01:00
|
|
|
if (iter == blockTable.end()) { \
|
|
|
|
std::cerr << "GADGET2: Cannot find block named '" << name << "'" << endl; \
|
|
|
|
if (data) delete data; \
|
|
|
|
delete f; \
|
|
|
|
return 0; \
|
|
|
|
} \
|
2016-02-05 16:53:39 +01:00
|
|
|
f->seek(iter->second.position); \
|
|
|
|
sz = iter->second.size; \
|
|
|
|
out_sz = sz;\
|
2016-01-26 22:59:35 +01:00
|
|
|
} \
|
|
|
|
}
|
2016-02-05 16:53:39 +01:00
|
|
|
#define ENSURE(name) ENSURE2(name,sz);
|
2012-11-20 22:58:10 +01:00
|
|
|
|
2010-09-12 21:09:39 +02:00
|
|
|
try
|
|
|
|
{
|
2016-01-26 22:59:35 +01:00
|
|
|
ENSURE("HEAD");
|
2012-11-20 22:58:10 +01:00
|
|
|
loadGadgetHeader(f, h, data, id);
|
|
|
|
|
2016-01-26 22:59:35 +01:00
|
|
|
velmul = sqrt(h.time);
|
2015-02-26 10:36:52 +01:00
|
|
|
|
|
|
|
if (h.flag_doubleprecision) {
|
2015-09-29 16:34:46 +02:00
|
|
|
//cout << "Gadget format with double precision" << endl;
|
2015-02-26 10:36:52 +01:00
|
|
|
readToDouble = boost::bind(myRead64<double>, f);
|
|
|
|
readToSingle = boost::bind(myRead64<float>, f);
|
|
|
|
float_size = sizeof(double);
|
|
|
|
} else {
|
2015-09-29 16:34:46 +02:00
|
|
|
//cout << "Gadget format with single precision" << endl;
|
2015-02-26 10:36:52 +01:00
|
|
|
readToDouble = boost::bind(myRead32<double>, f);
|
|
|
|
readToSingle = boost::bind(myRead32<float>, f);
|
|
|
|
float_size = sizeof(float);
|
2011-03-17 19:39:20 +01:00
|
|
|
}
|
2012-11-20 22:58:10 +01:00
|
|
|
NumPart = data->NumPart;
|
|
|
|
NumPartTotal = data->TotalNumPart;
|
2010-09-12 21:09:39 +02:00
|
|
|
}
|
|
|
|
catch (const InvalidUnformattedAccess& e)
|
|
|
|
{
|
|
|
|
cerr << "Invalid format while reading header" << endl;
|
|
|
|
delete data;
|
|
|
|
delete f;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-01-26 22:59:35 +01:00
|
|
|
|
2010-09-12 21:09:39 +02:00
|
|
|
if (loadflags & NEED_TYPE)
|
2010-04-27 14:08:46 +02:00
|
|
|
{
|
2010-09-12 21:09:39 +02:00
|
|
|
int p = 0;
|
2016-01-26 22:59:35 +01:00
|
|
|
|
2010-09-12 21:09:39 +02:00
|
|
|
data->type = new int[data->NumPart];
|
|
|
|
for (int k = 0; k < 6; k++)
|
2015-02-26 10:36:52 +01:00
|
|
|
for (int n = 0; n < h.npart[k]; n++,p++)
|
|
|
|
data->type[p] = k;
|
2010-04-27 14:08:46 +02:00
|
|
|
}
|
2010-04-27 13:38:00 +02:00
|
|
|
|
|
|
|
if (loadflags & NEED_POSITION) {
|
|
|
|
|
2010-04-27 14:08:46 +02:00
|
|
|
for (int i = 0; i < 3; i++) {
|
2015-02-26 10:36:52 +01:00
|
|
|
data->Pos[i] = new float[data->NumPart];
|
|
|
|
if (data->Pos[i] == 0) {
|
|
|
|
delete data;
|
|
|
|
return 0;
|
2010-04-27 14:08:46 +02:00
|
|
|
}
|
2015-02-26 10:36:52 +01:00
|
|
|
}
|
2010-09-12 21:09:39 +02:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2016-01-26 22:59:35 +01:00
|
|
|
ENSURE("POS ");
|
2010-09-12 21:09:39 +02:00
|
|
|
f->beginCheckpoint();
|
2015-06-03 10:31:09 +02:00
|
|
|
if (f->getBlockSize() != NumPart*float_size*3) {
|
|
|
|
// Check that single would work
|
|
|
|
if (f->getBlockSize() == NumPart*sizeof(float)*3) {
|
|
|
|
// Change to single
|
|
|
|
cout << "Change back to single. Buggy header." << endl;
|
|
|
|
readToDouble = boost::bind(myRead32<double>, f);
|
|
|
|
readToSingle = boost::bind(myRead32<float>, f);
|
|
|
|
float_size = sizeof(float);
|
|
|
|
}
|
|
|
|
}
|
2010-09-12 21:09:39 +02:00
|
|
|
for(int k = 0, p = 0; k < 6; k++) {
|
|
|
|
for(int n = 0; n < h.npart[k]; n++) {
|
2015-06-03 10:31:09 +02:00
|
|
|
// if ((n%1000000)==0) cout << n << endl;
|
2015-02-26 10:36:52 +01:00
|
|
|
data->Pos[0][p] = readToSingle();
|
|
|
|
data->Pos[1][p] = readToSingle();
|
|
|
|
data->Pos[2][p] = readToSingle();
|
2010-09-12 21:09:39 +02:00
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f->endCheckpoint();
|
|
|
|
}
|
|
|
|
catch (const InvalidUnformattedAccess& e)
|
|
|
|
{
|
2015-02-26 10:36:52 +01:00
|
|
|
cerr << "Invalid format while reading positions" << endl;
|
|
|
|
delete f;
|
|
|
|
delete data;
|
|
|
|
return 0;
|
2010-04-27 13:38:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
2015-02-26 10:36:52 +01:00
|
|
|
long float_size = (h.flag_doubleprecision) ? sizeof(double) : sizeof(float);
|
2010-04-27 13:38:00 +02:00
|
|
|
// Skip positions
|
2015-02-26 10:36:52 +01:00
|
|
|
f->skip(NumPart * 3 * float_size + 2*4);
|
2010-04-27 13:38:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (loadflags & NEED_VELOCITY) {
|
|
|
|
for (int i = 0; i < 3; i++)
|
2010-04-27 14:08:46 +02:00
|
|
|
{
|
|
|
|
data->Vel[i] = new float[data->NumPart];
|
|
|
|
if (data->Vel[i] == 0)
|
|
|
|
{
|
2010-09-12 21:09:39 +02:00
|
|
|
delete f;
|
2010-04-27 14:08:46 +02:00
|
|
|
delete data;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2010-09-12 21:09:39 +02:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2016-01-26 22:59:35 +01:00
|
|
|
ENSURE("VEL ");
|
2010-09-12 21:09:39 +02:00
|
|
|
f->beginCheckpoint();
|
|
|
|
for(int k = 0, p = 0; k < 6; k++) {
|
|
|
|
for(int n = 0; n < h.npart[k]; n++) {
|
2011-03-17 19:39:20 +01:00
|
|
|
// THIS IS GADGET 1
|
2015-06-03 10:31:09 +02:00
|
|
|
// if ((n%1000000)==0) cout << n << endl;
|
2015-02-26 10:36:52 +01:00
|
|
|
data->Vel[0][p] = readToSingle()*velmul;
|
|
|
|
data->Vel[1][p] = readToSingle()*velmul;
|
|
|
|
data->Vel[2][p] = readToSingle()*velmul;
|
2010-09-12 21:09:39 +02:00
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f->endCheckpoint();
|
|
|
|
}
|
|
|
|
catch (const InvalidUnformattedAccess& e)
|
|
|
|
{
|
|
|
|
cerr << "Invalid format while reading velocities" << endl;
|
|
|
|
delete f;
|
|
|
|
delete data;
|
|
|
|
return 0;
|
2010-04-27 13:38:00 +02:00
|
|
|
}
|
|
|
|
|
2011-03-17 19:39:20 +01:00
|
|
|
// THE VELOCITIES ARE IN PHYSICAL COORDINATES
|
|
|
|
/// // TODO: FIX THE UNITS OF THESE FUNKY VELOCITIES !!!
|
2010-04-27 13:38:00 +02:00
|
|
|
} else {
|
|
|
|
// Skip velocities
|
2015-02-26 10:36:52 +01:00
|
|
|
f->skip(NumPart*3*float_size+2*4);
|
2010-04-27 13:38:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Skip ids
|
|
|
|
if (loadflags & NEED_GADGET_ID) {
|
2010-09-12 21:09:39 +02:00
|
|
|
try
|
2010-04-27 13:38:00 +02:00
|
|
|
{
|
2016-02-05 16:53:39 +01:00
|
|
|
int64_t idSize;
|
|
|
|
ENSURE2("ID ", idSize);
|
|
|
|
|
|
|
|
if (idSize / data->NumPart == 8) {
|
|
|
|
readID = boost::bind(myReadI64<int64_t>, f);
|
|
|
|
} else
|
|
|
|
if (idSize / data->NumPart == 4) {
|
|
|
|
readID = boost::bind(myReadI32<int64_t>, f);
|
|
|
|
} else {
|
|
|
|
throw InvalidUnformattedAccess();
|
|
|
|
}
|
|
|
|
|
2010-09-12 21:09:39 +02:00
|
|
|
f->beginCheckpoint();
|
2016-02-05 17:27:39 +01:00
|
|
|
data->Id = new int64_t[data->NumPart];
|
2010-09-12 21:09:39 +02:00
|
|
|
if (data->Id == 0)
|
2010-04-27 13:38:00 +02:00
|
|
|
{
|
2010-09-12 21:09:39 +02:00
|
|
|
delete f;
|
|
|
|
delete data;
|
|
|
|
return 0;
|
2010-04-27 13:38:00 +02:00
|
|
|
}
|
2010-09-12 21:09:39 +02:00
|
|
|
|
|
|
|
for(int k = 0, p = 0; k < 6; k++)
|
|
|
|
{
|
|
|
|
for(int n = 0; n < h.npart[k]; n++)
|
|
|
|
{
|
2016-02-05 16:53:39 +01:00
|
|
|
data->Id[p] = readID();
|
2010-09-12 21:09:39 +02:00
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f->endCheckpoint();
|
|
|
|
}
|
|
|
|
catch (const InvalidUnformattedAccess& e)
|
|
|
|
{
|
2012-11-10 14:59:10 +01:00
|
|
|
cerr << "Invalid unformatted access while reading ID" << endl;
|
2010-09-12 21:09:39 +02:00
|
|
|
delete f;
|
|
|
|
delete data;
|
|
|
|
return 0;
|
2010-04-27 13:38:00 +02:00
|
|
|
}
|
|
|
|
} else {
|
2010-04-27 14:08:46 +02:00
|
|
|
f->skip(2*4);
|
2010-04-27 13:38:00 +02:00
|
|
|
for (int k = 0; k < 6; k++)
|
2010-04-27 14:08:46 +02:00
|
|
|
f->skip(h.npart[k]*4);
|
2010-04-27 13:38:00 +02:00
|
|
|
}
|
|
|
|
|
2014-07-05 22:05:04 +02:00
|
|
|
if (loadflags & NEED_MASS) {
|
2014-07-07 17:35:56 +02:00
|
|
|
bool do_load = false;
|
|
|
|
|
|
|
|
for (int k = 0; k < 6; k++)
|
|
|
|
{
|
|
|
|
do_load = do_load || ((h.mass[k] == 0)&&(h.npart[k]>0));
|
|
|
|
}
|
|
|
|
|
2014-07-05 22:05:04 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
long l = 0;
|
2016-01-26 22:59:35 +01:00
|
|
|
if (do_load) {
|
|
|
|
ENSURE("MASS");
|
2014-07-07 17:35:56 +02:00
|
|
|
f->beginCheckpoint();
|
2016-01-26 22:59:35 +01:00
|
|
|
}
|
2014-07-05 22:05:04 +02:00
|
|
|
data->Mass = new float[NumPart];
|
|
|
|
for (int k = 0; k < 6; k++)
|
|
|
|
{
|
|
|
|
if (h.mass[k] == 0) {
|
|
|
|
for(int n = 0; n < h.npart[k]; n++)
|
|
|
|
{
|
2015-06-03 10:31:09 +02:00
|
|
|
// if ((n%1000000)==0) cout << n << endl;
|
2015-02-26 10:36:52 +01:00
|
|
|
data->Mass[l++] = readToSingle();
|
2014-07-05 22:05:04 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for(int n = 0; n < h.npart[k]; n++)
|
|
|
|
{
|
2015-06-03 10:31:09 +02:00
|
|
|
if ((n%1000000)==0) cout << n << endl;
|
2014-07-05 22:05:04 +02:00
|
|
|
data->Mass[l++] = h.mass[k];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-07-07 17:35:56 +02:00
|
|
|
if (do_load)
|
|
|
|
f->endCheckpoint();
|
2014-07-05 22:05:04 +02:00
|
|
|
}
|
|
|
|
catch (const InvalidUnformattedAccess& e)
|
|
|
|
{
|
|
|
|
cerr << "Invalid unformatted access while reading ID" << endl;
|
|
|
|
delete f;
|
|
|
|
delete data;
|
|
|
|
return 0;
|
|
|
|
}
|
2014-07-07 17:35:56 +02:00
|
|
|
catch (const EndOfFileException& e)
|
|
|
|
{
|
|
|
|
for (int k = 0; k < 6; k++)
|
|
|
|
cerr << "mass[" << k << "] = " << h.mass[k] << endl;
|
|
|
|
}
|
2014-07-05 22:05:04 +02:00
|
|
|
} else {
|
|
|
|
f->skip(2*4);
|
|
|
|
for (int k = 0; k < 6; k++)
|
|
|
|
if (h.mass[k] == 0)
|
|
|
|
f->skip(h.npart[k]*4);
|
|
|
|
}
|
|
|
|
|
2010-04-27 14:08:46 +02:00
|
|
|
delete f;
|
|
|
|
|
2010-04-27 13:38:00 +02:00
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2016-01-26 22:59:35 +01:00
|
|
|
#undef ENSURE
|
2010-04-27 13:38:00 +02:00
|
|
|
|
2012-03-30 17:47:48 +02:00
|
|
|
|
2013-03-07 16:39:10 +01:00
|
|
|
void CosmoTool::writeGadget(const std::string& fname, SimuData *data, int GadgetFormat)
|
2012-03-30 17:47:48 +02:00
|
|
|
{
|
|
|
|
UnformattedWrite *f;
|
2013-03-07 16:39:10 +01:00
|
|
|
int npart[6], npartTotal[6];
|
2012-03-30 17:47:48 +02:00
|
|
|
float mass[6];
|
|
|
|
|
2014-05-31 08:43:22 +02:00
|
|
|
if (data->Pos[0] == 0 || data->Vel[0] == 0 || data->Id == 0) {
|
|
|
|
cerr << "Invalid simulation data array" << endl;
|
2012-03-30 17:47:48 +02:00
|
|
|
return;
|
2014-05-31 08:43:22 +02:00
|
|
|
}
|
2012-03-30 17:47:48 +02:00
|
|
|
|
|
|
|
f = new UnformattedWrite(fname);
|
2014-05-31 08:43:22 +02:00
|
|
|
if (f == 0) {
|
|
|
|
cerr << "Cannot create file" << endl;
|
2012-03-30 17:47:48 +02:00
|
|
|
return;
|
2014-05-31 08:43:22 +02:00
|
|
|
}
|
2012-03-30 17:47:48 +02:00
|
|
|
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
|
{
|
2013-03-07 16:39:10 +01:00
|
|
|
npart[i] = npartTotal[i] = 0;
|
2012-03-30 17:47:48 +02:00
|
|
|
mass[i] = 0;
|
|
|
|
}
|
2012-04-02 00:49:19 +02:00
|
|
|
mass[1] = 1.0;
|
2012-03-30 17:47:48 +02:00
|
|
|
npart[1] = data->NumPart;
|
2013-03-07 16:39:10 +01:00
|
|
|
npartTotal[1] = data->TotalNumPart;
|
2012-03-30 17:47:48 +02:00
|
|
|
|
|
|
|
f->beginCheckpoint();
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
|
f->writeInt32(npart[i]);
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
|
f->writeReal64(mass[i]);
|
|
|
|
|
|
|
|
f->writeReal64(data->time);
|
|
|
|
f->writeReal64(1/data->time-1);
|
|
|
|
f->writeInt32(0);
|
|
|
|
f->writeInt32(0);
|
|
|
|
|
|
|
|
for (int i = 0; i < 6; i++)
|
2013-03-07 16:39:10 +01:00
|
|
|
f->writeInt32(npartTotal[i]);
|
2012-03-30 17:47:48 +02:00
|
|
|
f->writeInt32(0);
|
|
|
|
f->writeInt32(1);
|
|
|
|
f->writeReal64(data->BoxSize);
|
|
|
|
f->writeReal64(data->Omega_M);
|
|
|
|
f->writeReal64(data->Omega_Lambda);
|
|
|
|
f->writeReal64(data->Hubble);
|
2012-04-02 00:49:19 +02:00
|
|
|
char buf[100] = { 0, };
|
|
|
|
f->writeOrderedBuffer(buf, 96);
|
2012-03-30 17:47:48 +02:00
|
|
|
f->endCheckpoint();
|
|
|
|
|
|
|
|
f->beginCheckpoint();
|
|
|
|
for(int n = 0; n < data->NumPart; n++) {
|
|
|
|
for (int k = 0; k < 3; k++)
|
|
|
|
f->writeReal32(data->Pos[k][n]);
|
|
|
|
}
|
|
|
|
f->endCheckpoint();
|
|
|
|
|
|
|
|
float velmul = 1.0;
|
2016-01-26 22:59:35 +01:00
|
|
|
velmul = sqrt(data->time);
|
2012-03-30 17:47:48 +02:00
|
|
|
|
|
|
|
f->beginCheckpoint();
|
|
|
|
for(int n = 0; n < data->NumPart; n++) {
|
|
|
|
for (int k = 0; k < 3; k++)
|
|
|
|
f->writeReal32(data->Vel[k][n]/velmul);
|
|
|
|
}
|
|
|
|
f->endCheckpoint();
|
|
|
|
|
|
|
|
f->beginCheckpoint();
|
|
|
|
for(int n = 0; n < data->NumPart; n++)
|
|
|
|
{
|
2012-04-02 00:49:19 +02:00
|
|
|
f->writeInt32(data->Id[n]);
|
2012-03-30 17:47:48 +02:00
|
|
|
}
|
|
|
|
f->endCheckpoint();
|
2012-04-02 00:49:19 +02:00
|
|
|
delete f;
|
2012-03-30 17:47:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|