diff options
author | tradke <> | 2004-06-23 15:36:00 +0000 |
---|---|---|
committer | tradke <> | 2004-06-23 15:36:00 +0000 |
commit | 936adee491b4058247ffa66aef122d8076702cb4 (patch) | |
tree | a8502a03f7bc38cdf9ae735b264ff18e734d5774 | |
parent | 69565ea8c378f3954271cd59253d9a881db1891d (diff) |
Output floating-point numbers with precision as specified by the IOASCII::out_precision parameter.
Replaced " " delimiter by a single tab to save file space.
darcs-hash:20040623153641-1d9bf-1ac576623c6f113dbe93d6ef18c33a15b1f1d1f5.gz
-rw-r--r-- | Carpet/CarpetIOASCII/src/ioascii.cc | 395 |
1 files changed, 198 insertions, 197 deletions
diff --git a/Carpet/CarpetIOASCII/src/ioascii.cc b/Carpet/CarpetIOASCII/src/ioascii.cc index 668cc88ab..eb28e27d0 100644 --- a/Carpet/CarpetIOASCII/src/ioascii.cc +++ b/Carpet/CarpetIOASCII/src/ioascii.cc @@ -29,9 +29,9 @@ #include "carpet.hh" #include "ioascii.hh" - + extern "C" { - static const char* rcsid = "$Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetIOASCII/src/ioascii.cc,v 1.76 2004/06/21 16:07:19 schnetter Exp $"; + static const char* rcsid = "$Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetIOASCII/src/ioascii.cc,v 1.77 2004/06/23 17:36:41 tradke Exp $"; CCTK_FILEVERSION(Carpet_CarpetIOASCII_ioascii_cc); } @@ -45,39 +45,39 @@ namespace Carpet { namespace CarpetIOASCII { - + using namespace std; using namespace Carpet; - + void SetFlag (int index, const char* optstring, void* arg); - - - + + + // Special output routines for complex numbers - + #ifdef CCTK_REAL4 ostream& operator<< (ostream& os, const CCTK_COMPLEX8& val) { return os << CCTK_Cmplx8Real(val) << " " << CCTK_Cmplx8Imag(val); } #endif - + #ifdef CCTK_REAL8 ostream& operator<< (ostream& os, const CCTK_COMPLEX16& val) { return os << CCTK_Cmplx16Real(val) << " " << CCTK_Cmplx16Imag(val); } #endif - + #ifdef CCTK_REAL16 ostream& operator<< (ostream& os, const CCTK_COMPLEX32& val) { return os << CCTK_Cmplx32Real(val) << " " << CCTK_Cmplx32Imag(val); } #endif - - - + + + template<int D,int DD> void WriteASCII (ostream& os, const gdata<D>* const gfdata, @@ -94,9 +94,9 @@ namespace CarpetIOASCII { const CCTK_REAL coord_time, const vect<CCTK_REAL,D>& coord_lower, const vect<CCTK_REAL,D>& coord_upper); - - - + + + int CarpetIOASCIIStartup() { IOASCII<0>::Startup(); @@ -105,43 +105,43 @@ namespace CarpetIOASCII { IOASCII<3>::Startup(); return 0; } - - - + + + void CarpetIOASCIIInit (CCTK_ARGUMENTS) { DECLARE_CCTK_ARGUMENTS; - + for (int d=0; d<4; ++d) { this_iteration[d] = 0; last_output_iteration[d] = 0; last_output_time[d] = cctk_time; } } - - - + + + // Definition of static members template<int outdim> int IOASCII<outdim>::GHExtension; template<int outdim> int IOASCII<outdim>::IOMethod; template<int outdim> vector<bool> IOASCII<outdim>::do_truncate; template<int outdim> vector<vector<vector<int> > > IOASCII<outdim>::last_output; - - - + + + template<int outdim> int IOASCII<outdim>::Startup() { ostringstream msg; msg << "AMR " << outdim << "D ASCII I/O provided by CarpetIOASCII"; CCTK_RegisterBanner (msg.str().c_str()); - + ostringstream extension_name; extension_name << "CarpetIOASCII_" << outdim << "D"; GHExtension = CCTK_RegisterGHExtension(extension_name.str().c_str()); CCTK_RegisterGHExtensionSetupGH (GHExtension, SetupGH); - + ostringstream method_name; method_name << "IOASCII_" << outdim << "D"; IOMethod = CCTK_RegisterIOMethod (method_name.str().c_str()); @@ -149,19 +149,19 @@ namespace CarpetIOASCII { CCTK_RegisterIOMethodOutputVarAs (IOMethod, OutputVarAs); CCTK_RegisterIOMethodTimeToOutput (IOMethod, TimeToOutput); CCTK_RegisterIOMethodTriggerOutput (IOMethod, TriggerOutput); - + return 0; } - - - + + + template<int outdim> void* IOASCII<outdim> ::SetupGH (tFleshConfig* const fc, const int convLevel, cGH* const cgh) { DECLARE_CCTK_PARAMETERS; const void *dummy; - + dummy = &fc; dummy = &convLevel; dummy = &cgh; @@ -169,7 +169,7 @@ namespace CarpetIOASCII { // Truncate all files if this is not a restart do_truncate.resize(CCTK_NumVars(), true); - + // No iterations have yet been output last_output.resize(mglevels); for (int ml=0; ml<mglevels; ++ml) { @@ -178,15 +178,15 @@ namespace CarpetIOASCII { last_output.at(ml).at(rl).resize(CCTK_NumVars(), -1); } } - + // We register only once, ergo we get only one handle. We store // that statically, so there is no need to pass anything to // Cactus. return 0; } - - - + + + template<int outdim> int IOASCII<outdim> ::OutputGH (const cGH* const cgh) @@ -198,18 +198,18 @@ namespace CarpetIOASCII { } return 0; } - - - + + + template<int outdim> int IOASCII<outdim> ::OutputVarAs (const cGH* const cgh, const char* const varname, const char* const alias) { DECLARE_CCTK_PARAMETERS; - + assert (is_level_mode()); - + const int n = CCTK_VarIndex(varname); if (n<0) { CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, @@ -225,7 +225,7 @@ namespace CarpetIOASCII { assert (var>=0 && var<CCTK_NumVarsInGroupI(group)); const int num_tl = CCTK_NumTimeLevelsFromVarI(n); assert (num_tl>=1); - + // Check for storage if (! CCTK_QueryGroupStorageI(cgh, group)) { CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, @@ -233,7 +233,7 @@ namespace CarpetIOASCII { varname); return 0; } - + const int grouptype = CCTK_GroupTypeI(group); switch (grouptype) { case CCTK_SCALAR: @@ -247,7 +247,7 @@ namespace CarpetIOASCII { assert (0); } const int rl = grouptype == CCTK_GF ? reflevel : 0; - + const int groupdim = CCTK_GroupDimI(group); if (outdim > groupdim) { CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, @@ -255,11 +255,11 @@ namespace CarpetIOASCII { return -1; } assert (outdim <= groupdim); - + // Get grid hierarchy extentsion from IOUtil const ioGH * const iogh = (const ioGH *)CCTK_GHExtension (cgh, "IO"); assert (iogh); - + // Create the output directory const char* myoutdir = GetStringParameter("out%dD_dir"); if (CCTK_EQUALS(myoutdir, "")) { @@ -268,13 +268,13 @@ namespace CarpetIOASCII { if (CCTK_MyProc(cgh)==0) { CCTK_CreateDirectory (0755, myoutdir); } - + // Loop over all direction combinations vect<int,outdim> dirs (0); - + bool done; do { - + // Output each combination only once bool ascending = true; for (int d1=0; d1<outdim; ++d1) { @@ -282,10 +282,10 @@ namespace CarpetIOASCII { ascending = ascending && dirs[d1] < dirs[d2]; } } - + // Skip output if the dimensions are not ascending if (ascending) { - + // If this output is desired at all bool desired; switch (outdim) { @@ -326,13 +326,13 @@ namespace CarpetIOASCII { default: assert (0); } - + // Skip output if not desired if (desired) { - + // Traverse all maps on this refinement and multigrid level BEGIN_MAP_LOOP(cgh, grouptype) { - + // Find the output offset ivect offset(0); if (grouptype == CCTK_GF) { @@ -420,10 +420,10 @@ namespace CarpetIOASCII { assert (0); } } // if grouptype is GF - + ofstream file; if (CCTK_MyProc(cgh)==0) { - + // Invent a file name ostringstream filenamebuf; if (new_filename_scheme) { @@ -462,7 +462,7 @@ namespace CarpetIOASCII { // we need a persistent temporary here string filenamestr = filenamebuf.str(); const char* const filename = filenamestr.c_str(); - + // If this is the first time, then write a nice header if (do_truncate.at(n)) { struct stat fileinfo; @@ -484,46 +484,46 @@ namespace CarpetIOASCII { assert (file.good()); } } - + // Open the file if (! file.is_open()) { file.open (filename, ios::out | ios::app); assert (file.good()); } - - file << setprecision(15); + + file << setprecision(out_precision); assert (file.good()); - + } // if on the root processor - + // Traverse and components on this multigrid and // refinement level and map BEGIN_COMPONENT_LOOP(cgh, grouptype) { - + const ggf<dim>* ff = 0; - + assert (var < (int)arrdata.at(group).at(Carpet::map).data.size()); ff = (ggf<dim>*)arrdata.at(group).at(Carpet::map).data.at(var); - + const int mintl = output_all_timelevels ? 1-num_tl : 0; const int maxtl = 0; for (int tl=mintl; tl<=maxtl; ++tl) { - + const gdata<dim>* const data = (*ff) (tl, rl, component, mglevel); ibbox ext = data->extent(); - + ivect lo = ext.lower(); ivect hi = ext.upper(); ivect str = ext.stride(); - + // Ignore ghost zones if desired for (int d=0; d<dim; ++d) { bool output_lower_ghosts = cgh->cctk_bbox[2*d] ? out3D_outer_ghosts : out3D_ghosts; bool output_upper_ghosts = cgh->cctk_bbox[2*d+1] ? out3D_outer_ghosts : out3D_ghosts; - + if (! output_lower_ghosts) { lo[d] += cgh->cctk_nghostzones[d] * str[d]; } @@ -532,7 +532,7 @@ namespace CarpetIOASCII { } } ext = ibbox(lo,hi,str); - + // coordinates const CCTK_REAL coord_time = cgh->cctk_time; rvect global_lower; @@ -552,7 +552,7 @@ namespace CarpetIOASCII { = global_lower + coord_delta * rvect(lo); const rvect coord_upper = global_lower + coord_delta * rvect(hi); - + ivect offset1; if (grouptype == CCTK_GF) { const ibbox& baseext = vdd.at(Carpet::map)->bases.at(0).at(mglevel).exterior; @@ -563,12 +563,12 @@ namespace CarpetIOASCII { for (int d=0; d<outdim; ++d) { offset1[dirs[d]] = ext.lower()[dirs[d]]; } - + WriteASCII (file, data, ext, n, cgh->cctk_iteration, offset1, dirs, rl, mglevel, Carpet::map, component, tl, coord_time, coord_lower, coord_upper); - + // Append EOL after every component if (CCTK_MyProc(cgh)==0) { if (separate_components) { @@ -577,11 +577,11 @@ namespace CarpetIOASCII { } } assert (file.good()); - + } // for tl - + } END_COMPONENT_LOOP; - + // Append EOL after every complete set of components if (CCTK_MyProc(cgh)==0) { if (separate_grids) { @@ -591,15 +591,15 @@ namespace CarpetIOASCII { file.close(); assert (file.good()); } - + assert (! file.is_open()); - + } END_MAP_LOOP; - + } // if (desired) - + } // if (ascending) - + // Next direction combination done = true; for (int d=0; d<outdim; ++d) { @@ -610,28 +610,28 @@ namespace CarpetIOASCII { } dirs[d] = 0; } - + } while (! done); // all directions - + // Don't truncate again do_truncate.at(n) = false; - + return 0; } - - - + + + template<int outdim> int IOASCII<outdim> ::TimeToOutput (const cGH* const cctkGH, const int vindex) { DECLARE_CCTK_ARGUMENTS; DECLARE_CCTK_PARAMETERS; - + assert (vindex>=0 && vindex<CCTK_NumVars()); - - - + + + const int grouptype = CCTK_GroupTypeFromVarI(vindex); switch (grouptype) { case CCTK_SCALAR: @@ -644,24 +644,24 @@ namespace CarpetIOASCII { default: assert (0); } - - - + + + // check whether to output at this iteration bool output_this_iteration; - + const char* myoutcriterion = GetStringParameter("out%dD_criterion"); if (CCTK_EQUALS(myoutcriterion, "default")) { myoutcriterion = out_criterion; } - + if (CCTK_EQUALS (myoutcriterion, "never")) { - + // Never output output_this_iteration = false; - + } else if (CCTK_EQUALS (myoutcriterion, "iteration")) { - + int myoutevery = GetIntParameter("out%dD_every"); if (myoutevery == -2) { myoutevery = out_every; @@ -682,9 +682,9 @@ namespace CarpetIOASCII { // we want no output at this iteration output_this_iteration = false; } - + } else if (CCTK_EQUALS (myoutcriterion, "divisor")) { - + int myoutevery = GetIntParameter("out%dD_every"); if (myoutevery == -2) { myoutevery = out_every; @@ -698,10 +698,10 @@ namespace CarpetIOASCII { } else { // we want no output at this iteration output_this_iteration = false; - } + } } else if (CCTK_EQUALS (myoutcriterion, "time")) { - + CCTK_REAL myoutdt = GetRealParameter("out%dD_dt"); if (myoutdt == -2) { myoutdt = out_dt; @@ -725,24 +725,24 @@ namespace CarpetIOASCII { // we want no output at this iteration output_this_iteration = false; } - + } else { - + assert (0); - + } // select output criterion - + if (! output_this_iteration) return 0; - - - + + + // check which variables to output static vector<bool> output_variables; static int output_variables_iteration = -1; - + if (cctk_iteration > output_variables_iteration) { output_variables.resize (CCTK_NumVars()); - + const char* const varlist = GetStringParameter("out%dD_vars"); if (CCTK_TraverseString (varlist, SetFlag, &output_variables, CCTK_GROUP_OR_VAR) < 0) @@ -756,11 +756,11 @@ namespace CarpetIOASCII { output_variables_iteration = cctk_iteration; } - + if (! output_variables.at(vindex)) return 0; - - - + + + if (last_output.at(mglevel).at(reflevel).at(vindex) == cctk_iteration) { // Has already been output during this iteration char* varname = CCTK_FullName(vindex); @@ -772,32 +772,32 @@ namespace CarpetIOASCII { free (varname); return 0; } - + assert (last_output.at(mglevel).at(reflevel).at(vindex) < cctk_iteration); - + // Should be output during this iteration return 1; } - - - + + + template<int outdim> int IOASCII<outdim> ::TriggerOutput (const cGH* const cgh, const int vindex) { assert (vindex>=0 && vindex<CCTK_NumVars()); - + char* varname = CCTK_FullName(vindex); const int retval = OutputVarAs (cgh, varname, CCTK_VarName(vindex)); free (varname); - + last_output.at(mglevel).at(reflevel).at(vindex) = cgh->cctk_iteration; - + return retval; } - - - + + + template<int outdim> int IOASCII<outdim> ::GetGridOffset (const cGH* const cgh, const int dir, @@ -820,7 +820,7 @@ namespace CarpetIOASCII { assert (ptype == PARAMETER_REAL); return CoordToOffset (cgh, dir, coord, 0); } - + // Second choice: explicit index char iparam[1000]; snprintf (iparam, sizeof iparam, itempl, outdim); @@ -835,7 +835,7 @@ namespace CarpetIOASCII { assert (ptype == PARAMETER_INT); return index; } - + // Third choice: explicit global coordinate const char* iothorn = CCTK_ImplementationThorn ("IO"); assert (iothorn); @@ -852,7 +852,7 @@ namespace CarpetIOASCII { return CoordToOffset (cgh, dir, coord, 0); } } - + // Fourth choice: explicit global index if (iglobal) { const int niglobal = CCTK_ParameterQueryTimesSet (iglobal, iothorn); @@ -867,55 +867,55 @@ namespace CarpetIOASCII { return index; } } - + // Fifth choice: default coordinate return CoordToOffset (cgh, dir, cfallback, 0); } - - - + + + template<int outdim> int IOASCII<outdim> ::CoordToOffset (const cGH* cgh, const int dir, const CCTK_REAL coord, const int ifallback) { assert (dir>=1 && dir<=dim); - + assert (mglevel!=-1 && reflevel!=-1 && Carpet::map!=-1); - + const CCTK_REAL delta = cgh->cctk_delta_space[dir-1] / cgh->cctk_levfac[dir-1]; const CCTK_REAL lower = cgh->cctk_origin_space[dir-1]; #if 0 const int npoints = cgh->cctk_gsh[dir-1]; const CCTK_REAL upper = lower + (npoints-1) * delta; #endif - + const CCTK_REAL rindex = (coord - lower) / delta; int cindex = (int)floor(rindex + 0.75); - + #if 0 if (cindex<0 || cindex>=npoints) { cindex = ifallback; - + assert (dir>=1 && dir<=3); CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, "The specified coordinate value %g for the %c-direction is not within the grid range [%g,%g] on convergence level %d, refinement level %d, map %d; using %g instead", coord, "xyz"[dir-1], lower, upper, mglevel, reflevel, Carpet::map, lower + delta * cindex); } - + assert (cindex>=0 && cindex<npoints); #else const void *dummy; dummy = &ifallback; dummy = &dummy; #endif - + return cindex; } - - - + + + template<int outdim> const char* IOASCII<outdim> ::GetStringParameter (const char* const parametertemplate) @@ -930,9 +930,9 @@ namespace CarpetIOASCII { assert (ptype == PARAMETER_STRING || ptype == PARAMETER_KEYWORD); return pval; } - - - + + + template<int outdim> CCTK_INT IOASCII<outdim> ::GetIntParameter (const char* const parametertemplate) @@ -948,9 +948,9 @@ namespace CarpetIOASCII { const CCTK_INT pval = *ppval; return pval; } - - - + + + template<int outdim> CCTK_REAL IOASCII<outdim> ::GetRealParameter (const char* const parametertemplate) @@ -966,18 +966,18 @@ namespace CarpetIOASCII { const CCTK_REAL pval = *ppval; return pval; } - - - + + + void SetFlag (int index, const char* optstring, void* arg) { optstring = optstring; vector<bool>& flags = *(vector<bool>*)arg; flags.at(index) = true; } - - - + + + // Output template<int D,int DD> void WriteASCII (ostream& os, @@ -997,16 +997,16 @@ namespace CarpetIOASCII { const vect<CCTK_REAL,D>& coord_upper) { assert (DD<=D); - + if (gfdata->proc()==0) { // output on processor 0 - + int rank; MPI_Comm_rank (dist::comm, &rank); if (rank == 0) { - + assert (os.good()); - + os << "# iteration " << time << endl << "# refinement level " << rl << " multigrid level " << ml @@ -1014,45 +1014,46 @@ namespace CarpetIOASCII { << " component " << c << " time level " << tl << endl - << "# column format: it tl rl c ml "; + << "# column format: it\ttl rl c ml\t"; assert (D>=1 && D<=3); const char* const coords = "xyz"; - for (int d=0; d<D; ++d) os << " i" << coords[d]; - os << " time "; - for (int d=0; d<D; ++d) os << " " << coords[d]; - os << " data" << endl; - + for (int d=0; d<D-1; ++d) os << "i" << coords[d] << " "; os << "i" << coords[D-1]; + os << "\ttime\t"; + for (int d=0; d<D-1; ++d) os << coords[d] << " "; os << coords[D-1]; + os << "\tdata" << endl; + const vect<int,DD> lo = gfext.lower()[dirs]; const vect<int,DD> up = gfext.upper()[dirs]; const vect<int,DD> str = gfext.stride()[dirs]; const bbox<int,DD> ext(lo,up,str); - + // Check whether the output origin is contained in the extent // of the data that should be output ivect org1(org); for (int d=0; d<DD; ++d) org1[dirs[d]] = ext.lower()[d]; if (gfext.contains(org1)) { - + typename bbox<int,DD>::iterator it=ext.begin(); do { - + ivect index(org); for (int d=0; d<DD; ++d) index[dirs[d]] = (*it)[d]; - os << time << " " << tl << " " << rl << " " << c << " " << ml - << " "; - for (int d=0; d<D; ++d) os << " " << index[d]; - os << " " << coord_time << " "; + os << time << "\t" << tl << " " << rl << " " << c << " " << ml + << "\t"; + for (int d=0; d<D-1; ++d) os << index[d] << " "; os << index[D-1]; + os << "\t" << coord_time << "\t"; for (int d=0; d<D; ++d) { assert (gfext.upper()[d] - gfext.lower()[d] >= 0); if (gfext.upper()[d] - gfext.lower()[d] == 0) { - os << " " << coord_lower[d]; + os << coord_lower[d]; } else { - os << " " << (coord_lower[d] + (index[d] - gfext.lower()[d]) + os << (coord_lower[d] + (index[d] - gfext.lower()[d]) * (coord_upper[d] - coord_lower[d]) / (gfext.upper()[d] - gfext.lower()[d])); } + if (d != D-1) os << " "; } - os << " "; + os << "\t"; switch (CCTK_VarTypeI(vi)) { #define TYPECASE(N,T) \ case N: \ @@ -1064,29 +1065,29 @@ namespace CarpetIOASCII { UnsupportedVarType(vi); } os << endl; - + ++it; - + for (int d=0; d<DD; ++d) { if ((*it)[d]!=(*ext.end())[d]) break; os << endl; } - + } while (it!=ext.end()); - + } else { - + os << "#" << endl; - + } // if ! ext contains org - + assert (os.good()); - + } - + } else { // copy to processor 0 and output there - + gdata<D>* const tmp = gfdata->make_typed(vi); tmp->allocate(gfdata->extent(), 0); for (comm_state<dim> state; !state.done(); state.step()) { @@ -1095,20 +1096,20 @@ namespace CarpetIOASCII { WriteASCII (os, tmp, gfext, vi, time, org, dirs, rl, ml, m, c, tl, coord_time, coord_lower, coord_upper); delete tmp; - + } } - - - - - + + + + + // Explicit instantiation for all output dimensions template class IOASCII<0>; template class IOASCII<1>; template class IOASCII<2>; template class IOASCII<3>; - + template void WriteASCII (ostream& os, const gdata<3>* const gfdata, @@ -1125,7 +1126,7 @@ namespace CarpetIOASCII { const CCTK_REAL coord_time, const vect<CCTK_REAL,3>& coord_lower, const vect<CCTK_REAL,3>& coord_upper); - + template void WriteASCII (ostream& os, const gdata<3>* const gfdata, @@ -1142,7 +1143,7 @@ namespace CarpetIOASCII { const CCTK_REAL coord_time, const vect<CCTK_REAL,3>& coord_lower, const vect<CCTK_REAL,3>& coord_upper); - + template void WriteASCII (ostream& os, const gdata<3>* const gfdata, |