aboutsummaryrefslogtreecommitdiff
path: root/CarpetDev/CarpetIOF5/src/iof5.cc
diff options
context:
space:
mode:
Diffstat (limited to 'CarpetDev/CarpetIOF5/src/iof5.cc')
-rw-r--r--CarpetDev/CarpetIOF5/src/iof5.cc315
1 files changed, 315 insertions, 0 deletions
diff --git a/CarpetDev/CarpetIOF5/src/iof5.cc b/CarpetDev/CarpetIOF5/src/iof5.cc
new file mode 100644
index 000000000..8b93054d6
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/iof5.cc
@@ -0,0 +1,315 @@
+#include <cctk.h>
+#include <cctk_Arguments.h>
+#include <cctk_Parameters.h>
+#include <util_Table.h>
+
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+#include <iomanip>
+#include <iostream>
+#include <limits>
+#include <sstream>
+#include <string>
+
+#include <hdf5.h>
+#include <iof5.hh>
+
+#include "CactusBase/IOUtil/src/ioutil_CheckpointRecovery.h"
+
+
+
+namespace CarpetIOF5 {
+
+ using namespace std;
+ using namespace Carpet;
+
+
+
+ // Checkpointing state
+ static int last_checkpoint_iteration = -1;
+
+
+
+ // Scheduled startup routine
+ int CarpetIOF5_Startup ()
+ {
+ CCTK_RegisterBanner ("AMR F5 I/O provided by CarpetIOF5");
+
+ int const GHExtension = CCTK_RegisterGHExtension (CCTK_THORNSTRING);
+ CCTK_RegisterGHExtensionSetupGH (GHExtension, SetupGH);
+
+ return 0;
+ }
+
+ // Registered GH extension setup routine
+ void* SetupGH (tFleshConfig* const fleshconfig,
+ int const convLevel, cGH* const cctkGH)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ // register I/O method
+ int const IOMethod = CCTK_RegisterIOMethod ("IOF5");
+ CCTK_RegisterIOMethodOutputGH (IOMethod, OutputGH );
+ CCTK_RegisterIOMethodTimeToOutput (IOMethod, TimeToOutput );
+ CCTK_RegisterIOMethodTriggerOutput (IOMethod, TriggerOutput);
+ CCTK_RegisterIOMethodOutputVarAs (IOMethod, OutputVarAs );
+
+ // there no actual extension data structure
+ return NULL;
+ }
+
+ // Scheduled initialisation routine
+ void CarpetIOF5_Init (CCTK_ARGUMENTS)
+ {
+ DECLARE_CCTK_ARGUMENTS;
+
+ *this_iteration = -1;
+ *next_output_iteration = 0;
+
+ last_checkpoint_iteration = cctk_iteration;
+ }
+
+
+
+ // Callbacks for CarpetIOHDF5's I/O method
+
+ struct callback_arg_t {
+ cGH const* cctkGH;
+ };
+ void do_output (int const vindex,
+ char const* const optstring,
+ void* const callback_arg);
+
+ int OutputGH (cGH const* const cctkGH)
+ {
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
+
+ static Carpet::Timer timer ("F5::OutputGH");
+ timer.start();
+
+ callback_arg_t callback_arg;
+ callback_arg.cctkGH = cctkGH;
+ CCTK_TraverseString (out_vars, do_output, &callback_arg, CCTK_GROUP_OR_VAR);
+
+ timer.stop(0);
+
+ return 0;
+ }
+
+ void do_output (int const vindex,
+ char const* const optstring,
+ void* const callback_arg_)
+ {
+ callback_arg_t& callback_arg =
+ * static_cast<callback_arg_t*>(callback_arg_);
+ cGH const* const cctkGH = callback_arg.cctkGH;
+ if (TimeToOutput (cctkGH, vindex)) {
+ TriggerOutput (cctkGH, vindex);
+ }
+ }
+
+ int TimeToOutput (cGH const* const cctkGH, int const vindex)
+ {
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
+
+ int const numvars = CCTK_NumVars();
+ assert (vindex>=0 and vindex<numvars);
+
+ // Output only in global mode
+ if (not do_global_mode) return 0;
+
+ // whether to output at this iteration
+ bool output_this_iteration = false;
+
+ int const my_out_every = out_every == -2 ? IO_out_every : out_every;
+ if (my_out_every > 0) {
+ if (*this_iteration == cctk_iteration) {
+ // we already decided to output this iteration
+ output_this_iteration = true;
+ } else if (cctk_iteration >= *next_output_iteration) {
+ // it is time for the next output
+ output_this_iteration = true;
+ *this_iteration = cctk_iteration;
+ *next_output_iteration = cctk_iteration + my_out_every;
+ }
+ }
+
+ return output_this_iteration ? 1 : 0;
+ }
+
+ int TriggerOutput (cGH const* const cctkGH, int const vindex)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ 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=tolower(*p);
+ int const retval = OutputVarAs (cctkGH, fullname, groupname);
+ free (groupname);
+ free (fullname);
+
+ return retval;
+ }
+
+ int OutputVarAs (cGH const* const cctkGH,
+ const char* const varname, const char* const alias)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ assert (is_level_mode());
+ BEGIN_GLOBAL_MODE(cctkGH) {
+ DECLARE_CCTK_ARGUMENTS;
+
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "F5::OutputVarAs: iteration=%d", cctk_iteration);
+
+
+
+ // We don't know how to open multiple files yet
+ assert (CCTK_EQUALS (file_content, "everything"));
+
+ // Open file
+ static bool first_time = true;
+
+ // The file name doesn't matter since we currently write
+ // everything into a single file
+ int const vindex = CCTK_VarIndex (varname);
+ assert (vindex >= 0);
+ string const basename = generate_basename (cctkGH, vindex);
+ int const myproc = CCTK_MyProc(cctkGH);
+ int const proc = myproc;
+ string const name = create_filename (cctkGH, basename, proc, first_time);
+
+ indent_t indent;
+ cout << indent << "process=" << proc << "\n";
+
+ bool const truncate_file = first_time and IO_TruncateOutputFiles(cctkGH);
+ hid_t const file =
+ truncate_file ?
+ H5Fcreate (name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT) :
+ H5Fopen (name.c_str(), H5F_ACC_RDWR , H5P_DEFAULT);
+ assert (file >= 0);
+ first_time = false;
+
+ vector<bool> output_var(CCTK_NumVars());
+ output_var.at(vindex) = true;
+ output (cctkGH, file, output_var, false);
+
+ // Close file
+ herr_t const herr = H5Fclose (file);
+ assert (not herr);
+
+ } END_GLOBAL_MODE;
+
+ return 0; // no error
+ }
+
+
+
+ // Checkpointing
+
+ void Checkpoint (cGH const* const cctkGH, int const called_from)
+ {
+ assert (is_global_mode());
+
+ // generate filenames for both the temporary and real checkpoint
+ // files
+ int const ioproc = CCTK_MyProc(cctkGH);
+ int const parallel_io = 1;
+ char* const filename =
+ IOUtil_AssembleFilename (cctkGH, NULL, "", ".f5",
+ called_from, ioproc, not parallel_io);
+ char* const tempname =
+ IOUtil_AssembleFilename (cctkGH, NULL, ".tmp", ".f5",
+ called_from, ioproc, not parallel_io);
+
+ hid_t const file =
+ H5Fcreate (tempname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ assert (file >= 0);
+
+ vector<bool> output_var(CCTK_NumVars());
+ for (int gindex=0; gindex<CCTK_NumGroups(); ++gindex) {
+ // only checkpoint groups with storage
+ if (CCTK_QueryGroupStorageI(cctkGH, gindex) <= 0) continue;
+ if (CCTK_NumVarsInGroupI(gindex) == 0) continue;
+
+ // do not checkpoint groups with a "checkpoint=no" tag
+ cGroup gdata;
+ CCTK_GroupData (gindex, &gdata);
+ int const len =
+ Util_TableGetString (gdata.tagstable, 0, NULL, "checkpoint");
+ if (len > 0) {
+ char buf[1000];
+ Util_TableGetString (gdata.tagstable, sizeof buf, buf, "checkpoint");
+ if (CCTK_EQUALS(buf, "no")) continue;
+ assert (CCTK_EQUALS(buf, "yes"));
+ }
+
+ int const first_vindex = CCTK_FirstVarIndexI (gindex);
+ int const num_vars = CCTK_NumVarsInGroupI (gindex);
+ for (int vindex=first_vindex; vindex<first_vindex+num_vars; ++vindex) {
+ output_var.at(vindex) = true;
+ }
+ }
+
+ output (cctkGH, file, output_var, true);
+
+ // Close file
+ herr_t const herr = H5Fclose (file);
+ assert (not herr);
+
+ // Wait until all files have been written, then rename the
+ // checkpoint files
+ // TODO: ensure there were no errors
+ CCTK_Barrier (cctkGH);
+ int const ierr = rename (tempname, filename);
+ assert (not ierr);
+ }
+
+ void CarpetIOF5_InitialDataCheckpoint (CCTK_ARGUMENTS)
+ {
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
+
+ if (checkpoint and checkpoint_ID) {
+ Checkpoint (cctkGH, CP_INITIAL_DATA);
+ }
+ }
+
+ void CarpetIOF5_EvolutionCheckpoint (CCTK_ARGUMENTS)
+ {
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
+
+ bool const checkpoint_by_iteration =
+ checkpoint_every > 0 and
+ cctk_iteration >= last_checkpoint_iteration + checkpoint_every;
+ bool const do_checkpoint =
+ checkpoint and (checkpoint_by_iteration or checkpoint_next);
+
+ if (do_checkpoint) {
+ Checkpoint (cctkGH, CP_EVOLUTION_DATA);
+ }
+ }
+
+ void CarpetIOF5_TerminationCheckpoint (CCTK_ARGUMENTS)
+ {
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
+
+ if (checkpoint and checkpoint_on_terminate) {
+
+ bool const did_checkpoint = cctk_iteration == last_checkpoint_iteration;
+ bool const do_checkpoint = not did_checkpoint;
+
+ if (do_checkpoint) {
+ Checkpoint (cctkGH, CP_EVOLUTION_DATA);
+ }
+ }
+ }
+
+} // end namespace CarpetIOF5