2010-07-02 20:49:30 +02:00
|
|
|
/*
|
|
|
|
|
|
|
|
output_gadget2.cc - This file is part of MUSIC -
|
|
|
|
a code to generate multi-scale initial conditions
|
|
|
|
for cosmological simulations
|
|
|
|
|
|
|
|
Copyright (C) 2010 Oliver Hahn
|
|
|
|
|
|
|
|
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, 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 General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <fstream>
|
2010-10-26 20:37:31 +02:00
|
|
|
#include "log.hh"
|
2010-07-02 20:49:30 +02:00
|
|
|
#include "output.hh"
|
|
|
|
|
|
|
|
template< typename T_store=float >
|
|
|
|
class gadget2_output_plugin : public output_plugin
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
|
|
|
|
std::ofstream ofs_;
|
|
|
|
bool bmultimass_;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct io_header
|
|
|
|
{
|
|
|
|
int npart[6];
|
|
|
|
double mass[6];
|
|
|
|
double time;
|
|
|
|
double redshift;
|
|
|
|
int flag_sfr;
|
|
|
|
int flag_feedback;
|
|
|
|
unsigned int npartTotal[6];
|
|
|
|
int flag_cooling;
|
|
|
|
int num_files;
|
|
|
|
double BoxSize;
|
|
|
|
double Omega0;
|
|
|
|
double OmegaLambda;
|
|
|
|
double HubbleParam;
|
|
|
|
int flag_stellarage;
|
|
|
|
int flag_metals;
|
|
|
|
unsigned int npartTotalHighWord[6];
|
|
|
|
int flag_entropy_instead_u;
|
|
|
|
char fill[60];
|
|
|
|
}header;
|
|
|
|
|
|
|
|
|
|
|
|
header header_;
|
|
|
|
|
|
|
|
std::string fname;
|
|
|
|
|
|
|
|
enum iofields {
|
|
|
|
id_dm_mass, id_dm_vel, id_dm_pos, id_gas_vel, id_gas_rho, id_gas_temp
|
|
|
|
};
|
|
|
|
|
|
|
|
unsigned block_buf_size_;
|
2010-10-26 20:37:31 +02:00
|
|
|
unsigned long long npartmax_;
|
|
|
|
unsigned nfiles_;
|
|
|
|
|
2010-07-02 20:49:30 +02:00
|
|
|
//bool bbndparticles_;
|
|
|
|
bool bmorethan2bnd_;
|
2010-11-11 07:56:46 +01:00
|
|
|
bool kpcunits_;
|
2010-07-02 20:49:30 +02:00
|
|
|
|
|
|
|
void assemble_gadget_file( void )
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
//............................................................................
|
|
|
|
//... copy from the temporary files, interleave the data and save ............
|
|
|
|
|
|
|
|
char fnx[256],fny[256],fnz[256],fnvx[256],fnvy[256],fnvz[256],fnm[256];
|
|
|
|
|
|
|
|
sprintf( fnx, "___ic_temp_%05d.bin", 100*id_dm_pos+0 );
|
|
|
|
sprintf( fny, "___ic_temp_%05d.bin", 100*id_dm_pos+1 );
|
|
|
|
sprintf( fnz, "___ic_temp_%05d.bin", 100*id_dm_pos+2 );
|
|
|
|
sprintf( fnvx, "___ic_temp_%05d.bin", 100*id_dm_vel+0 );
|
|
|
|
sprintf( fnvy, "___ic_temp_%05d.bin", 100*id_dm_vel+1 );
|
|
|
|
sprintf( fnvz, "___ic_temp_%05d.bin", 100*id_dm_vel+2 );
|
|
|
|
sprintf( fnm, "___ic_temp_%05d.bin", 100*id_dm_mass );
|
|
|
|
|
|
|
|
std::ifstream
|
|
|
|
ifs1( fnx, std::ios::binary ),
|
|
|
|
ifs2( fny, std::ios::binary ),
|
|
|
|
ifs3( fnz, std::ios::binary );
|
|
|
|
|
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
const unsigned
|
2010-07-02 20:49:30 +02:00
|
|
|
nptot = header_.npart[1]+header_.npart[5];
|
2010-10-26 20:37:31 +02:00
|
|
|
unsigned
|
2010-07-02 20:49:30 +02:00
|
|
|
npleft = nptot,
|
2010-10-26 20:37:31 +02:00
|
|
|
n2read = std::min((unsigned)block_buf_size_,npleft);
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-07-21 10:10:29 +02:00
|
|
|
std::cout << " - Writing " << nptot << " particles to Gadget file...\n"
|
|
|
|
<< " type 1 : " << header_.npart[1] << "\n"
|
|
|
|
<< " type 5 : " << header_.npart[5] << "\n";
|
|
|
|
|
2010-07-02 20:49:30 +02:00
|
|
|
|
|
|
|
//... particle coordinates ..................................................
|
2010-10-26 20:37:31 +02:00
|
|
|
long long blk;
|
|
|
|
ifs1.read( (char *)&blk, sizeof(long long) );
|
|
|
|
if( blk != nptot*(long long)sizeof(T_store) )
|
|
|
|
{
|
|
|
|
LOGERR("Internal consistency error in gadget2 output plug-in");
|
|
|
|
LOGERR("Expected %d bytes in temp file but found %d",nptot*(unsigned)sizeof(T_store),blk);
|
2010-07-02 20:49:30 +02:00
|
|
|
throw std::runtime_error("Internal consistency error in gadget2 output plug-in");
|
2010-10-26 20:37:31 +02:00
|
|
|
|
|
|
|
}
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
ifs2.read( (char *)&blk, sizeof(long long) );
|
|
|
|
if( blk != nptot*(long long)sizeof(T_store) )
|
|
|
|
{
|
|
|
|
LOGERR("Internal consistency error in gadget2 output plug-in");
|
|
|
|
LOGERR("Expected %d bytes in temp file but found %d",nptot*(unsigned)sizeof(T_store),blk);
|
2010-07-02 20:49:30 +02:00
|
|
|
throw std::runtime_error("Internal consistency error in gadget2 output plug-in");
|
2010-10-26 20:37:31 +02:00
|
|
|
}
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
ifs3.read( (char *)&blk, sizeof(long long) );
|
|
|
|
if( blk != nptot*(long long)sizeof(T_store) )
|
|
|
|
{
|
|
|
|
LOGERR("Internal consistency error in gadget2 output plug-in");
|
|
|
|
LOGERR("Expected %d bytes in temp file but found %d",nptot*(unsigned)sizeof(T_store),blk);
|
2010-07-02 20:49:30 +02:00
|
|
|
throw std::runtime_error("Internal consistency error in gadget2 output plug-in");
|
2010-10-26 20:37:31 +02:00
|
|
|
}
|
2010-07-02 20:49:30 +02:00
|
|
|
|
|
|
|
std::vector<T_store> adata3;
|
|
|
|
adata3.reserve( 3*block_buf_size_ );
|
|
|
|
T_store *tmp1, *tmp2, *tmp3;
|
|
|
|
|
|
|
|
tmp1 = new T_store[block_buf_size_];
|
|
|
|
tmp2 = new T_store[block_buf_size_];
|
|
|
|
tmp3 = new T_store[block_buf_size_];
|
|
|
|
|
2010-11-13 00:05:45 +01:00
|
|
|
//int fileno = 0;
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-11-13 00:05:45 +01:00
|
|
|
//size_t npart_left = nptot;
|
2010-10-26 20:37:31 +02:00
|
|
|
|
|
|
|
while( true )
|
2010-07-02 20:49:30 +02:00
|
|
|
{
|
2010-10-26 20:37:31 +02:00
|
|
|
int blksize = sizeof(header);
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
//... write the header .......................................................
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
header this_header( header_ );
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
ofs_.write( (char *)&blksize, sizeof(int) );
|
|
|
|
ofs_.write( (char *)&this_header, sizeof(header) );
|
|
|
|
ofs_.write( (char *)&blksize, sizeof(int) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
blksize = 3*nptot*sizeof(T_store);
|
|
|
|
ofs_.write( (char *)&blksize, sizeof(int) );
|
|
|
|
|
|
|
|
while( n2read > 0 )
|
2010-07-02 20:49:30 +02:00
|
|
|
{
|
2010-10-26 20:37:31 +02:00
|
|
|
//ifs1.read( (char*)&tmp1[0], n2read*sizeof(T_store) );
|
|
|
|
ifs1.read( reinterpret_cast<char*>(&tmp1[0]), n2read*sizeof(T_store) );
|
|
|
|
ifs2.read( reinterpret_cast<char*>(&tmp2[0]), n2read*sizeof(T_store) );
|
|
|
|
ifs3.read( reinterpret_cast<char*>(&tmp3[0]), n2read*sizeof(T_store) );
|
|
|
|
|
|
|
|
for( unsigned i=0; i<n2read; ++i )
|
|
|
|
{
|
|
|
|
adata3.push_back( tmp1[i] );
|
|
|
|
adata3.push_back( tmp2[i] );
|
|
|
|
adata3.push_back( tmp3[i] );
|
|
|
|
}
|
|
|
|
ofs_.write( reinterpret_cast<char*>(&adata3[0]), 3*n2read*sizeof(T_store) );
|
|
|
|
|
|
|
|
adata3.clear();
|
|
|
|
npleft -= n2read;
|
|
|
|
n2read = std::min( block_buf_size_,npleft );
|
2010-07-02 20:49:30 +02:00
|
|
|
}
|
2010-10-26 20:37:31 +02:00
|
|
|
ofs_.write( reinterpret_cast<char*>(&blksize), sizeof(int) );
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
remove( fnx );
|
|
|
|
remove( fny );
|
|
|
|
remove( fnz );
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
//... particle velocities ..................................................
|
|
|
|
ifs1.close(); ifs1.open( fnvx, std::ios::binary );
|
|
|
|
ifs2.close(); ifs2.open( fnvy, std::ios::binary );
|
|
|
|
ifs3.close(); ifs3.open( fnvz, std::ios::binary );
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-11-11 07:56:46 +01:00
|
|
|
ifs1.read( (char *)&blk, sizeof(long long) );
|
2010-10-26 20:37:31 +02:00
|
|
|
if( blk != nptot*(unsigned)sizeof(T_store)){
|
|
|
|
delete[] tmp1;
|
|
|
|
delete[] tmp2;
|
|
|
|
delete[] tmp3;
|
|
|
|
LOGERR("Internal consistency error in gadget2 output plug-in");
|
|
|
|
LOGERR("Expected %d bytes in temp file but found %d",nptot*(unsigned)sizeof(T_store),blk);
|
|
|
|
throw std::runtime_error("Internal consistency error in gadget2 output plug-in");
|
|
|
|
}
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-11-11 07:56:46 +01:00
|
|
|
ifs2.read( (char *)&blk, sizeof(long long) );
|
2010-10-26 20:37:31 +02:00
|
|
|
if( blk != nptot*(unsigned)sizeof(T_store)){
|
|
|
|
delete[] tmp1;
|
|
|
|
delete[] tmp2;
|
|
|
|
delete[] tmp3;
|
|
|
|
LOGERR("Internal consistency error in gadget2 output plug-in");
|
|
|
|
LOGERR("Expected %d bytes in temp file but found %d",nptot*(unsigned)sizeof(T_store),blk);
|
|
|
|
throw std::runtime_error("Internal consistency error in gadget2 output plug-in");
|
|
|
|
}
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-11-11 07:56:46 +01:00
|
|
|
ifs3.read( (char *)&blk, sizeof(long long) );
|
2010-10-26 20:37:31 +02:00
|
|
|
if( blk != nptot*(unsigned)sizeof(T_store)){
|
2010-07-02 20:49:30 +02:00
|
|
|
delete[] tmp1;
|
2010-10-26 20:37:31 +02:00
|
|
|
delete[] tmp2;
|
|
|
|
delete[] tmp3;
|
|
|
|
LOGERR("Internal consistency error in gadget2 output plug-in");
|
|
|
|
LOGERR("Expected %d bytes in temp file but found %d",nptot*(unsigned)sizeof(T_store),blk);
|
2010-07-02 20:49:30 +02:00
|
|
|
throw std::runtime_error("Internal consistency error in gadget2 output plug-in");
|
|
|
|
}
|
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
npleft = nptot;
|
|
|
|
n2read = std::min(block_buf_size_,npleft);
|
2010-07-02 20:49:30 +02:00
|
|
|
|
|
|
|
|
|
|
|
ofs_.write( reinterpret_cast<char*>(&blksize), sizeof(int) );
|
2010-10-26 20:37:31 +02:00
|
|
|
|
2010-07-02 20:49:30 +02:00
|
|
|
while( n2read > 0 )
|
|
|
|
{
|
|
|
|
ifs1.read( reinterpret_cast<char*>(&tmp1[0]), n2read*sizeof(T_store) );
|
2010-10-26 20:37:31 +02:00
|
|
|
ifs2.read( reinterpret_cast<char*>(&tmp2[0]), n2read*sizeof(T_store) );
|
|
|
|
ifs3.read( reinterpret_cast<char*>(&tmp3[0]), n2read*sizeof(T_store) );
|
|
|
|
|
|
|
|
for( unsigned i=0; i<n2read; ++i )
|
|
|
|
{
|
|
|
|
adata3.push_back( tmp1[i] );
|
|
|
|
adata3.push_back( tmp2[i] );
|
|
|
|
adata3.push_back( tmp3[i] );
|
|
|
|
}
|
|
|
|
|
|
|
|
ofs_.write( reinterpret_cast<char*>(&adata3[0]), 3*n2read*sizeof(T_store) );
|
|
|
|
|
|
|
|
adata3.clear();
|
2010-07-02 20:49:30 +02:00
|
|
|
npleft -= n2read;
|
2010-10-26 20:37:31 +02:00
|
|
|
n2read = std::min( block_buf_size_,npleft );
|
2010-07-02 20:49:30 +02:00
|
|
|
}
|
|
|
|
ofs_.write( reinterpret_cast<char*>(&blksize), sizeof(int) );
|
2010-10-26 20:37:31 +02:00
|
|
|
remove( fnvx );
|
|
|
|
remove( fnvy );
|
|
|
|
remove( fnvz );
|
|
|
|
|
|
|
|
|
|
|
|
delete[] tmp2;
|
|
|
|
delete[] tmp3;
|
|
|
|
|
|
|
|
|
|
|
|
//... particle IDs ..........................................................
|
|
|
|
std::vector<unsigned> ids(block_buf_size_,0);
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
unsigned idcount = 0;
|
|
|
|
npleft = nptot;
|
|
|
|
n2read = std::min(block_buf_size_,npleft);
|
|
|
|
blksize = sizeof(unsigned)*nptot;
|
|
|
|
|
|
|
|
//... generate contiguous IDs and store in file .......................//
|
|
|
|
ofs_.write( reinterpret_cast<char*>(&blksize), sizeof(int) );
|
|
|
|
while( n2read > 0 )
|
|
|
|
{
|
|
|
|
for( unsigned i=0; i<n2read; ++i )
|
|
|
|
ids[i] = idcount++;
|
|
|
|
ofs_.write( reinterpret_cast<char*>(&ids[0]), n2read*sizeof(unsigned) );
|
|
|
|
ids.clear();
|
|
|
|
npleft -= n2read;
|
|
|
|
n2read = std::min( block_buf_size_,npleft );
|
|
|
|
}
|
|
|
|
ofs_.write( reinterpret_cast<char*>(&blksize), sizeof(int) );
|
|
|
|
|
|
|
|
|
|
|
|
//... particle masses .......................................................
|
|
|
|
if( bmultimass_ && bmorethan2bnd_ )
|
|
|
|
{
|
|
|
|
unsigned npcoarse = header_.npart[5];
|
|
|
|
|
|
|
|
ifs1.close();
|
|
|
|
ifs1.open( fnm, std::ios::binary );
|
|
|
|
|
|
|
|
if( !ifs1.good() )
|
|
|
|
{
|
|
|
|
LOGERR("Could not open buffer file in gadget2 output plug-in");
|
|
|
|
throw std::runtime_error("Could not open buffer file in gadget2 output plug-in");
|
|
|
|
}
|
|
|
|
|
2010-11-11 07:56:46 +01:00
|
|
|
ifs1.read( (char *)&blk, sizeof(long long) );
|
2010-10-26 20:37:31 +02:00
|
|
|
if( blk != npcoarse*(unsigned)sizeof(T_store)){
|
|
|
|
delete[] tmp1;
|
|
|
|
LOGERR("Internal consistency error in gadget2 output plug-in");
|
|
|
|
LOGERR("Expected %d bytes in temp file but found %d",nptot*(unsigned)sizeof(T_store),blk);
|
|
|
|
throw std::runtime_error("Internal consistency error in gadget2 output plug-in");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
npleft = npcoarse;
|
|
|
|
n2read = std::min(block_buf_size_,npleft);
|
|
|
|
blksize = npcoarse*sizeof(T_store);
|
|
|
|
|
|
|
|
ofs_.write( reinterpret_cast<char*>(&blksize), sizeof(int) );
|
|
|
|
while( n2read > 0 )
|
|
|
|
{
|
|
|
|
ifs1.read( reinterpret_cast<char*>(&tmp1[0]), n2read*sizeof(T_store) );
|
|
|
|
ofs_.write( reinterpret_cast<char*>(&tmp1[0]), n2read*sizeof(T_store) );
|
2010-11-11 07:56:46 +01:00
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
npleft -= n2read;
|
|
|
|
n2read = std::min( block_buf_size_,npleft );
|
2010-11-11 07:56:46 +01:00
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
}
|
|
|
|
ofs_.write( reinterpret_cast<char*>(&blksize), sizeof(int) );
|
|
|
|
|
|
|
|
remove( fnm );
|
|
|
|
}
|
|
|
|
|
|
|
|
delete[] tmp1;
|
|
|
|
ofs_.flush();
|
2010-10-27 06:42:49 +02:00
|
|
|
|
|
|
|
break;
|
2010-07-02 20:49:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
gadget2_output_plugin( config_file& cf )//std::string afname, Cosmology cosm, Parameters param, unsigned block_buf_size = 100000 )
|
|
|
|
: output_plugin( cf ), ofs_( fname_.c_str(), std::ios::binary|std::ios::trunc )
|
|
|
|
{
|
2010-07-21 10:10:29 +02:00
|
|
|
block_buf_size_ = cf_.getValueSafe<unsigned>("output","gadget_blksize",1048576);
|
|
|
|
//block_buf_size_ = cf_.getValueSafe<unsigned>("output","gadget_blksize",100000);
|
2010-07-02 20:49:30 +02:00
|
|
|
//bbndparticles_ = !cf_.getValueSafe<bool>("output","gadget_nobndpart",false);
|
2010-10-26 20:37:31 +02:00
|
|
|
npartmax_ = 1<<30;
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-27 06:42:49 +02:00
|
|
|
if(!ofs_.good())
|
|
|
|
throw std::runtime_error("gadget-2 output plug-in could not open output file for writing!\n");
|
|
|
|
|
2010-07-02 20:49:30 +02:00
|
|
|
bmorethan2bnd_ = false;
|
|
|
|
if( levelmax_ > levelmin_ +1)
|
|
|
|
bmorethan2bnd_ = true;
|
|
|
|
|
|
|
|
bmultimass_ = true;
|
|
|
|
if( levelmax_ == levelmin_ )
|
|
|
|
bmultimass_ = false;
|
|
|
|
|
|
|
|
|
|
|
|
for( int i=0; i<6; ++i )
|
|
|
|
{
|
|
|
|
header_.npart[i] = 0;
|
|
|
|
header_.npartTotal[i] = 0;
|
|
|
|
header_.npartTotalHighWord[i] = 0;
|
|
|
|
header_.mass[i] = 0.0;
|
|
|
|
}
|
|
|
|
|
2010-11-11 07:56:46 +01:00
|
|
|
//... write displacements in kpc/h rather than Mpc/h?
|
|
|
|
kpcunits_ = cf.getValueSafe<bool>("output","gadget_usekpc",false);
|
|
|
|
|
2010-07-02 20:49:30 +02:00
|
|
|
//... set time ......................................................
|
|
|
|
header_.redshift = cf.getValue<double>("setup","zstart");
|
|
|
|
header_.time = 1.0/(1.0+header_.redshift);
|
|
|
|
|
|
|
|
//... SF flags
|
|
|
|
header_.flag_sfr = 0;
|
|
|
|
header_.flag_feedback = 0;
|
|
|
|
header_.flag_cooling = 0;
|
|
|
|
|
|
|
|
//...
|
|
|
|
header_.num_files = 1;
|
|
|
|
header_.BoxSize = cf.getValue<double>("setup","boxlength");
|
|
|
|
header_.Omega0 = cf.getValue<double>("cosmology","Omega_m");
|
|
|
|
header_.OmegaLambda = cf.getValue<double>("cosmology","Omega_L");
|
|
|
|
header_.HubbleParam = cf.getValue<double>("cosmology","H0");
|
|
|
|
|
|
|
|
header_.flag_stellarage = 0;
|
|
|
|
header_.flag_metals = 0;
|
|
|
|
|
|
|
|
|
|
|
|
header_.flag_entropy_instead_u = 0;
|
2010-11-11 07:56:46 +01:00
|
|
|
|
|
|
|
if( kpcunits_ )
|
|
|
|
header_.BoxSize *= 1000.0;
|
2010-07-02 20:49:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void write_dm_mass( const grid_hierarchy& gh )
|
|
|
|
{
|
|
|
|
double rhoc = 27.7519737; // h^2 1e10 M_sol / Mpc^3
|
|
|
|
|
2010-11-11 07:56:46 +01:00
|
|
|
if( kpcunits_ )
|
|
|
|
rhoc *= 10.0; // in h^2 M_sol / kpc^3
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-11-11 07:56:46 +01:00
|
|
|
header_.mass[1] = header_.Omega0 * rhoc * pow(header_.BoxSize,3.)/pow(2,3*levelmax_);
|
|
|
|
|
2010-07-02 20:49:30 +02:00
|
|
|
if( bmorethan2bnd_ )
|
|
|
|
{
|
2010-10-26 20:37:31 +02:00
|
|
|
unsigned long long npcoarse = gh.count_leaf_cells(gh.levelmin(), gh.levelmax()-1);
|
|
|
|
unsigned long long nwritten = 0;
|
2010-07-02 20:49:30 +02:00
|
|
|
|
|
|
|
std::vector<T_store> temp_dat;
|
2010-10-16 08:11:10 +02:00
|
|
|
temp_dat.reserve(block_buf_size_); //clear();
|
|
|
|
|
|
|
|
char temp_fname[256];
|
|
|
|
sprintf( temp_fname, "___ic_temp_%05d.bin", 100*id_dm_mass );
|
|
|
|
std::ofstream ofs_temp( temp_fname, std::ios::binary|std::ios::trunc );
|
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
long long blksize = sizeof(T_store)*npcoarse;
|
2010-10-16 08:11:10 +02:00
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
ofs_temp.write( (char *)&blksize, sizeof(long long) );
|
2010-10-16 08:11:10 +02:00
|
|
|
|
2010-07-02 20:49:30 +02:00
|
|
|
for( int ilevel=gh.levelmax()-1; ilevel>=(int)gh.levelmin(); --ilevel )
|
|
|
|
{
|
2010-11-11 07:56:46 +01:00
|
|
|
double pmass = header_.Omega0 * rhoc * pow(header_.BoxSize,3.)/pow(2,3*ilevel);
|
2010-07-02 20:49:30 +02:00
|
|
|
|
|
|
|
for( unsigned i=0; i<gh.get_grid(ilevel)->size(0); ++i )
|
|
|
|
for( unsigned j=0; j<gh.get_grid(ilevel)->size(1); ++j )
|
|
|
|
for( unsigned k=0; k<gh.get_grid(ilevel)->size(2); ++k )
|
|
|
|
if( ! gh.is_refined(ilevel,i,j,k) )
|
2010-10-16 08:11:10 +02:00
|
|
|
{
|
|
|
|
if( temp_dat.size() < block_buf_size_ )
|
|
|
|
temp_dat.push_back( pmass );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ofs_temp.write( (char*)&temp_dat[0], sizeof(T_store)*block_buf_size_ );
|
|
|
|
nwritten += block_buf_size_;
|
|
|
|
temp_dat.clear();
|
|
|
|
temp_dat.push_back( pmass );
|
|
|
|
}
|
|
|
|
}
|
2010-07-02 20:49:30 +02:00
|
|
|
}
|
|
|
|
|
2010-10-16 08:11:10 +02:00
|
|
|
if( temp_dat.size() > 0 )
|
|
|
|
{
|
|
|
|
ofs_temp.write( (char*)&temp_dat[0], sizeof(T_store)*temp_dat.size() );
|
|
|
|
nwritten+=temp_dat.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nwritten != npcoarse )
|
|
|
|
throw std::runtime_error("Internal consistency error while writing temporary file for masses");
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
ofs_temp.write( (char *)&blksize, sizeof(long long) );
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-16 08:11:10 +02:00
|
|
|
if( ofs_temp.bad() )
|
|
|
|
throw std::runtime_error("I/O error while writing temporary file for masses");
|
2010-07-02 20:49:30 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
header_.mass[5] = header_.Omega0 * rhoc * pow(header_.BoxSize,3.)/pow(2,3*levelmin_);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void write_dm_position( int coord, const grid_hierarchy& gh )
|
|
|
|
{
|
|
|
|
//... count number of leaf cells ...//
|
2010-10-26 20:37:31 +02:00
|
|
|
unsigned long long npcoarse = 0, npfine = 0;
|
2010-07-02 20:49:30 +02:00
|
|
|
|
|
|
|
npfine = gh.count_leaf_cells(gh.levelmax(), gh.levelmax());
|
|
|
|
if( bmultimass_ )
|
|
|
|
npcoarse = gh.count_leaf_cells(gh.levelmin(), gh.levelmax()-1);
|
|
|
|
|
|
|
|
|
|
|
|
//... determine if we need to shift the coordinates back
|
|
|
|
double *shift = NULL;
|
|
|
|
|
|
|
|
if( cf_.getValueSafe<bool>("output","shift_back",false ) )
|
|
|
|
{
|
|
|
|
if( coord == 0 )
|
|
|
|
std::cout << " - gadget2 output plug-in will shift particle positions back...\n";
|
|
|
|
|
|
|
|
double h = 1.0/pow(2,levelmin_);
|
|
|
|
shift = new double[3];
|
|
|
|
shift[0] = -(double)cf_.getValue<int>( "setup", "shift_x" )*h;
|
|
|
|
shift[1] = -(double)cf_.getValue<int>( "setup", "shift_y" )*h;
|
|
|
|
shift[2] = -(double)cf_.getValue<int>( "setup", "shift_z" )*h;
|
|
|
|
}
|
|
|
|
|
2010-10-02 00:18:06 +02:00
|
|
|
/*if( !cf_.getValueSafe<bool>("output","stagger_particles",false ) )
|
2010-09-01 06:59:31 +02:00
|
|
|
{
|
|
|
|
double h = 1.0/pow(2,levelmax_);
|
|
|
|
if( shift==NULL )
|
|
|
|
{
|
|
|
|
shift = new double[3];
|
|
|
|
shift[0] = -0.5*h;
|
|
|
|
shift[1] = -0.5*h;
|
|
|
|
shift[2] = -0.5*h;
|
|
|
|
}else{
|
|
|
|
shift[0] -= 0.5*h;
|
|
|
|
shift[1] -= 0.5*h;
|
|
|
|
shift[2] -= 0.5*h;
|
|
|
|
}
|
|
|
|
|
2010-10-02 00:18:06 +02:00
|
|
|
}*/
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
unsigned long long npart = npfine+npcoarse;
|
|
|
|
unsigned long long nwritten = 0;
|
|
|
|
|
2010-07-02 20:49:30 +02:00
|
|
|
//...
|
|
|
|
header_.npart[1] = npfine;
|
|
|
|
header_.npart[5] = npcoarse;
|
2010-10-26 20:37:31 +02:00
|
|
|
header_.npartTotal[1] = (unsigned)npfine;
|
|
|
|
header_.npartTotal[5] = (unsigned)npcoarse;
|
|
|
|
header_.npartTotalHighWord[1] = (unsigned)(npfine>>32);
|
|
|
|
header_.npartTotalHighWord[5] = (unsigned)(npfine>>32);
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
header_.num_files = (int)ceil((double)npart/(double)npartmax_);
|
2010-07-02 20:49:30 +02:00
|
|
|
|
|
|
|
//... collect displacements and convert to absolute coordinates with correct
|
|
|
|
//... units
|
|
|
|
std::vector<T_store> temp_data;
|
2010-10-16 08:11:10 +02:00
|
|
|
temp_data.reserve( block_buf_size_ );
|
|
|
|
|
|
|
|
|
|
|
|
char temp_fname[256];
|
|
|
|
sprintf( temp_fname, "___ic_temp_%05d.bin", 100*id_dm_pos+coord );
|
|
|
|
std::ofstream ofs_temp( temp_fname, std::ios::binary|std::ios::trunc );
|
|
|
|
|
2010-10-26 20:37:31 +02:00
|
|
|
long long blksize = sizeof(T_store)*npart;
|
|
|
|
ofs_temp.write( (char *)&blksize, sizeof(long long) );
|
2010-07-02 20:49:30 +02:00
|
|
|
|
|
|
|
double xfac = header_.BoxSize;
|
|
|
|
|
2010-11-11 07:56:46 +01:00
|
|
|
//if(kpcunits_)
|
|
|
|
// xfac *= 1000.0;
|
|
|
|
|
2010-07-02 20:49:30 +02:00
|
|
|
for( int ilevel=gh.levelmax(); ilevel>=(int)gh.levelmin(); --ilevel )
|
|
|
|
for( unsigned i=0; i<gh.get_grid(ilevel)->size(0); ++i )
|
|
|
|
for( unsigned j=0; j<gh.get_grid(ilevel)->size(1); ++j )
|
|
|
|
for( unsigned k=0; k<gh.get_grid(ilevel)->size(2); ++k )
|
|
|
|
if( ! gh.is_refined(ilevel,i,j,k) )
|
|
|
|
{
|
|
|
|
double xx[3];
|
|
|
|
gh.cell_pos(ilevel, i, j, k, xx);
|
|
|
|
if( shift != NULL )
|
|
|
|
xx[coord] += shift[coord];
|
|
|
|
xx[coord] = fmod( (xx[coord]+(*gh.get_grid(ilevel))(i,j,k))*xfac + header_.BoxSize, header_.BoxSize );
|
2010-10-16 08:11:10 +02:00
|
|
|
|
|
|
|
if( temp_data.size() < block_buf_size_ )
|
|
|
|
temp_data.push_back( xx[coord] );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ofs_temp.write( (char*)&temp_data[0], sizeof(T_store)*block_buf_size_ );
|
|
|
|
nwritten += block_buf_size_;
|
|
|
|
temp_data.clear();
|
|
|
|
temp_data.push_back( xx[coord] );
|
|
|
|
}
|
2010-07-02 20:49:30 +02:00
|
|
|
}
|
|
|
|
|
2010-10-16 08:11:10 +02:00
|
|
|
if( temp_data.size() > 0 )
|
|
|
|
{
|
|
|
|
ofs_temp.write( (char*)&temp_data[0], sizeof(T_store)*temp_data.size() );
|
|
|
|
nwritten += temp_data.size();
|
|
|
|
}
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-16 08:11:10 +02:00
|
|
|
if( nwritten != npart )
|
|
|
|
throw std::runtime_error("Internal consistency error while writing temporary file for positions");
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-16 08:11:10 +02:00
|
|
|
//... dump to temporary file
|
2010-10-26 20:37:31 +02:00
|
|
|
ofs_temp.write( (char *)&blksize, sizeof(long long) );
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-16 08:11:10 +02:00
|
|
|
if( ofs_temp.bad() )
|
|
|
|
throw std::runtime_error("I/O error while writing temporary file for positions");
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-16 08:11:10 +02:00
|
|
|
ofs_temp.close();
|
2010-07-02 20:49:30 +02:00
|
|
|
|
|
|
|
if( shift != NULL )
|
|
|
|
delete[] shift;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void write_dm_velocity( int coord, const grid_hierarchy& gh )
|
|
|
|
{
|
|
|
|
//... count number of leaf cells ...//
|
|
|
|
unsigned npcoarse = 0, npfine = 0;
|
|
|
|
|
|
|
|
npfine = gh.count_leaf_cells(gh.levelmax(), gh.levelmax());
|
|
|
|
if( bmultimass_ )
|
|
|
|
npcoarse = gh.count_leaf_cells(gh.levelmin(), gh.levelmax()-1);
|
|
|
|
|
|
|
|
header_.npart[1] = npfine;
|
|
|
|
header_.npart[5] = npcoarse;
|
|
|
|
header_.npartTotal[1] = npfine;
|
|
|
|
header_.npartTotal[5] = npcoarse;
|
|
|
|
header_.npartTotalHighWord[1] = 0;
|
|
|
|
header_.npartTotalHighWord[5] = 0;
|
|
|
|
|
|
|
|
//... collect displacements and convert to absolute coordinates with correct
|
|
|
|
//... units
|
|
|
|
std::vector<T_store> temp_data;
|
2010-10-16 08:11:10 +02:00
|
|
|
//temp_data.reserve( npfine+npcoarse );
|
|
|
|
temp_data.reserve( block_buf_size_ );
|
2010-07-02 20:49:30 +02:00
|
|
|
|
|
|
|
float isqrta = 1.0f/sqrt(header_.time);
|
|
|
|
float vfac = isqrta*header_.BoxSize;
|
|
|
|
|
2010-11-11 07:56:46 +01:00
|
|
|
if( kpcunits_ )
|
|
|
|
vfac /= 1000.0;
|
|
|
|
|
2010-10-16 08:11:10 +02:00
|
|
|
unsigned npart = npfine+npcoarse;
|
|
|
|
unsigned nwritten = 0;
|
|
|
|
|
|
|
|
char temp_fname[256];
|
|
|
|
sprintf( temp_fname, "___ic_temp_%05d.bin", 100*id_dm_vel+coord );
|
|
|
|
std::ofstream ofs_temp( temp_fname, std::ios::binary|std::ios::trunc );
|
|
|
|
|
2010-11-11 07:56:46 +01:00
|
|
|
//int blksize = sizeof(T_store)*npart;
|
|
|
|
//ofs_temp.write( (char *)&blksize, sizeof(int) );
|
|
|
|
long long blksize = sizeof(T_store)*npart;
|
|
|
|
ofs_temp.write( (char *)&blksize, sizeof(long long) );
|
2010-10-16 08:11:10 +02:00
|
|
|
|
2010-07-02 20:49:30 +02:00
|
|
|
for( int ilevel=levelmax_; ilevel>=(int)levelmin_; --ilevel )
|
|
|
|
for( unsigned i=0; i<gh.get_grid(ilevel)->size(0); ++i )
|
|
|
|
for( unsigned j=0; j<gh.get_grid(ilevel)->size(1); ++j )
|
|
|
|
for( unsigned k=0; k<gh.get_grid(ilevel)->size(2); ++k )
|
|
|
|
if( ! gh.is_refined(ilevel,i,j,k) )
|
2010-10-16 08:11:10 +02:00
|
|
|
{
|
|
|
|
if( temp_data.size() < block_buf_size_ )
|
|
|
|
temp_data.push_back( (*gh.get_grid(ilevel))(i,j,k) * vfac );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ofs_temp.write( (char*)&temp_data[0], sizeof(T_store)*block_buf_size_ );
|
|
|
|
nwritten += block_buf_size_;
|
|
|
|
temp_data.clear();
|
|
|
|
temp_data.push_back( (*gh.get_grid(ilevel))(i,j,k) * vfac );
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
if( temp_data.size() > 0 )
|
|
|
|
{
|
|
|
|
ofs_temp.write( (char*)&temp_data[0], temp_data.size()*sizeof(T_store) );
|
|
|
|
nwritten += temp_data.size();
|
|
|
|
}
|
2010-07-02 20:49:30 +02:00
|
|
|
|
2010-10-16 08:11:10 +02:00
|
|
|
if( nwritten != npart )
|
|
|
|
throw std::runtime_error("Internal consistency error while writing temporary file for velocities");
|
2010-07-02 20:49:30 +02:00
|
|
|
|
|
|
|
ofs_temp.write( (char *)&blksize, sizeof(int) );
|
|
|
|
|
2010-10-16 08:11:10 +02:00
|
|
|
if( ofs_temp.bad() )
|
|
|
|
throw std::runtime_error("I/O error while writing temporary file for velocities");
|
|
|
|
|
|
|
|
ofs_temp.close();
|
2010-07-02 20:49:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void write_dm_density( const grid_hierarchy& gh )
|
|
|
|
{
|
|
|
|
//... we don't care about DM density for Gadget
|
|
|
|
}
|
|
|
|
|
|
|
|
void write_dm_potential( const grid_hierarchy& gh )
|
|
|
|
{ }
|
|
|
|
|
|
|
|
void write_gas_potential( const grid_hierarchy& gh )
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//... write data for gas -- don't do this
|
|
|
|
void write_gas_velocity( int coord, const grid_hierarchy& gh )
|
|
|
|
{
|
|
|
|
std::cout << " - WARNING: Gadget-2 output plug-in does not support baryons yet!\n"
|
|
|
|
<< " Baryon data is not written to file!" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void write_gas_position( int coord, const grid_hierarchy& gh )
|
|
|
|
{
|
|
|
|
std::cout << " - WARNING: Gadget-2 output plug-in does not support baryons yet!\n"
|
|
|
|
<< " Baryon data is not written to file!" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void write_gas_density( const grid_hierarchy& gh )
|
|
|
|
{
|
|
|
|
std::cout << " - WARNING: Gadget-2 output plug-in does not support baryons yet!\n"
|
|
|
|
<< " Baryon data is not written to file!" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void finalize( void )
|
|
|
|
{
|
|
|
|
this->assemble_gadget_file();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace{
|
|
|
|
output_plugin_creator_concrete< gadget2_output_plugin<float> > creator1("gadget2");
|
|
|
|
#ifndef SINGLE_PRECISION
|
|
|
|
output_plugin_creator_concrete< gadget2_output_plugin<double> > creator2("gadget2_double");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|