TPRT57JJWUDQ6C24ZJETKIDWODKWGYDISPYR3B42BNA25UAOVT3AC
G6X2R5HSOTVAF5UMMYILUTUXLOVWZ6Y5Q5KXUJAMRHTD7POWNIHAC
B7Y552HZXBV2PD22T7ZXGFJKUYU23A7XDWV4XZK46SGQKX7U45PQC
4A3DZIOI4URHKDB5SKTLQHM273MBH25AI2T2BTV7BXJIPGOKIPGAC
2MTD37PDBF7KZKC6LXG2IVDYMMUMNNS557WMFVSCZM3SAKOGDC5QC
FEMASUBNU32NSG4DNXZX54CGCA57PVRGYO46L3A6F2EJ4BCSJ3SAC
RCLGQ2LZMFVPBPTU2G55DJ6HZPOGGTPZRZCY54VGP6YLHANJ2LAQC
NUOLOGCKMF5UOBGBYEOX4O7NQ5AEVVLCH6KRBQRJQXIRDNJ2C2ZQC
EJWFGXTWIBKJ62LO6QM62LM7MGTYEHOCZDKA3UVR5UYWQZ2O54DQC
2DKSL6DKZAIYQUJGDULORCKU5K4Z5Z3W4RIKQYDSLKMCNQNDZFBAC
N42E473LAYAM5NC4UXPM6WD37FLCUM26JCCKCARQEMXM7V6GWYNQC
6PYEITKIMEZZLF2UZMYD5QJWQYCXKGWTRBE7OENW5EEAXAQSKHPQC
7PAIPBWZYYNQN2YXNUNXVMUTVBT2SA7SVX5NMNKMBAE2OAOC63XQC
IUZBBJREO22GSWFJTEXQYPOYALGCQB6J5XLOKSLPQY6D42O7CR7AC
FS7Q6TUHBK5WSRDC3TM6KV2BPGWATRBLDHFGEJ72BR3FRDEOC3WAC
YIQN7NJTGEVKW7JZHL6CTH6EPCIXCNBYNURIGXPYZAOUX3VAJQMAC
BJDGFYBMECTJG7BHLNHLSCUCBVYHAY6OGY37FIJP6JDGNDXQNQVAC
3KQ5ZQE45TNGATMW4R4NHXVBULGOXHF7JYC53BZL2LNDQ2V7C2CAC
5XGIB7XMEZNBLA5ZLQTXRTC3AZ5CTRGMXWBPVMWXG4DPHKWDF4ZAC
UZAKARMGORRQG733ZUPJOEGL5FG243I32NCC2SRSFDCZKUQ5A52QC
M5R6KQLXLGYSVKHVAX5AJKD6NYE6IM5Z6WVTR3BTKPJDNNKF3ARAC
OJZWEAJRLOA5FZAC6FMGBQ6XFQFDNO55IRWLFWDAYWM54MUIU5LAC
M7FZ5YH4U6TXWMCSM6A5GDXXUH636DROLQJPZV5SG52IR7227VJQC
KJSF54YTAY3FMPYFLPRFP3Y7LQWLQKSUO7JARUPHLJJMXRVXSRGAC
BQW37JNPOOQ5E3J5BSTIB4SIUNFCD5KM36LSEU2EBCLOEWZBESVQC
WASO7G5FJXRXWNH2U2FLUNEKU6VE63OI3HUYP64BVD4LMD6KE7OQC
GKKJ75HX2ERLVBZVE2CUB6T3J2SUT7R3UKEKTEYNOG43ZKX6X5MQC
DGEGTDYVGRHEGNFDHCCVTD6AVLRJ2XHDXQPWR5MMR62V5NU2XGIQC
722HZ7UFINNE3YKSYKP2NHZ5XEG5QQLQHSKC7PREJZR3EX6RDYUAC
#include <array>
#include <cassert>
#include <cctype>
#include <fstream>
#include <functional>
#include <memory>
void WriteTSV(const cGH *restrict cctkGH, const string &filename, int gi,
const vector<string> &varnames) {
ostringstream buf;
buf << filename << ".tsv";
ofstream file(buf.str());
const string sep = "\t";
// get more precision for floats, could also use
// https://stackoverflow.com/a/30968371
file << setprecision(numeric_limits<CCTK_REAL>::digits10 + 1) << scientific;
// Output header
file << "# 1:iteration" << sep << "2:time" << sep << "3:level" << sep
<< "4:component" << sep << "5:i" << sep << "6:j" << sep << "7:k" << sep
<< "8:x" << sep << "9:y" << sep << "10:z";
int col = 11;
for (const auto &varname : varnames)
file << sep << col++ << ":" << varname;
file << "\n";
for (const auto &leveldata : ghext->leveldata) {
const auto &groupdata = *leveldata.groupdata.at(gi);
const int tl = 0;
const auto &geom = ghext->amrcore->Geom(leveldata.level);
const auto &mfab = *groupdata.mfab.at(tl);
for (amrex::MFIter mfi(mfab); mfi.isValid(); ++mfi) {
const amrex::Array4<const CCTK_REAL> &vars = mfab.array(mfi);
const auto &imin = vars.begin;
const auto &imax = vars.end;
for (int k = imin.z; k < imax.z; ++k) {
for (int j = imin.y; j < imax.y; ++j) {
for (int i = imin.x; i < imax.x; ++i) {
const array<int, dim> I{i, j, k};
array<CCTK_REAL, dim> x;
for (int d = 0; d < dim; ++d)
x[d] = geom.ProbLo(d) +
(I[d] + 0.5 * groupdata.indextype[d]) * geom.CellSize(d);
file << cctkGH->cctk_iteration << sep << cctkGH->cctk_time << sep
<< leveldata.level << sep << mfi.index() << sep << I[0] << sep
<< I[1] << sep << I[2] << sep << x[0] << sep << x[1] << sep
<< x[2];
for (int n = 0; n < groupdata.numvars; ++n)
file << sep << vars(i, j, k, n);
file << "\n";
}
}
}
}
}
file.close();
}
void OutputTSV(const cGH *restrict cctkGH) {
DECLARE_CCTK_ARGUMENTS;
DECLARE_CCTK_PARAMETERS;
if (!out_tsv)
return;
static Timer timer("OutputTSV");
Interval interval(timer);
const int numgroups = CCTK_NumGroups();
for (int gi = 0; gi < numgroups; ++gi) {
cGroup group;
int ierr = CCTK_GroupData(gi, &group);
assert(!ierr);
if (group.grouptype != CCTK_GF)
continue;
auto &restrict groupdata0 = *ghext->leveldata.at(0).groupdata.at(gi);
if (groupdata0.mfab.size() > 0) {
const int tl = 0;
string groupname = unique_C_ptr<char>(CCTK_GroupName(gi)).get();
groupname = regex_replace(groupname, regex("::"), "-");
for (auto &c : groupname)
c = tolower(c);
ostringstream buf;
buf << out_dir << "/" << groupname;
buf << ".it" << setw(6) << setfill('0') << cctk_iteration;
buf << ".p" << setw(4) << setfill('0') << CCTK_MyProc(nullptr);
const string filename = buf.str();
amrex::Vector<string> varnames(groupdata0.numvars);
for (int vi = 0; vi < groupdata0.numvars; ++vi) {
ostringstream buf;
buf << CCTK_VarName(groupdata0.firstvarindex + vi);
for (int i = 0; i < tl; ++i)
buf << "_p";
varnames.at(vi) = buf.str();
}
WriteTSV(cctkGH, filename, gi, varnames);
}
}
}
////////////////////////////////////////////////////////////////////////////////
#include "io_tsv.hxx"
#include "driver.hxx"
#include "timer.hxx"
#include <cctk_Arguments.h>
#include <cctk_Parameters.h>
#include <fstream>
#include <iomanip>
#include <limits>
#include <regex>
#include <string>
#include <vector>
namespace CarpetX {
using namespace std;
void WriteTSV(const cGH *restrict cctkGH, const string &filename, int gi,
const vector<string> &varnames) {
ostringstream buf;
buf << filename << ".tsv";
ofstream file(buf.str());
const string sep = "\t";
// get more precision for floats, could also use
// https://stackoverflow.com/a/30968371
file << setprecision(numeric_limits<CCTK_REAL>::digits10 + 1) << scientific;
// Output header
file << "# 1:iteration" << sep << "2:time" << sep << "3:level" << sep
<< "4:component" << sep << "5:i" << sep << "6:j" << sep << "7:k" << sep
<< "8:x" << sep << "9:y" << sep << "10:z";
int col = 11;
for (const auto &varname : varnames)
file << sep << col++ << ":" << varname;
file << "\n";
for (const auto &leveldata : ghext->leveldata) {
const auto &groupdata = *leveldata.groupdata.at(gi);
const int tl = 0;
const auto &geom = ghext->amrcore->Geom(leveldata.level);
const auto &mfab = *groupdata.mfab.at(tl);
for (amrex::MFIter mfi(mfab); mfi.isValid(); ++mfi) {
const amrex::Array4<const CCTK_REAL> &vars = mfab.array(mfi);
const auto &imin = vars.begin;
const auto &imax = vars.end;
for (int k = imin.z; k < imax.z; ++k) {
for (int j = imin.y; j < imax.y; ++j) {
for (int i = imin.x; i < imax.x; ++i) {
const array<int, dim> I{i, j, k};
array<CCTK_REAL, dim> x;
for (int d = 0; d < dim; ++d)
x[d] = geom.ProbLo(d) +
(I[d] + 0.5 * groupdata.indextype[d]) * geom.CellSize(d);
file << cctkGH->cctk_iteration << sep << cctkGH->cctk_time << sep
<< leveldata.level << sep << mfi.index() << sep << I[0] << sep
<< I[1] << sep << I[2] << sep << x[0] << sep << x[1] << sep
<< x[2];
for (int n = 0; n < groupdata.numvars; ++n)
file << sep << vars(i, j, k, n);
file << "\n";
}
}
}
}
}
file.close();
}
void OutputTSV(const cGH *restrict cctkGH) {
DECLARE_CCTK_ARGUMENTS;
DECLARE_CCTK_PARAMETERS;
if (!out_tsv)
return;
static Timer timer("OutputTSV");
Interval interval(timer);
const int numgroups = CCTK_NumGroups();
for (int gi = 0; gi < numgroups; ++gi) {
cGroup group;
int ierr = CCTK_GroupData(gi, &group);
assert(!ierr);
if (group.grouptype != CCTK_GF)
continue;
auto &restrict groupdata0 = *ghext->leveldata.at(0).groupdata.at(gi);
if (groupdata0.mfab.size() > 0) {
const int tl = 0;
string groupname = unique_C_ptr<char>(CCTK_GroupName(gi)).get();
groupname = regex_replace(groupname, regex("::"), "-");
for (auto &c : groupname)
c = tolower(c);
ostringstream buf;
buf << out_dir << "/" << groupname;
buf << ".it" << setw(6) << setfill('0') << cctk_iteration;
buf << ".p" << setw(4) << setfill('0') << CCTK_MyProc(nullptr);
const string filename = buf.str();
amrex::Vector<string> varnames(groupdata0.numvars);
for (int vi = 0; vi < groupdata0.numvars; ++vi) {
ostringstream buf;
buf << CCTK_VarName(groupdata0.firstvarindex + vi);
for (int i = 0; i < tl; ++i)
buf << "_p";
varnames.at(vi) = buf.str();
}
WriteTSV(cctkGH, filename, gi, varnames);
}
}
}
} // namespace CarpetX
#ifndef IO_TSV_HXX
#define IO_TSV_HXX
#include <cctk.h>
namespace CarpetX {
void OutputTSV(const cGH *restrict cctkGH);
}
#endif // #ifndef IO_TSV_HXX