aboutsummaryrefslogtreecommitdiff
path: root/Carpet
diff options
context:
space:
mode:
authorThomas Radke <tradke@aei.mpg.de>2005-11-20 18:28:00 +0000
committerThomas Radke <tradke@aei.mpg.de>2005-11-20 18:28:00 +0000
commit4dcf17df6ce2e7e57deb2eb8596aec30dc10b251 (patch)
treea10d580de2d1ebd96602663cd816df66c2d33709 /Carpet
parent320aa358a82ab670d312a0a05d956bfaef2a02ea (diff)
CarpetIOASCII: make use of IOUtil's infrastructure to implement new features and
fix a bug As CarpetIOHDF5, CarpetIOASCII now provides option strings to variable/group names in IOASCII::out[0-3]D_vars parameters. Currently supported options are 'out_every' and 'refinement_levels' to specify individual output frequencies and refinement levels. See the thorn documentation for details. Also fixed was a bug in output file handling for the case when both periodic and unconditional output (via CCTK_OutputVarAsByMethod()) into separate files were requested: each output file is now properly truncated. darcs-hash:20051120182851-776a0-2c3224274cca325a8e1e0a92df25a55e87474763.gz
Diffstat (limited to 'Carpet')
-rw-r--r--Carpet/CarpetIOASCII/doc/documentation.tex160
-rw-r--r--Carpet/CarpetIOASCII/src/ioascii.cc600
-rw-r--r--Carpet/CarpetIOASCII/src/ioascii.hh3
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]