diff options
Diffstat (limited to 'Carpet')
-rw-r--r-- | Carpet/CarpetIOASCII/doc/documentation.tex | 160 | ||||
-rw-r--r-- | Carpet/CarpetIOASCII/src/ioascii.cc | 600 | ||||
-rw-r--r-- | Carpet/CarpetIOASCII/src/ioascii.hh | 3 |
3 files changed, 355 insertions, 408 deletions
diff --git a/Carpet/CarpetIOASCII/doc/documentation.tex b/Carpet/CarpetIOASCII/doc/documentation.tex index da08f340a..cc16fa456 100644 --- a/Carpet/CarpetIOASCII/doc/documentation.tex +++ b/Carpet/CarpetIOASCII/doc/documentation.tex @@ -1,67 +1,3 @@ -% *======================================================================* -% Cactus Thorn template for ThornGuide documentation -% Author: Ian Kelley -% Date: Sun Jun 02, 2002 -% -% Thorn documentation in the latex file doc/documentation.tex -% will be included in ThornGuides built with the Cactus make system. -% The scripts employed by the make system automatically include -% pages about variables, parameters and scheduling parsed from the -% relevent thorn CCL files. -% -% This template contains guidelines which help to assure that your -% documentation will be correctly added to ThornGuides. More -% information is available in the Cactus UsersGuide. -% -% Guidelines: -% - Do not change anything before the line -% % STARTx CACTUS THORNGUIDE", -% except for filling in the title, author, date etc. fields. -% - Each of these fields should only be on ONE line. -% - Author names should be sparated with a \\ or a comma -% - You can define your own macros are OK, but they must appear after -% the STARTx CACTUS THORNGUIDE line, and do not redefine standard -% latex commands. -% - To avoid name clashes with other thorns, 'labels', 'citations', -% 'references', and 'image' names should conform to the following -% convention: -% ARRANGEMENT_THORN_LABEL -% For example, an image wave.eps in the arrangement CactusWave and -% thorn WaveToyC should be renamed to CactusWave_WaveToyC_wave.eps -% - Graphics should only be included using the graphix package. -% More specifically, with the "includegraphics" command. Do -% not specify any graphic file extensions in your .tex file. This -% will allow us (later) to create a PDF version of the ThornGuide -% via pdflatex. | -% - References should be included with the latex "bibitem" command. -% - use \begin{abstract}...\end{abstract} instead of \abstract{...} -% - For the benefit of our Perl scripts, and for future extensions, -% please use simple latex. -% -% *======================================================================* -% -% Example of including a graphic image: -% \begin{figure}[ht] -% \begin{center} -% \includegraphics[width=6cm]{MyArrangement_MyThorn_MyFigure} -% \end{center} -% \caption{Illustration of this and that} -% \label{MyArrangement_MyThorn_MyLabel} -% \end{figure} -% -% Example of using a label: -% \label{MyArrangement_MyThorn_MyLabel} -% -% Example of a citation: -% \cite{MyArrangement_MyThorn_Author99} -% -% Example of including a reference -% \bibitem{MyArrangement_MyThorn_Author99} -% {J. Author, {\em The Title of the Book, Journal, or periodical}, 1 (1999), -% 1--16. {\tt http://www.nowhere.com/}} -% -% *======================================================================* - \documentclass{article} % Use the Cactus ThornGuide style file @@ -73,32 +9,31 @@ \begin{document} % The author of the documentation -\author{Erik Schnetter \textless schnetter@aei.mpg.de\textgreater} +\author{Erik Schnetter \textless schnetter@aei.mpg.de\textgreater\\ + Thomas Radke \textless tradke@aei.mpg.de\textgreater} % The title of the document (not necessarily the name of the Thorn) \title{CarpetIOASCII} % the date your document was last changed, if your document is in CVS, % please use: -\date{October 16, 2002} +\date{November 20, 2005} \maketitle % Do not delete next line % START CACTUS THORNGUIDE -% Add all definitions used in this documentation here -% \def\mydef etc +\newcommand{\ThisThorn}{{\it CarpetIOASCII}} -% Add an abstract for this thorn's documentation +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{abstract} This thorn reproduces thorn IOASCII from arrangement CactusBase but is specifically for the driver thorn Carpet. \end{abstract} -% The following sections are suggestive only. -% Remove them or add your own. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Introduction} This thorn provides ASCII output of data in 1, 2 or 3 dimensions. It @@ -113,6 +48,82 @@ standard IOASCII thorn. Information about, e.g., the refinement level and the index position of the output are also given. All the output can be visualized using gnuplot. +The \ThisThorn\ I/O methods can output any type of CCTK grid variables +(grid scalars, grid functions, and grid arrays of arbitrary dimension); +data is written into separate files named {\tt "<varname>.asc"}. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{\ThisThorn\ Parameters} + +The most important parameters to control the \ThisThorn\ I/O methods are listed +below. Many parameters come as a set of four individuals, one for each +I/O method, controlling 0, 1, 2, or 3-dimensional ASCII output respectively. + +\begin{itemize} + \item {\tt IOASCII::out[0-3]D\_every} (steerable)\\ + How often to do periodic \ThisThorn\ output. If this parameter is set + in the parameter file, it will override the setting of the shared + {\tt IO::out\_every} parameter. The output frequency can also be set + for individual variables using the {\tt out\_every} option in an + option string appended to the {\tt IOASCII::out[0-3]D\_vars} parameter. + + \item {\tt IOASCII::out[0-3]D\_dt} (steerable)\\ + output in intervals of that much coordinate time (overwrites + {\tt IO::out\_dt}) + + \item {\tt IOASCII::out[0-3]D\_criterion} (steerable)\\ + criterion to select output intervals (overwrites + {\tt IO::out\_criterion}) + + \item {\tt IOASCII::out[0-3]D\_vars} (steerable)\\ + The list of variables to output using the \ThisThorn\ I/O method. + The variables must be given by their fully qualified variable or group + name. The special keyword {\it all} requests \ThisThorn\ output for + all variables. Multiple names must be separated by whitespaces. + + Each group/variable name can have an option string attached in which you + can specify a different output frequency for that individual variable, + or a set of individual refinement levels to be output, eg. +\begin{verbatim} + IOASCII::out1D_vars = "wavetoy::phi{ out_every = 4 refinement_levels = { 1 2 } }" +\end{verbatim} + + \item {\tt IOASCII::out[0-3]D\_dir}\\ + The directory in which to place the \ThisThorn\ output files. + If the directory doesn't exist at startup it will be created.\\ + If this parameter is set to an empty string \ThisThorn\ output will go + to the standard output directory as specified in {\tt IO::out\_dir}. + + \item {\tt IOASCII::out\_precision} (steerable)\\ + How many digits to output floating-point numbers with (overwrites + {\tt IO::out\_precision}). + + \item {\tt IOASCII::one\_file\_per\_group}\\ + Write one output file per group instead of per variable. + +\end{itemize} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Using the flesh I/O API to produce ASCII output} + +Periodic output of grid variables is usually specified via I/O parameters +in the parameter file and then automatically triggered by the flesh scheduler +at each iteration step after analysis. If output should also be triggered +at a different time, one can do that from within an application thorn by +invoking one of the {\tt CCTK\_OutputVar*()} I/O routines provided +by the flesh I/O API (see chapter B8.2 ``IO'' in the Cactus Users Guide). +In this case, the application thorn routine which calls {\tt CCTK\_OutputVar*()} +must be scheduled in level mode. + +If output for a variable is required also for intermediate timesteps +this can be achieved by calling {\tt CCTK\_OutputVarAs*()} with a different +{\tt alias} name; output for the same variable is then written into +different ASCII files based on the {\tt alias} argument. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Utilities} \label{sec:utils} @@ -139,9 +150,10 @@ filename, where the number in the output filename is given by the refinement level. -\begin{thebibliography}{9} - -\end{thebibliography} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%\begin{thebibliography}{9} +% +%\end{thebibliography} % Do not delete next line % END CACTUS THORNGUIDE diff --git a/Carpet/CarpetIOASCII/src/ioascii.cc b/Carpet/CarpetIOASCII/src/ioascii.cc index ae08538e3..4ff377f65 100644 --- a/Carpet/CarpetIOASCII/src/ioascii.cc +++ b/Carpet/CarpetIOASCII/src/ioascii.cc @@ -6,18 +6,13 @@ #include <cstdlib> #include <cstring> -#include <sys/stat.h> -#include <sys/types.h> - #include <fstream> #include <iomanip> +#include <map> #include <ostream> #include <sstream> -#include <string> -#include <vector> #include "cctk.h" -#include "cctk_Functions.h" #include "cctk_Parameters.h" #include "util_Network.h" #include "util_Table.h" @@ -25,13 +20,6 @@ #include "CactusBase/IOUtil/src/ioGH.h" #include "CactusBase/IOUtil/src/ioutil_Utils.h" -#include "data.hh" -#include "dist.hh" -#include "gdata.hh" -#include "gf.hh" -#include "ggf.hh" -#include "vect.hh" - #include "carpet.hh" #include "ioascii.hh" @@ -50,7 +38,7 @@ namespace CarpetIOASCII { using namespace std; using namespace Carpet; - void SetFlag (int index, const char* optstring, void* arg); + static void GetVarIndex (int vindex, const char* optstring, void* arg); @@ -125,10 +113,7 @@ namespace CarpetIOASCII { // Definition of static members template<int outdim> const char* IOASCII<outdim>::my_out_dir; template<int outdim> char* IOASCII<outdim>::my_out_vars; - template<int outdim> vector<bool> IOASCII<outdim>::do_truncate; template<int outdim> vector<ioRequest*> IOASCII<outdim>::requests; - template<int outdim> - vector<vector<vector<int> > > IOASCII<outdim>::last_output; static bool stop_on_parse_errors = false; @@ -178,20 +163,9 @@ namespace CarpetIOASCII { // Truncate all files if this is not a restart const int numvars = CCTK_NumVars (); - do_truncate.resize (numvars, true); requests.resize (numvars); - // No iterations have yet been output - last_output.resize(mglevels); - for (int ml=0; ml<mglevels; ++ml) { - last_output.at(ml).resize(maxreflevels); - for (int rl=0; rl<maxreflevels; ++rl) { - last_output.at(ml).at(rl).resize(CCTK_NumVars(), -1); - } - } - - - /* create the output directory */ + // create the output directory my_out_dir = GetStringParameter("out%dD_dir"); if (CCTK_EQUALS (my_out_dir, "")) { my_out_dir = out_dir; @@ -230,12 +204,12 @@ namespace CarpetIOASCII { DECLARE_CCTK_PARAMETERS; // re-parse the 'IOASCII::out%d_vars' parameter if it has changed - char name[11]; - sprintf (name, "out%dD_vars", outdim); const char* const out_vars = GetStringParameter("out%dD_vars"); - if (strcmp (out_vars, my_out_vars)) { - IOUtil_ParseVarsForOutput (cctkGH, CCTK_THORNSTRING, name, + ostringstream parameter_name; + parameter_name << "IOASCII::out" << outdim << "D_vars"; + IOUtil_ParseVarsForOutput (cctkGH, CCTK_THORNSTRING, + parameter_name.str().c_str(), stop_on_parse_errors, out_vars, -1, &requests[0]); @@ -284,62 +258,200 @@ namespace CarpetIOASCII { template<int outdim> int IOASCII<outdim> + ::TimeToOutput (const cGH* const cctkGH, const int vindex) + { + DECLARE_CCTK_ARGUMENTS; + DECLARE_CCTK_PARAMETERS; + + assert (vindex >= 0 and vindex < CCTK_NumVars ()); + + if (CCTK_GroupTypeFromVarI (vindex) != CCTK_GF and not do_global_mode) { + return 0; + } + + CheckSteerableParameters (cctkGH); + + // check if output for this variable was requested + if (not requests[vindex]) { + return (0); + } + + // check whether this refinement level should be output + if (not (requests[vindex]->refinement_levels & (1 << reflevel))) { + return (0); + } + + // check if output for this variable was requested individually + // by a "<varname>{ out_every = <number> }" option string + // this will overwrite the output criterion setting + const char* myoutcriterion = GetStringParameter("out%dD_criterion"); + if (CCTK_EQUALS(myoutcriterion, "default")) { + myoutcriterion = out_criterion; + } + if (requests[vindex]->out_every >= 0) { + myoutcriterion = "divisor"; + } + + if (CCTK_EQUALS (myoutcriterion, "never")) { + return (0); + } + + // check whether to output at this iteration + bool output_this_iteration = false; + + if (CCTK_EQUALS (myoutcriterion, "iteration")) { + int myoutevery = GetIntParameter("out%dD_every"); + if (myoutevery == -2) { + myoutevery = out_every; + } + if (myoutevery > 0) { + if (cctk_iteration == this_iteration[outdim]) { + // we already decided to output this iteration + output_this_iteration = true; + } else if (cctk_iteration + >= last_output_iteration[outdim] + myoutevery) { + // it is time for the next output + output_this_iteration = true; + last_output_iteration[outdim] = cctk_iteration; + this_iteration[outdim] = cctk_iteration; + } + } + } else if (CCTK_EQUALS (myoutcriterion, "divisor")) { + int myoutevery = GetIntParameter("out%dD_every"); + if (myoutevery == -2) { + myoutevery = out_every; + } + if (requests[vindex]->out_every >= 0) { + myoutevery = requests[vindex]->out_every; + } + if (myoutevery > 0 and (cctk_iteration % myoutevery) == 0) { + // we already decided to output this iteration + output_this_iteration = true; + } + } else if (CCTK_EQUALS (myoutcriterion, "time")) { + CCTK_REAL myoutdt = GetRealParameter("out%dD_dt"); + if (myoutdt == -2) { + myoutdt = out_dt; + } + if (myoutdt == 0 or cctk_iteration == this_iteration[outdim]) { + output_this_iteration = true; + } else if (myoutdt > 0 and (cctk_time / cctk_delta_time + >= (last_output_time[outdim] + myoutdt) / cctk_delta_time - 1.0e-12)) { + // it is time for the next output + output_this_iteration = true; + last_output_time[outdim] = cctk_time; + this_iteration[outdim] = cctk_iteration; + } + } // select output criterion + + return output_this_iteration ? 1 : 0; + } + + + + template<int outdim> + int IOASCII<outdim> ::OutputVarAs (const cGH* const cctkGH, const char* const varname, const char* const alias) { + DECLARE_CCTK_ARGUMENTS; DECLARE_CCTK_PARAMETERS; + int vindex = -1; + + if (CCTK_TraverseString (varname, GetVarIndex, &vindex, CCTK_VAR) < 0) { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "error while parsing variable name '%s' (alias name '%s')", + varname, alias); + return (-1); + } + + if (vindex < 0) { + return (-1); + } + if (! is_level_mode()) { CCTK_WARN (1, "OutputVarAs must be called in level mode"); return -1; } assert (is_level_mode()); - const int n = CCTK_VarIndex(varname); - if (n<0) { + const int group = CCTK_GroupIndexFromVarI (vindex); + assert (group >= 0); + const int vindex0 = CCTK_FirstVarIndexI (group); + assert (vindex0 >= 0 and vindex >= vindex0); + const int var = vindex - vindex0; + const int num_tl = CCTK_NumTimeLevelsFromVarI (vindex); + assert (num_tl >= 1); + + const int grouptype = CCTK_GroupTypeI (group); + if (grouptype != CCTK_GF) { + assert (do_global_mode); + } + const int rl = grouptype == CCTK_GF ? reflevel : 0; + + const int groupdim = CCTK_GroupDimI(group); + if (outdim > groupdim) { CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Variable \"%s\" does not exist", varname); + "Cannot produce %dD ASCII output file '%s' for variable '%s' " + "because it has only %d dimensions", + outdim, alias, varname, groupdim); return -1; } - assert (n>=0 && n<CCTK_NumVars()); - const int group = CCTK_GroupIndexFromVarI (n); - assert (group>=0 && group<(int)Carpet::arrdata.size()); - const int n0 = CCTK_FirstVarIndexI(group); - assert (n0>=0 && n0<CCTK_NumVars()); - const int var = n - n0; - assert (var>=0 && var<CCTK_NumVarsInGroupI(group)); - const int num_tl = CCTK_NumTimeLevelsFromVarI(n); - assert (num_tl>=1); // Check for storage - if (! CCTK_QueryGroupStorageI(cctkGH, group)) { + if (not CCTK_QueryGroupStorageI (cctkGH, group)) { CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Cannot output variable \"%s\" because it has no storage", + "Cannot output variable '%s' because it has no storage", varname); return 0; } - const int grouptype = CCTK_GroupTypeI(group); - switch (grouptype) { - case CCTK_SCALAR: - case CCTK_ARRAY: - assert (do_global_mode); - break; - case CCTK_GF: - /* do nothing */ - break; - default: - assert (0); + // get the default I/O request for this variable + ioRequest* request = requests[vindex]; + if (not request) { + request = IOUtil_DefaultIORequest (cctkGH, vindex, 1); } - const int rl = grouptype == CCTK_GF ? reflevel : 0; - const int groupdim = CCTK_GroupDimI(group); - if (outdim > groupdim) { - CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Cannot produce %dD ASCII output file \"%s\" for variable \"%s\" because it has only %d dimensions", outdim, alias, varname, groupdim); - return -1; + // check if the file has been created already + typedef std::map<string, vector<vector<vector<int> > > > filelist; + static filelist created_files; + string basefilename (my_out_dir); + basefilename.append (alias); + filelist::iterator thisfile = created_files.find (basefilename); + bool is_new_file = thisfile == created_files.end(); + if (is_new_file) { + int const numvars = CCTK_NumVars (); + vector<vector<vector<int> > > last_outputs; // [ml][rl][var] + last_outputs.resize (mglevels); + for (int ml = 0; ml < mglevels; ++ml) { + last_outputs[ml].resize (maxreflevels); + for (int rl = 0; rl < maxreflevels; ++rl) { + last_outputs[ml][rl].resize (numvars, cctk_iteration - 1); + } + } + thisfile = created_files.insert (thisfile, + filelist::value_type (basefilename, + last_outputs)); + assert (thisfile != created_files.end()); + } + is_new_file &= IO_TruncateOutputFiles (cctkGH); + + // check if this variable has been output already during this iteration + int& last_output = thisfile->second.at(mglevel).at(reflevel).at(vindex); + if (last_output == cctk_iteration) { + // Has already been output during this iteration + char* varname = CCTK_FullName (vindex); + CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING, + "Skipping output for variable '%s', because this variable " + "has already been output during the current iteration -- " + "probably via a trigger during the analysis stage", + varname); + free (varname); + return (0); } - assert (outdim <= groupdim); + assert (last_output < cctk_iteration); + last_output = cctk_iteration; // Get grid hierarchy extentsion from IOUtil const ioGH * const iogh = (const ioGH *)CCTK_GHExtension (cctkGH, "IO"); @@ -502,11 +614,11 @@ namespace CarpetIOASCII { // Invent a file name ostringstream filenamebuf; + filenamebuf << my_out_dir << "/" << alias << "."; + if (maps > 1) { + filenamebuf << Carpet::map << "."; + } if (new_filename_scheme) { - filenamebuf << my_out_dir << "/" << alias << "."; - if (maps > 1) { - filenamebuf << Carpet::map << "."; - } for (int d=0; d<outdim; ++d) { const char* const coords = "xyz"; filenamebuf << coords[dirs[d]]; @@ -523,10 +635,6 @@ namespace CarpetIOASCII { // } filenamebuf << ".asc"; } else { - filenamebuf << my_out_dir << "/" << alias << "."; - if (maps > 1) { - filenamebuf << Carpet::map << "."; - } for (int d=0; d<outdim; ++d) { assert (dirs[d]>=0 && dirs[d]<3); const char* const coords = "xyz"; @@ -539,93 +647,82 @@ namespace CarpetIOASCII { string filenamestr = filenamebuf.str(); const char* const filename = filenamestr.c_str(); + + // Open the file + file.open (filename, ios::out | + (is_new_file ? ios::trunc : ios::app)); + if (! file.good()) { + CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, + "Could not open output file '%s' for variable '%s'", + filename, varname); + } // If this is the first time, then write a nice header - if (do_truncate.at(n)) { - struct stat fileinfo; - if (IO_TruncateOutputFiles (cctkGH) - || stat(filename, &fileinfo)!=0) { - file.open (filename, ios::out | ios::trunc); - if (! file.good()) { - CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, - "Could not open output file \"%s\" for variable \"%s\"", - filename, varname); - } - assert (file.good()); - { - bool want_date = false; - bool want_parfilename = false; - bool want_other = false; - if (CCTK_EQUALS (out_fileinfo, "none")) { - // do nothing - } else if (CCTK_EQUALS (out_fileinfo, "axis labels")) { - // do nothing - } else if (CCTK_EQUALS (out_fileinfo, "creation date")) { - want_date = true; - } else if (CCTK_EQUALS (out_fileinfo, "parameter filename")) { - want_parfilename = true; - } else if (CCTK_EQUALS (out_fileinfo, "all")) { - want_date = true; - want_parfilename = true; - want_other = true; - } else { - CCTK_WARN (0, "internal error"); - } - file << "# "<< outdim << "D ASCII output created by CarpetIOASCII" << endl; - if (want_date) { - char run_host [1000]; - Util_GetHostName (run_host, sizeof run_host); + if (is_new_file) { + bool want_date = false; + bool want_parfilename = false; + bool want_other = false; + if (CCTK_EQUALS (out_fileinfo, "none")) { + // do nothing + } else if (CCTK_EQUALS (out_fileinfo, "axis labels")) { + // do nothing + } else if (CCTK_EQUALS (out_fileinfo, "creation date")) { + want_date = true; + } else if (CCTK_EQUALS (out_fileinfo, "parameter filename")) { + want_parfilename = true; + } else if (CCTK_EQUALS (out_fileinfo, "all")) { + want_date = true; + want_parfilename = true; + want_other = true; + } else { + CCTK_WARN (0, "internal error"); + } + file << "# "<< outdim << "D ASCII output created by CarpetIOASCII" << endl; + if (want_date) { + char run_host [1000]; + Util_GetHostName (run_host, sizeof run_host); #if 0 - char const * const run_user = CCTK_RunUser(); + char const * const run_user = CCTK_RunUser(); #else - char const * const run_user = getenv ("USER"); + char const * const run_user = getenv ("USER"); #endif - char run_date [1000]; - Util_CurrentDate (sizeof run_date, run_date); - char run_time [1000]; - Util_CurrentTime (sizeof run_time, run_time); - file << "# created on " << run_host - << " by " << run_user - << " on " << run_date - << " at " << run_time << endl; - } - if (want_parfilename) { - char parameter_filename [10000]; - CCTK_ParameterFilename (sizeof parameter_filename, parameter_filename); - file << "# parameter filename: \"" << parameter_filename << "\"" << endl; - } - if (want_other) { - if (CCTK_IsFunctionAliased ("UniqueSimulationID")) { - char const * const job_id - = (char const *) UniqueSimulationID (cctkGH); - file << "# Simulation ID: " << job_id << endl; - } - } - file << "#" << endl; - } - if (one_file_per_group) { - char* groupname = CCTK_GroupNameFromVarI(n); - file << "# " << groupname; - free (groupname); - } else { - file << "# " << varname; + char run_date [1000]; + Util_CurrentDate (sizeof run_date, run_date); + char run_time [1000]; + Util_CurrentTime (sizeof run_time, run_time); + file << "# created on " << run_host + << " by " << run_user + << " on " << run_date + << " at " << run_time << endl; + + if (want_parfilename) { + char parameter_filename [10000]; + CCTK_ParameterFilename (sizeof parameter_filename, parameter_filename); + file << "# parameter filename: \"" << parameter_filename << "\"" << endl; } - for (int d=0; d<outdim; ++d) { - file << " " << "xyz"[dirs[d]]; + if (want_other) { + if (CCTK_IsFunctionAliased ("UniqueSimulationID")) { + char const * const job_id + = (char const *) UniqueSimulationID (cctkGH); + file << "# Simulation ID: " << job_id << endl; + } } - file << " (" << alias << ")" << endl; file << "#" << endl; - assert (file.good()); } - } - - // Open the file - if (! file.is_open()) { - file.open (filename, ios::out | ios::app); - assert (file.good()); + if (one_file_per_group) { + char* groupname = CCTK_GroupNameFromVarI(vindex); + file << "# " << groupname; + free (groupname); + } else { + file << "# " << varname; + } + for (int d=0; d<outdim; ++d) { + file << " " << "xyz"[dirs[d]]; + } + file << " (" << alias << ")" << endl; + file << "#" << endl; } file << setprecision(out_precision); - assert (file.good()); } // if on the root processor @@ -637,8 +734,7 @@ namespace CarpetIOASCII { int const ierr = CCTK_GroupData (group, & groupdata); assert (! ierr); if (groupdata.disttype != CCTK_DISTRIB_CONSTANT - or component == 0) - { + or component == 0) { const ggf* const ff = arrdata.at(group).at(Carpet::map).data.at(var); @@ -739,7 +835,7 @@ namespace CarpetIOASCII { datas.resize (1); datas.at(0) = data; } - WriteASCII (file, datas, ext, n, cctkGH->cctk_iteration, + WriteASCII (file, datas, ext, vindex, cctkGH->cctk_iteration, offset1, dirs, rl, mglevel, Carpet::map, component, tl, coord_time, coord_lower, coord_upper); @@ -790,9 +886,6 @@ namespace CarpetIOASCII { } while (! done); // all directions - // Don't truncate again - do_truncate.at(n) = false; - return 0; } @@ -800,188 +893,27 @@ namespace CarpetIOASCII { 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); - if (grouptype != CCTK_GF and not do_global_mode) { - return 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; - } - if (myoutevery <= 0) { - // output is disabled - output_this_iteration = false; - } else if (cctk_iteration == this_iteration[outdim]) { - // we already decided to output this iteration - output_this_iteration = true; - } else if (cctk_iteration - >= last_output_iteration[outdim] + myoutevery) { - // it is time for the next output - output_this_iteration = true; - last_output_iteration[outdim] = cctk_iteration; - this_iteration[outdim] = cctk_iteration; - } else { - // 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; - } - if (myoutevery <= 0) { - // output is disabled - output_this_iteration = false; - } else if (cctk_iteration % myoutevery == 0) { - // we already decided to output this iteration - output_this_iteration = true; - } 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; - } - if (myoutdt < 0) { - // output is disabled - output_this_iteration = false; - } else if (myoutdt == 0) { - // output all iterations - output_this_iteration = true; - } else if (cctk_iteration == this_iteration[outdim]) { - // we already decided to output this iteration - output_this_iteration = true; - } else if (cctk_time / cctk_delta_time - >= (last_output_time[outdim] + myoutdt) / cctk_delta_time - 1.0e-12) { - // it is time for the next output - output_this_iteration = true; - last_output_time[outdim] = cctk_time; - this_iteration[outdim] = cctk_iteration; - } else { - // 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) - { - int abort_on_error = output_variables_iteration < 0 && - strict_io_parameter_check; - CCTK_VWarn (abort_on_error ? 0 : 1, __LINE__, __FILE__,CCTK_THORNSTRING, - "error while parsing parameter 'IOASCII::out%dD_vars'", - outdim); - } - - 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); - CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING, - "Skipping output for variable \"%s\", because this variable " - "has already been output during the current iteration -- " - "probably via a trigger during the analysis stage", - varname); - 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 cctkGH, const int vindex) { DECLARE_CCTK_PARAMETERS; - assert (vindex>=0 && vindex<CCTK_NumVars()); + assert (vindex >= 0 and vindex < CCTK_NumVars ()); - int retval; + char* const fullname = CCTK_FullName(vindex); + int retval; if (one_file_per_group) { - - char* const fullname = CCTK_FullName(vindex); - int const gindex = CCTK_GroupIndexFromVarI(vindex); - char* const groupname = CCTK_GroupName(gindex); - for (char* p=groupname; *p; ++p) *p=(char)tolower(*p); - retval = OutputVarAs (cctkGH, fullname, groupname); - free (fullname); - free (groupname); - - int const firstvar = CCTK_FirstVarIndexI(gindex); - int const numvars = CCTK_NumVarsInGroupI(gindex); - for (int n=firstvar; n<firstvar+numvars; ++n) { - last_output.at(mglevel).at(reflevel).at(n) = cctkGH->cctk_iteration; - } - + char* alias = CCTK_GroupNameFromVarI (vindex); + for (char* p = alias; *p; ++p) *p = (char) tolower (*p); + retval = OutputVarAs (cctkGH, fullname, alias); + free (alias); } else { - - char* const fullname = CCTK_FullName(vindex); - char const* varname = CCTK_VarName(vindex); - retval = OutputVarAs (cctkGH, fullname, varname); - free (fullname); - - last_output.at(mglevel).at(reflevel).at(vindex) = cctkGH->cctk_iteration; - + const char* const alias = CCTK_VarName (vindex); + retval = OutputVarAs (cctkGH, fullname, alias); } + free (fullname); + return retval; } @@ -1158,11 +1090,17 @@ namespace CarpetIOASCII { - void SetFlag (int index, const char* optstring, void* arg) + static void GetVarIndex (int vindex, const char* optstring, void* arg) { - optstring = optstring; - vector<bool>& flags = *(vector<bool>*)arg; - flags.at(index) = true; + if (optstring) { + char *fullname = CCTK_FullName (vindex); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "Option string '%s' will be ignored for ASCII output of " + "variable '%s'", optstring, fullname); + free (fullname); + } + + *((int *) arg) = vindex; } diff --git a/Carpet/CarpetIOASCII/src/ioascii.hh b/Carpet/CarpetIOASCII/src/ioascii.hh index 73489e29c..2af02ce4c 100644 --- a/Carpet/CarpetIOASCII/src/ioascii.hh +++ b/Carpet/CarpetIOASCII/src/ioascii.hh @@ -27,9 +27,6 @@ namespace CarpetIOASCII { // list of variables to output static char* my_out_vars; - // Do truncate the output files for a variable - static vector<bool> do_truncate; - // Last iteration on which a refinement level of a variable was // output (INT_MIN for none) static vector<vector<vector<int> > > last_output; // [ml][rl][var] |