aboutsummaryrefslogtreecommitdiff
path: root/CarpetDev/CarpetIOF5_standalone
diff options
context:
space:
mode:
authorErik Schnetter <schnetter@cct.lsu.edu>2010-08-24 12:04:51 -0400
committerBarry Wardell <barry.wardell@gmail.com>2011-12-14 18:21:12 +0000
commita62e8ee3f1e86100cda633f51c22ee063e28df76 (patch)
tree96c4522bba984cfb4a1e53ce75733d6cdbf08c01 /CarpetDev/CarpetIOF5_standalone
parenteb813afcef1be0aba7154fe41d21e4a7657371ad (diff)
CarpetIOF5: Rename old thorn
Diffstat (limited to 'CarpetDev/CarpetIOF5_standalone')
-rw-r--r--CarpetDev/CarpetIOF5_standalone/README30
-rw-r--r--CarpetDev/CarpetIOF5_standalone/TODO4
-rw-r--r--CarpetDev/CarpetIOF5_standalone/configuration.ccl3
-rw-r--r--CarpetDev/CarpetIOF5_standalone/doc/documentation.tex144
-rw-r--r--CarpetDev/CarpetIOF5_standalone/interface.ccl50
-rw-r--r--CarpetDev/CarpetIOF5_standalone/par/wavetoy-cc-ref.par244
-rw-r--r--CarpetDev/CarpetIOF5_standalone/par/wavetoy-cc-uni.par230
-rw-r--r--CarpetDev/CarpetIOF5_standalone/par/wavetoy-vc-ref.par244
-rw-r--r--CarpetDev/CarpetIOF5_standalone/par/wavetoy-vc-uni.par245
-rw-r--r--CarpetDev/CarpetIOF5_standalone/param.ccl154
-rw-r--r--CarpetDev/CarpetIOF5_standalone/schedule.ccl14
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/IOF5.cc694
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/coordinate_system.cc166
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/coordinate_system.hh104
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/data_region.cc91
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/data_region.hh64
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/extending.cc113
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/extending.hh76
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/f5writer.cc445
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/f5writer.hh74
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/file.cc272
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/file.hh103
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/make.code.defn19
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/meta_data_region.cc116
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/meta_data_region.hh62
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/physical_quantity.cc119
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/physical_quantity.hh67
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/simulation.cc96
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/simulation.hh64
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/tensor_component.cc171
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/tensor_component.hh62
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/timestep.cc124
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/timestep.hh70
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/topology.cc200
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/topology.hh133
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/utils.cc512
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/utils.hh93
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/writer-old.cc511
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/writer.cc400
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/writer.hh70
40 files changed, 6453 insertions, 0 deletions
diff --git a/CarpetDev/CarpetIOF5_standalone/README b/CarpetDev/CarpetIOF5_standalone/README
new file mode 100644
index 000000000..a625117a0
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/README
@@ -0,0 +1,30 @@
+Cactus Code Thorn CarpetIOF5
+Thorn Author(s) : Erik Schnetter <schnetter@aei.mpg.de>
+Thorn Maintainer(s) : Erik Schnetter <schnetter@aei.mpg.de>
+--------------------------------------------------------------------------
+
+Purpose of the thorn:
+
+Input and output data using the HDF5 based F5 file format.
+
+
+
+An F5 file contains the following hierarchy:
+
+ Bundle
+ Slice
+ Grid
+ Topology
+ Representation
+ Field
+
+We have a class hierarchy:
+
+ file
+ timestep (slice)
+ simulation (grid) [grid hierarchy of one patch]
+ topology (topology) [one refinement level]
+ coordinate_system (representation)
+ physical_quantity (field)
+ data_region
+ tensor_component
diff --git a/CarpetDev/CarpetIOF5_standalone/TODO b/CarpetDev/CarpetIOF5_standalone/TODO
new file mode 100644
index 000000000..3fa9b3ca2
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/TODO
@@ -0,0 +1,4 @@
+2008-01-19: Need to write table of contents as well. What format
+should it have?
+
+2008-01-19: Checkpointing and recovery is not yet supported.
diff --git a/CarpetDev/CarpetIOF5_standalone/configuration.ccl b/CarpetDev/CarpetIOF5_standalone/configuration.ccl
new file mode 100644
index 000000000..d5c33c995
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/configuration.ccl
@@ -0,0 +1,3 @@
+# Configuration definitions for thorn CarpetIOF5
+
+REQUIRES Carpet CarpetLib F5 HDF5 IOUtil
diff --git a/CarpetDev/CarpetIOF5_standalone/doc/documentation.tex b/CarpetDev/CarpetIOF5_standalone/doc/documentation.tex
new file mode 100644
index 000000000..9d8b3d19e
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/doc/documentation.tex
@@ -0,0 +1,144 @@
+% *======================================================================*
+% Cactus Thorn template for ThornGuide documentation
+% Author: Ian Kelley
+% Date: Sun Jun 02, 2002
+% $Header: /cactusdevcvs/Cactus/doc/ThornGuide/template.tex,v 1.12 2004/01/07 20:12:39 rideout Exp $
+%
+% 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
+% relevant 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
+% % START 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 separated with a \\ or a comma.
+% - You can define your own macros, but they must appear after
+% the START CACTUS THORNGUIDE line, and must 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 graphicx package.
+% More specifically, with the "\includegraphics" command. Do
+% not specify any graphic file extensions in your .tex file. This
+% will allow us 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{...}
+% - Do not use \appendix, instead include any appendices you need as
+% standard sections.
+% - 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/}}
+%
+% *======================================================================*
+
+% If you are using CVS use this line to give version information
+% $Header: /cactusdevcvs/Cactus/doc/ThornGuide/template.tex,v 1.12 2004/01/07 20:12:39 rideout Exp $
+
+\documentclass{article}
+
+% Use the Cactus ThornGuide style file
+% (Automatically used from Cactus distribution, if you have a
+% thorn without the Cactus Flesh download this from the Cactus
+% homepage at www.cactuscode.org)
+\usepackage{../../../../doc/latex/cactus}
+
+\begin{document}
+
+% The author of the documentation
+\author{Erik Schnetter \textless schnetter@aei.mpg.de\textgreater}
+
+% The title of the document (not necessarily the name of the Thorn)
+\title{}
+
+% the date your document was last changed, if your document is in CVS,
+% please use:
+% \date{$ $Date: 2004/01/07 20:12:39 $ $}
+\date{April 24 2005}
+
+\maketitle
+
+% Do not delete next line
+% START CACTUS THORNGUIDE
+
+% Add all definitions used in this documentation here
+% \def\mydef etc
+
+% Add an abstract for this thorn's documentation
+\begin{abstract}
+
+\end{abstract}
+
+% The following sections are suggestive only.
+% Remove them or add your own.
+
+\section{Introduction}
+
+\section{Physical System}
+
+\section{Numerical Implementation}
+
+\section{Using This Thorn}
+
+\subsection{Obtaining This Thorn}
+
+\subsection{Basic Usage}
+
+\subsection{Special Behaviour}
+
+\subsection{Interaction With Other Thorns}
+
+\subsection{Examples}
+
+\subsection{Support and Feedback}
+
+\section{History}
+
+\subsection{Thorn Source Code}
+
+\subsection{Thorn Documentation}
+
+\subsection{Acknowledgements}
+
+
+\begin{thebibliography}{9}
+
+\end{thebibliography}
+
+% Do not delete next line
+% END CACTUS THORNGUIDE
+
+\end{document}
diff --git a/CarpetDev/CarpetIOF5_standalone/interface.ccl b/CarpetDev/CarpetIOF5_standalone/interface.ccl
new file mode 100644
index 000000000..aa7a39fee
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/interface.ccl
@@ -0,0 +1,50 @@
+# Interface definition for thorn CarpetIOF5
+
+IMPLEMENTS: IOF5
+
+USES INCLUDE: bbox.hh defs.hh dh.hh vect.hh
+USES INCLUDE: carpet.hh modes.hh
+
+
+
+CCTK_INT next_output_iteration TYPE=scalar
+CCTK_REAL next_output_time TYPE=scalar
+CCTK_INT this_iteration TYPE=scalar
+
+
+
+CCTK_INT FUNCTION Coord_GroupSystem \
+ (CCTK_POINTER_TO_CONST IN cctkGH, \
+ CCTK_STRING IN groupname)
+REQUIRES FUNCTION Coord_GroupSystem
+
+# Check whether existing output files should be truncated or not
+CCTK_INT FUNCTION IO_TruncateOutputFiles \
+ (CCTK_POINTER_TO_CONST IN cctkGH)
+REQUIRES FUNCTION IO_TruncateOutputFiles
+
+
+
+# Return a pointer to an unmodifiable C string
+# which contains a unique ID for this configuration
+CCTK_POINTER_TO_CONST \
+FUNCTION UniqueConfigID (CCTK_POINTER_TO_CONST IN cctkGH)
+USES FUNCTION UniqueConfigID
+
+# Return a pointer to an unmodifiable C string
+# which contains a unique ID for this build
+CCTK_POINTER_TO_CONST \
+FUNCTION UniqueBuildID (CCTK_POINTER_TO_CONST IN cctkGH)
+USES FUNCTION UniqueBuildID
+
+# Return a pointer to an unmodifiable C string
+# which contains a unique ID for this simulation
+CCTK_POINTER_TO_CONST \
+FUNCTION UniqueSimulationID (CCTK_POINTER_TO_CONST IN cctkGH)
+USES FUNCTION UniqueSimulationID
+
+# Return a pointer to an unmodifiable C string
+# which contains a unique ID for this run
+CCTK_POINTER_TO_CONST \
+FUNCTION UniqueRunID (CCTK_POINTER_TO_CONST IN cctkGH)
+USES FUNCTION UniqueRunID
diff --git a/CarpetDev/CarpetIOF5_standalone/par/wavetoy-cc-ref.par b/CarpetDev/CarpetIOF5_standalone/par/wavetoy-cc-ref.par
new file mode 100644
index 000000000..1e8c2783d
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/par/wavetoy-cc-ref.par
@@ -0,0 +1,244 @@
+Cactus::cctk_run_title = "WaveToy cell-centred refined"
+
+Cactus::cctk_full_warnings = yes
+Cactus::highlight_warning_messages = no
+#Cactus::cctk_timer_output = "full"
+
+Cactus::terminate = "time"
+Cactus::cctk_final_time = 1.0
+
+
+
+ActiveThorns = "IOUtil"
+
+IO::out_dir = $parfile
+
+
+
+ActiveThorns = "InitBase"
+
+InitBase::initial_data_setup_method = "init_single_level"
+
+
+
+ActiveThorns = "AEILocalInterp"
+
+ActiveThorns = "Fortran"
+
+ActiveThorns = "HDF5"
+
+ActiveThorns = "LocalInterp"
+
+ActiveThorns = "LoopControl"
+
+ActiveThorns = "NaNCatcher"
+
+ActiveThorns = "Slab"
+
+
+
+ActiveThorns = "Carpet CarpetLib CarpetInterp CarpetReduce CarpetSlab"
+
+Carpet::verbose = no
+Carpet::schedule_barriers = no
+Carpet::veryverbose = no
+CarpetLib::output_bboxes = no
+
+Carpet::domain_from_coordbase = yes
+Carpet::max_refinement_levels = 3
+
+driver::ghost_size = 2
+
+Carpet::refinement_centering = "cell"
+Carpet::prolongation_order_space = 2
+Carpet::prolongation_order_time = 2
+
+Carpet::convergence_level = 0
+
+Carpet::init_each_timelevel = yes
+Carpet::regrid_during_initialisation = no
+Carpet::enable_all_storage = no
+
+Carpet::poison_new_timelevels = yes
+CarpetLib::poison_new_memory = yes
+
+Carpet::grid_structure_filename = "carpet-grid-structure"
+Carpet::output_timers_every = 100
+CarpetLib::print_timestats_every = 100
+CarpetLib::print_memstats_every = 100
+
+
+
+ActiveThorns = "NaNChecker"
+
+NaNChecker::check_every = 100
+NaNChecker::action_if_found = "terminate"
+NaNChecker::check_vars = "
+ WaveToy::scalarevolve
+"
+
+
+
+ActiveThorns = "Boundary CartGrid3D CoordBase SymBase"
+
+CoordBase::domainsize = "minmax"
+
+CoordBase::xmin = -0.50
+CoordBase::ymin = -0.50
+CoordBase::zmin = -0.50
+CoordBase::xmax = +0.50
+CoordBase::ymax = +0.50
+CoordBase::zmax = +0.50
+CoordBase::dx = 0.05
+CoordBase::dy = 0.05
+CoordBase::dz = 0.05
+
+CoordBase::boundary_staggered_x_lower = yes
+CoordBase::boundary_staggered_y_lower = yes
+CoordBase::boundary_staggered_z_lower = yes
+CoordBase::boundary_staggered_x_upper = yes
+CoordBase::boundary_staggered_y_upper = yes
+CoordBase::boundary_staggered_z_upper = yes
+
+CartGrid3D::type = "coordbase"
+
+
+
+ActiveThorns = "CarpetRegrid2"
+
+CarpetRegrid2::regrid_every = 0
+
+CarpetRegrid2::snap_to_coarse = yes
+
+CarpetRegrid2::num_centres = 1
+
+CarpetRegrid2::num_levels_1 = 3
+CarpetRegrid2::radius_1[1] = 0.25
+CarpetRegrid2::radius_1[2] = 0.125
+
+
+
+ActiveThorns = "WavetoyC"
+
+WaveToy::bound = "radiation"
+
+
+
+ActiveThorns = "IDScalarWaveC"
+
+IDScalarWave::initial_data = "gaussian"
+IDScalarWave::radius = 0.0
+IDScalarWave::sigma = 0.1
+IDScalarWave::amplitude = 1.0
+
+
+
+ActiveThorns = "Time"
+
+Time::dtfac = 0.5
+
+
+
+ActiveThorns = "CarpetIOBasic"
+
+IOBasic::outInfo_every = 1
+IOBasic::outInfo_reductions = "norm2 minimum maximum"
+IOBasic::outInfo_vars = "
+ WaveToy::phi
+"
+
+
+
+ActiveThorns = "CarpetIOScalar"
+
+IOScalar::one_file_per_group = yes
+
+IOScalar::outScalar_every = 1
+IOScalar::outScalar_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+
+
+ActiveThorns = "CarpetIOASCII"
+
+IOASCII::one_file_per_group = yes
+
+#IOASCII::output_symmetry_points = no
+#IOASCII::out3D_ghosts = no
+
+IOASCII::out0D_every = 1
+IOASCII::out0D_vars = "
+ Carpet::timing
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+IOASCII::out1D_every = 1
+IOASCII::out1D_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+IOASCII::out2D_every = 10
+IOASCII::out2D_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+IOASCII::out3D_every = 100
+IOASCII::out3D_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+
+
+Activethorns = "CarpetIOHDF5"
+
+IOHDF5::out_every = 100
+IOHDF5::compression_level = 1
+IOHDF5::out_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+IOHDF5::checkpoint = yes
+IO::checkpoint_dir = $parfile
+IO::checkpoint_ID = yes
+IO::checkpoint_every = 100
+IO::checkpoint_on_terminate = yes
+
+Carpet::regrid_during_recovery = no
+IOHDF5::use_grid_structure_from_checkpoint = yes
+
+IO::recover = "autoprobe"
+IO::recover_dir = $parfile
+
+
+
+ActiveThorns = "Formaline"
+
+Formaline::send_as_rdf = yes
+Formaline::rdf_hostname[0] = "buran.aei.mpg.de"
+Formaline::rdf_port [0] = 24997
+Formaline::rdf_hostname[1] = "devportal.cct.lsu.edu"
+Formaline::rdf_port [1] = 8080
+
+
+
+ActiveThorns = "Twitter"
+
+
+
+ActiveThorns = "TimerReport"
+
+TimerReport::out_every = 100
+TimerReport::out_filename = "TimerReport"
diff --git a/CarpetDev/CarpetIOF5_standalone/par/wavetoy-cc-uni.par b/CarpetDev/CarpetIOF5_standalone/par/wavetoy-cc-uni.par
new file mode 100644
index 000000000..d5265e3c8
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/par/wavetoy-cc-uni.par
@@ -0,0 +1,230 @@
+Cactus::cctk_run_title = "WaveToy cell-centred unigrid"
+
+Cactus::cctk_full_warnings = yes
+Cactus::highlight_warning_messages = no
+#Cactus::cctk_timer_output = "full"
+
+Cactus::terminate = "time"
+Cactus::cctk_final_time = 1.0
+
+
+
+ActiveThorns = "IOUtil"
+
+IO::out_dir = $parfile
+
+
+
+ActiveThorns = "InitBase"
+
+InitBase::initial_data_setup_method = "init_single_level"
+
+
+
+ActiveThorns = "AEILocalInterp"
+
+ActiveThorns = "Fortran"
+
+ActiveThorns = "HDF5"
+
+ActiveThorns = "LocalInterp"
+
+ActiveThorns = "LoopControl"
+
+ActiveThorns = "NaNCatcher"
+
+ActiveThorns = "Slab"
+
+
+
+ActiveThorns = "Carpet CarpetLib CarpetInterp CarpetReduce CarpetSlab"
+
+Carpet::verbose = no
+Carpet::schedule_barriers = no
+Carpet::veryverbose = no
+CarpetLib::output_bboxes = no
+
+Carpet::domain_from_coordbase = yes
+Carpet::max_refinement_levels = 3
+
+driver::ghost_size = 2
+
+Carpet::refinement_centering = "cell"
+Carpet::prolongation_order_space = 3
+Carpet::prolongation_order_time = 2
+
+Carpet::convergence_level = 0
+
+Carpet::init_each_timelevel = yes
+Carpet::regrid_during_initialisation = no
+Carpet::enable_all_storage = no
+
+Carpet::poison_new_timelevels = yes
+CarpetLib::poison_new_memory = yes
+
+Carpet::grid_structure_filename = "carpet-grid-structure"
+Carpet::output_timers_every = 100
+CarpetLib::print_timestats_every = 100
+CarpetLib::print_memstats_every = 100
+
+
+
+ActiveThorns = "NaNChecker"
+
+NaNChecker::check_every = 100
+NaNChecker::action_if_found = "terminate"
+NaNChecker::check_vars = "
+ WaveToy::scalarevolve
+"
+
+
+
+ActiveThorns = "Boundary CartGrid3D CoordBase SymBase"
+
+CoordBase::domainsize = "minmax"
+
+CoordBase::xmin = -0.50
+CoordBase::ymin = -0.50
+CoordBase::zmin = -0.50
+CoordBase::xmax = +0.50
+CoordBase::ymax = +0.50
+CoordBase::zmax = +0.50
+CoordBase::dx = 0.0125
+CoordBase::dy = 0.0125
+CoordBase::dz = 0.0125
+
+CoordBase::boundary_staggered_x_lower = yes
+CoordBase::boundary_staggered_y_lower = yes
+CoordBase::boundary_staggered_z_lower = yes
+CoordBase::boundary_staggered_x_upper = yes
+CoordBase::boundary_staggered_y_upper = yes
+CoordBase::boundary_staggered_z_upper = yes
+
+CartGrid3D::type = "coordbase"
+
+
+
+ActiveThorns = "WavetoyC"
+
+WaveToy::bound = "radiation"
+
+
+
+ActiveThorns = "IDScalarWaveC"
+
+IDScalarWave::initial_data = "gaussian"
+IDScalarWave::radius = 0.0
+IDScalarWave::sigma = 0.1
+IDScalarWave::amplitude = 1.0
+
+
+
+ActiveThorns = "Time"
+
+Time::dtfac = 0.5
+
+
+
+ActiveThorns = "CarpetIOBasic"
+
+IOBasic::outInfo_every = 1
+IOBasic::outInfo_reductions = "norm2 minimum maximum"
+IOBasic::outInfo_vars = "
+ WaveToy::phi
+"
+
+
+
+ActiveThorns = "CarpetIOScalar"
+
+IOScalar::one_file_per_group = yes
+
+IOScalar::outScalar_every = 1
+IOScalar::outScalar_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+
+
+ActiveThorns = "CarpetIOASCII"
+
+IOASCII::one_file_per_group = yes
+
+IOASCII::output_symmetry_points = no
+IOASCII::out3D_ghosts = no
+
+IOASCII::out0D_every = 1
+IOASCII::out0D_vars = "
+ Carpet::timing
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+IOASCII::out1D_every = 1
+IOASCII::out1D_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+IOASCII::out2D_every = 10
+IOASCII::out2D_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+IOASCII::out3D_every = 100
+IOASCII::out3D_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+
+
+Activethorns = "CarpetIOHDF5"
+
+IOHDF5::out_every = 100
+IOHDF5::compression_level = 1
+IOHDF5::out_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+IOHDF5::checkpoint = yes
+IO::checkpoint_dir = $parfile
+IO::checkpoint_ID = yes
+IO::checkpoint_every = 100
+IO::checkpoint_on_terminate = yes
+
+Carpet::regrid_during_recovery = no
+IOHDF5::use_grid_structure_from_checkpoint = yes
+
+IO::recover = "autoprobe"
+IO::recover_dir = $parfile
+
+
+
+ActiveThorns = "Formaline"
+
+Formaline::send_as_rdf = yes
+Formaline::rdf_hostname[0] = "buran.aei.mpg.de"
+Formaline::rdf_port [0] = 24997
+Formaline::rdf_hostname[1] = "devportal.cct.lsu.edu"
+Formaline::rdf_port [1] = 8080
+
+
+
+ActiveThorns = "Twitter"
+
+
+
+ActiveThorns = "TimerReport"
+
+TimerReport::out_every = 100
+TimerReport::out_filename = "TimerReport"
diff --git a/CarpetDev/CarpetIOF5_standalone/par/wavetoy-vc-ref.par b/CarpetDev/CarpetIOF5_standalone/par/wavetoy-vc-ref.par
new file mode 100644
index 000000000..46ccdd6b2
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/par/wavetoy-vc-ref.par
@@ -0,0 +1,244 @@
+Cactus::cctk_run_title = "WaveToy vertex-centred refined"
+
+Cactus::cctk_full_warnings = yes
+Cactus::highlight_warning_messages = no
+#Cactus::cctk_timer_output = "full"
+
+Cactus::terminate = "time"
+Cactus::cctk_final_time = 1.0
+
+
+
+ActiveThorns = "IOUtil"
+
+IO::out_dir = $parfile
+
+
+
+ActiveThorns = "InitBase"
+
+InitBase::initial_data_setup_method = "init_single_level"
+
+
+
+ActiveThorns = "AEILocalInterp"
+
+ActiveThorns = "Fortran"
+
+ActiveThorns = "HDF5"
+
+ActiveThorns = "LocalInterp"
+
+ActiveThorns = "LoopControl"
+
+ActiveThorns = "NaNCatcher"
+
+ActiveThorns = "Slab"
+
+
+
+ActiveThorns = "Carpet CarpetLib CarpetInterp CarpetReduce CarpetSlab"
+
+Carpet::verbose = no
+Carpet::schedule_barriers = no
+Carpet::veryverbose = no
+CarpetLib::output_bboxes = no
+
+Carpet::domain_from_coordbase = yes
+Carpet::max_refinement_levels = 3
+
+driver::ghost_size = 2
+
+Carpet::refinement_centering = "vertex"
+Carpet::prolongation_order_space = 3
+Carpet::prolongation_order_time = 2
+
+Carpet::convergence_level = 0
+
+Carpet::init_each_timelevel = yes
+Carpet::regrid_during_initialisation = no
+Carpet::enable_all_storage = no
+
+Carpet::poison_new_timelevels = yes
+CarpetLib::poison_new_memory = yes
+
+Carpet::grid_structure_filename = "carpet-grid-structure"
+Carpet::output_timers_every = 100
+CarpetLib::print_timestats_every = 100
+CarpetLib::print_memstats_every = 100
+
+
+
+ActiveThorns = "NaNChecker"
+
+NaNChecker::check_every = 100
+NaNChecker::action_if_found = "terminate"
+NaNChecker::check_vars = "
+ WaveToy::scalarevolve
+"
+
+
+
+ActiveThorns = "Boundary CartGrid3D CoordBase SymBase"
+
+CoordBase::domainsize = "minmax"
+
+CoordBase::xmin = -0.50
+CoordBase::ymin = -0.50
+CoordBase::zmin = -0.50
+CoordBase::xmax = +0.50
+CoordBase::ymax = +0.50
+CoordBase::zmax = +0.50
+CoordBase::dx = 0.05
+CoordBase::dy = 0.05
+CoordBase::dz = 0.05
+
+CoordBase::boundary_staggered_x_lower = no
+CoordBase::boundary_staggered_y_lower = no
+CoordBase::boundary_staggered_z_lower = no
+CoordBase::boundary_staggered_x_upper = no
+CoordBase::boundary_staggered_y_upper = no
+CoordBase::boundary_staggered_z_upper = no
+
+CartGrid3D::type = "coordbase"
+
+
+
+ActiveThorns = "CarpetRegrid2"
+
+CarpetRegrid2::regrid_every = 0
+
+CarpetRegrid2::snap_to_coarse = yes
+
+CarpetRegrid2::num_centres = 1
+
+CarpetRegrid2::num_levels_1 = 3
+CarpetRegrid2::radius_1[1] = 0.25
+CarpetRegrid2::radius_1[2] = 0.125
+
+
+
+ActiveThorns = "WavetoyC"
+
+WaveToy::bound = "radiation"
+
+
+
+ActiveThorns = "IDScalarWaveC"
+
+IDScalarWave::initial_data = "gaussian"
+IDScalarWave::radius = 0.0
+IDScalarWave::sigma = 0.1
+IDScalarWave::amplitude = 1.0
+
+
+
+ActiveThorns = "Time"
+
+Time::dtfac = 0.5
+
+
+
+ActiveThorns = "CarpetIOBasic"
+
+IOBasic::outInfo_every = 1
+IOBasic::outInfo_reductions = "norm2 minimum maximum"
+IOBasic::outInfo_vars = "
+ WaveToy::phi
+"
+
+
+
+ActiveThorns = "CarpetIOScalar"
+
+IOScalar::one_file_per_group = yes
+
+IOScalar::outScalar_every = 1
+IOScalar::outScalar_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+
+
+ActiveThorns = "CarpetIOASCII"
+
+IOASCII::one_file_per_group = yes
+
+#IOASCII::output_symmetry_points = no
+#IOASCII::out3D_ghosts = no
+
+IOASCII::out0D_every = 1
+IOASCII::out0D_vars = "
+ Carpet::timing
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+IOASCII::out1D_every = 1
+IOASCII::out1D_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+IOASCII::out2D_every = 10
+IOASCII::out2D_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+IOASCII::out3D_every = 100
+IOASCII::out3D_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+
+
+Activethorns = "CarpetIOHDF5"
+
+IOHDF5::out_every = 100
+IOHDF5::compression_level = 1
+IOHDF5::out_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+IOHDF5::checkpoint = yes
+IO::checkpoint_dir = $parfile
+IO::checkpoint_ID = yes
+IO::checkpoint_every = 100
+IO::checkpoint_on_terminate = yes
+
+Carpet::regrid_during_recovery = no
+IOHDF5::use_grid_structure_from_checkpoint = yes
+
+IO::recover = "autoprobe"
+IO::recover_dir = $parfile
+
+
+
+ActiveThorns = "Formaline"
+
+Formaline::send_as_rdf = yes
+Formaline::rdf_hostname[0] = "buran.aei.mpg.de"
+Formaline::rdf_port [0] = 24997
+Formaline::rdf_hostname[1] = "devportal.cct.lsu.edu"
+Formaline::rdf_port [1] = 8080
+
+
+
+ActiveThorns = "Twitter"
+
+
+
+ActiveThorns = "TimerReport"
+
+TimerReport::out_every = 100
+TimerReport::out_filename = "TimerReport"
diff --git a/CarpetDev/CarpetIOF5_standalone/par/wavetoy-vc-uni.par b/CarpetDev/CarpetIOF5_standalone/par/wavetoy-vc-uni.par
new file mode 100644
index 000000000..e2339f342
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/par/wavetoy-vc-uni.par
@@ -0,0 +1,245 @@
+Cactus::cctk_run_title = "WaveToy vertex-centred unigrid"
+
+Cactus::cctk_full_warnings = yes
+Cactus::highlight_warning_messages = no
+
+Cactus::terminate = "time"
+Cactus::cctk_final_time = 1.0
+
+
+
+ActiveThorns = "IOUtil"
+
+IO::out_dir = $parfile
+
+
+
+ActiveThorns = "InitBase"
+
+InitBase::initial_data_setup_method = "init_single_level"
+
+
+
+ActiveThorns = "AEILocalInterp"
+
+ActiveThorns = "Fortran"
+
+ActiveThorns = "HDF5"
+
+ActiveThorns = "LocalInterp"
+
+ActiveThorns = "LoopControl"
+
+ActiveThorns = "NaNCatcher"
+
+ActiveThorns = "Slab"
+
+
+
+ActiveThorns = "Carpet CarpetLib CarpetInterp CarpetReduce CarpetSlab"
+
+Carpet::verbose = no
+Carpet::schedule_barriers = no
+Carpet::veryverbose = no
+CarpetLib::output_bboxes = no
+
+Carpet::domain_from_coordbase = yes
+Carpet::max_refinement_levels = 3
+
+driver::ghost_size = 2
+
+Carpet::refinement_centering = "vertex"
+Carpet::prolongation_order_space = 3
+Carpet::prolongation_order_time = 2
+
+Carpet::convergence_level = 0
+
+Carpet::init_each_timelevel = yes
+Carpet::regrid_during_initialisation = no
+Carpet::enable_all_storage = no
+
+Carpet::poison_new_timelevels = yes
+CarpetLib::poison_new_memory = yes
+
+Carpet::grid_structure_filename = "carpet-grid-structure"
+Carpet::output_timers_every = 100
+CarpetLib::print_timestats_every = 100
+CarpetLib::print_memstats_every = 100
+
+
+
+ActiveThorns = "NaNChecker"
+
+NaNChecker::check_every = 100
+NaNChecker::action_if_found = "terminate"
+NaNChecker::check_vars = "
+ WaveToy::scalarevolve
+"
+
+
+
+ActiveThorns = "Boundary CartGrid3D CoordBase SymBase"
+
+CoordBase::domainsize = "minmax"
+
+CoordBase::xmin = -0.50
+CoordBase::ymin = -0.50
+CoordBase::zmin = -0.50
+CoordBase::xmax = +0.50
+CoordBase::ymax = +0.50
+CoordBase::zmax = +0.50
+CoordBase::dx = 0.0125
+CoordBase::dy = 0.0125
+CoordBase::dz = 0.0125
+
+CoordBase::boundary_staggered_x_lower = no
+CoordBase::boundary_staggered_y_lower = no
+CoordBase::boundary_staggered_z_lower = no
+CoordBase::boundary_staggered_x_upper = no
+CoordBase::boundary_staggered_y_upper = no
+CoordBase::boundary_staggered_z_upper = no
+
+CartGrid3D::type = "coordbase"
+
+
+
+ActiveThorns = "WavetoyC"
+
+WaveToy::bound = "radiation"
+
+
+
+ActiveThorns = "IDScalarWaveC"
+
+IDScalarWave::initial_data = "gaussian"
+IDScalarWave::radius = 0.0
+IDScalarWave::sigma = 0.1
+IDScalarWave::amplitude = 1.0
+
+
+
+ActiveThorns = "Time"
+
+Time::dtfac = 0.5
+
+
+
+ActiveThorns = "CarpetIOBasic"
+
+IOBasic::outInfo_every = 1
+IOBasic::outInfo_reductions = "norm2 minimum maximum"
+IOBasic::outInfo_vars = "
+ WaveToy::phi
+"
+
+
+
+#ActiveThorns = "CarpetIOScalar"
+#
+#IOScalar::one_file_per_group = yes
+#
+#IOScalar::outScalar_every = 1
+#IOScalar::outScalar_vars = "
+# grid::coordinates
+# CarpetReduce::weight
+# WaveToy::scalarevolve
+#"
+
+
+
+ActiveThorns = "CarpetIOASCII"
+
+IOASCII::one_file_per_group = yes
+
+IOASCII::output_symmetry_points = yes # no
+IOASCII::out3D_ghosts = yes # no
+
+#IOASCII::out0D_every = 1
+#IOASCII::out0D_vars = "
+# Carpet::timing
+# grid::coordinates
+# CarpetReduce::weight
+# WaveToy::scalarevolve
+#"
+
+IOASCII::out1D_every = 1
+IOASCII::out1D_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+#IOASCII::out2D_every = 10
+#IOASCII::out2D_vars = "
+# grid::coordinates
+# CarpetReduce::weight
+# WaveToy::scalarevolve
+#"
+#
+#IOASCII::out3D_every = 100
+#IOASCII::out3D_vars = "
+# grid::coordinates
+# CarpetReduce::weight
+# WaveToy::scalarevolve
+#"
+
+
+
+Activethorns = "CarpetIOHDF5"
+
+IOHDF5::out_every = 64
+IOHDF5::compression_level = 1
+IOHDF5::out_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+#IOHDF5::checkpoint = yes
+#IO::checkpoint_dir = $parfile
+#IO::checkpoint_ID = yes
+#IO::checkpoint_every = 100
+#IO::checkpoint_on_terminate = yes
+#
+#Carpet::regrid_during_recovery = no
+#IOHDF5::use_grid_structure_from_checkpoint = yes
+#
+#IO::recover = "autoprobe"
+#IO::recover_dir = $parfile
+
+
+
+Activethorns = "CarpetIOF5"
+
+IOF5::out_every = 64
+IOF5::chunk_size_x = 8
+IOF5::chunk_size_y = 8
+IOF5::chunk_size_z = 8
+IOF5::compression_level = 1
+IOF5::write_checksum = yes
+IOF5::out_vars = "
+ grid::coordinates
+ CarpetReduce::weight
+ WaveToy::scalarevolve
+"
+
+
+ActiveThorns = "Formaline"
+
+Formaline::send_as_rdf = yes
+Formaline::rdf_hostname[0] = "buran.aei.mpg.de"
+Formaline::rdf_port [0] = 24997
+Formaline::rdf_hostname[1] = "devportal.cct.lsu.edu"
+Formaline::rdf_port [1] = 8080
+
+
+
+ActiveThorns = "Twitter"
+
+
+
+ActiveThorns = "TimerReport"
+
+TimerReport::out_every = 100
+TimerReport::output_all_timers_together = yes
+TimerReport::out_filename = "TimerReport"
diff --git a/CarpetDev/CarpetIOF5_standalone/param.ccl b/CarpetDev/CarpetIOF5_standalone/param.ccl
new file mode 100644
index 000000000..f9d1249bd
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/param.ccl
@@ -0,0 +1,154 @@
+# Parameter definitions for thorn CarpetIOF5
+
+BOOLEAN verbose "Produce screen output while running"
+{
+} no
+
+BOOLEAN veryverbose "Produce much screen output while running"
+{
+} no
+
+
+
+SHARES: IO
+
+USES KEYWORD out_mode
+USES INT out_proc_every
+
+USES INT out_timesteps_per_file
+
+USES KEYWORD out_save_parameters
+
+USES STRING out_dir AS IO_out_dir
+USES KEYWORD out_criterion AS IO_out_criterion
+USES INT out_every AS IO_out_every
+USES REAL out_dt AS IO_out_dt
+
+
+
+PRIVATE:
+
+STRING out_dir "Output directory (overrides IO::out_dir)" STEERABLE=always
+{
+ "^$" :: "Empty: use IO::out_dir"
+ ".+" :: "Not empty: directory name"
+} ""
+
+KEYWORD file_content "Create one file for every x" STEERABLE=always
+{
+ "variable" :: ""
+ "group" :: ""
+ "thorn" :: ""
+ "everything" :: ""
+} "group"
+
+INT iteration_digits "Minimum number of digits for iteration number" STEERABLE=always
+{
+ 0:* :: ""
+} 10
+
+STRING out_filename "File name (without extension) for file_content='everything'" STEERABLE=always
+{
+ "" :: ""
+} "output"
+
+INT processor_digits "Minimum number of digits for processor number" STEERABLE=always
+{
+ 0:* :: ""
+} 6
+
+STRING out_extension "File name extension" STEERABLE=always
+{
+ "" :: "File extension (including a leading dot, if desired)"
+} ".f5"
+
+BOOLEAN create_subdirs "Create subdirectories for the output files to reduce the number of files per directory" STEERABLE=always
+{
+} "no"
+
+BOOLEAN one_dir_per_file "Create one subdirectory per output file to reduce locking overhead" STEERABLE=always
+{
+} "no"
+
+
+
+
+STRING out_vars "Variables and groups which should be output in the F5 file format" STEERABLE=always
+{
+ "" :: "List of group or variable names"
+} ""
+
+KEYWORD out_criterion "Criterion to select CarpetIOHDF5 output intervals" STEERABLE=always
+{
+ "default" :: "Use IO::out_criterion"
+ "always" :: "Always output"
+ "never" :: "Never output"
+ "iteration" :: "Output every so many iterations"
+ "time" :: "Output every that much coordinate time"
+} "default"
+
+INT out_every "How often to do CarpetIOF5 output (overrides IO::out_every)" STEERABLE=always
+{
+ 1:* :: "Output every so many time steps"
+ 0 :: "As often as possible"
+ -1 :: "No output"
+ -2 :: "Use IO::out_every"
+} -2
+
+REAL out_dt "How often to do CarpetIOF5 output (overrides IO::out_dt)" STEERABLE=always
+{
+ (0:* :: "In intervals of that much coordinate time"
+ 0 :: "As often as possible"
+ -1 :: "No output"
+ -2 :: "Use IO::out_dt"
+} -2
+
+REAL dt_fudge "Fudge factor for time comparisons" STEERABLE=always
+{
+ 0:* :: ""
+} 1.0e-12
+
+
+
+INT chunk_size_x "Chunk size for chunked datasets" STEERABLE=always
+{
+ -1 :: "no chunking (use actual dataset size)"
+ 1:* :: "desired chunk size"
+} -1
+
+INT chunk_size_y "Chunk size for chunked datasets" STEERABLE=always
+{
+ -1 :: "no chunking (use actual dataset size)"
+ 1:* :: "desired chunk size"
+} -1
+
+INT chunk_size_z "Chunk size for chunked datasets" STEERABLE=always
+{
+ -1 :: "no chunking (use actual dataset size)"
+ 1:* :: "desired chunk size"
+} -1
+
+INT compression_level "Compression level to use for writing HDF5 data" STEERABLE=always
+{
+ 0 :: "no compression"
+ 1:9 :: "higher numbers compress better"
+} 0
+
+BOOLEAN write_checksum "Add a checksum when writing HDF5 files" STEERABLE=always
+{
+} "no"
+
+BOOLEAN check_checksum "Check checksum (if present) when reading HDF5 files" STEERABLE=always
+{
+} "no"
+
+
+
+KEYWORD output_regions "Regions which should be output" STEERABLE=always
+{
+ "exterior" :: "whole region (including boundaries)"
+ #"communicated" :: "exterior without outer boundary"
+ "owned" :: "evolved in time"
+ # "active" :: "owned minus buffers"
+ "interior" :: "interior (without ghost zones)"
+} "exterior"
diff --git a/CarpetDev/CarpetIOF5_standalone/schedule.ccl b/CarpetDev/CarpetIOF5_standalone/schedule.ccl
new file mode 100644
index 000000000..3f6209662
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/schedule.ccl
@@ -0,0 +1,14 @@
+# Schedule definitions for thorn CarpetIOF5
+
+STORAGE: next_output_iteration next_output_time this_iteration
+
+SCHEDULE CarpetIOF5_Startup AT startup AFTER IOUtil_Startup
+{
+ LANG: C
+} "Startup routine"
+
+SCHEDULE CarpetIOF5_Init AT basegrid
+{
+ LANG: C
+ OPTIONS: global
+} "Initialisation routine"
diff --git a/CarpetDev/CarpetIOF5_standalone/src/IOF5.cc b/CarpetDev/CarpetIOF5_standalone/src/IOF5.cc
new file mode 100644
index 000000000..1173f5228
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/IOF5.cc
@@ -0,0 +1,694 @@
+#include <algorithm>
+#include <cassert>
+#include <cctype>
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+#include <iomanip>
+#include <sstream>
+#include <string>
+#include <vector>
+
+// force HDF5 1.8.x installations to use the new API
+#define H5Dcreate_vers 2
+
+#include <hdf5.h>
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "CactusBase/IOUtil/src/ioutil_CheckpointRecovery.h"
+
+#include "carpet.hh"
+
+#include "defs.hh"
+
+#include "extending.hh"
+#include "file.hh"
+#include "utils.hh"
+#include "writer.hh"
+
+
+
+namespace CarpetIOF5 {
+
+
+
+ int const Error_none = 0; // no error
+
+ int const Error_illegal_varname = -1;
+ int const Error_group_has_no_storage = -2;
+
+ int const Error_lonely_option_string = -3;
+ int const Error_unterminated_option_string = -4;
+ int const Error_garbage_after_option_string = -5;
+ int const Error_invalid_variable_name = -6;
+
+
+
+ extern "C" int
+ CarpetIOF5_Startup ();
+
+ static void *
+ Setup (tFleshConfig * const fleshconfig,
+ int const convlevel,
+ cGH * const cctkGH);
+
+ extern "C" void
+ CarpetIOF5_Init (CCTK_ARGUMENTS);
+
+
+
+ static int
+ OutputGH (cGH const * cctkGH);
+
+ static void
+ mark_variables (int variable,
+ char const * options,
+ void * ptr);
+
+
+
+ static int
+ TimeToOutput (cGH const * cctkGH,
+ int variable);
+
+
+
+ static int
+ TriggerOutput (cGH const * cctkGH,
+ int variable);
+
+
+
+ static int
+ OutputVarAs (cGH const * cctkGH,
+ char const * varname,
+ char const * alias);
+
+
+
+ static void
+ WriteParameters (F5::file_t & file);
+
+
+
+ static string
+ generate_filename (cGH const * cctkGH,
+ int variable);
+
+
+
+ int
+ CarpetIOF5_Startup ()
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose) CCTK_INFO ("Startup");
+ return extending_t::create (Setup);
+ }
+
+
+
+ void *
+ Setup (tFleshConfig * const fleshconfig,
+ int const convlevel,
+ cGH * const cctkGH)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ assert (fleshconfig != 0);
+ if (verbose) CCTK_INFO ("Setup");
+ return extending_t::setup
+ (cctkGH, OutputGH, TimeToOutput, TriggerOutput, OutputVarAs);
+ }
+
+
+
+ void
+ CarpetIOF5_Init (CCTK_ARGUMENTS)
+ {
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose) CCTK_INFO ("Init");
+
+ * next_output_iteration = 0;
+ * next_output_time = cctk_time;
+ * this_iteration = -1;
+ }
+
+
+
+ int
+ OutputGH (cGH const * const cctkGH)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ assert (cctkGH != 0);
+
+ if (verbose) CCTK_INFO ("OutputGH");
+
+ int ierr;
+
+ vector<bool> want_variables (CCTK_NumVars());
+ ierr
+ = CCTK_TraverseString (out_vars,
+ mark_variables,
+ static_cast<void *> (& want_variables),
+ CCTK_GROUP_OR_VAR);
+ switch (ierr) {
+ case -2: return Error_lonely_option_string;
+ case -3: return Error_unterminated_option_string;
+ case -4: return Error_garbage_after_option_string;
+ case -5: return Error_invalid_variable_name;
+ }
+ assert (ierr >= 0);
+
+ ierr = Error_none;
+ for (int variable = 0; variable < CCTK_NumVars(); ++ variable)
+ {
+ if (want_variables.at(variable))
+ {
+ if (TimeToOutput (cctkGH, variable))
+ {
+ ierr = TriggerOutput (cctkGH, variable);
+ }
+ }
+ }
+
+ return ierr;
+ }
+
+
+
+ void
+ mark_variables (int const variable,
+ char const * const options,
+ void * const ptr)
+ {
+ vector<bool> & want_variables = * static_cast<vector<bool> *> (ptr);
+ want_variables.at (variable) = true;
+ }
+
+
+
+ int
+ TimeToOutput (cGH const * const cctkGH,
+ int const variable)
+ {
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
+
+ assert (cctkGH != 0);
+ assert (variable >= 0 and variable < CCTK_NumVars());
+
+ assert (Carpet::is_level_mode());
+
+ if (verbose)
+ {
+ char * const fullname = CCTK_FullName(variable);
+ CCTK_VInfo (CCTK_THORNSTRING, "TimeToOutput \"%s\"", fullname);
+ free (fullname);
+ }
+
+ bool should_output;
+
+ char const * const my_out_criterion
+ = (CCTK_EQUALS (out_criterion, "default")
+ ? IO_out_criterion
+ : out_criterion);
+
+ if (CCTK_EQUALS (my_out_criterion, "always"))
+ {
+ should_output = true;
+ }
+ else if (CCTK_EQUALS (my_out_criterion, "never"))
+ {
+ should_output = false;
+ }
+ else if (CCTK_EQUALS (my_out_criterion, "iteration"))
+ {
+ int const my_out_every = out_every == -2 ? IO_out_every : out_every;
+ switch (my_out_every)
+ {
+ case 0:
+ should_output = true;
+ break;
+ case -1:
+ should_output = false;
+ break;
+ default:
+ if (* this_iteration == cctk_iteration)
+ {
+ // we already decided to output this iteration
+ should_output = true;
+ }
+ else if (cctk_iteration >= * next_output_iteration)
+ {
+ // it is time for the next output
+ should_output = true;
+ * this_iteration = cctk_iteration;
+ * next_output_iteration = cctk_iteration + my_out_every;
+ }
+ else
+ {
+ should_output = false;
+ }
+ break;
+ }
+ }
+ else if (CCTK_EQUALS (my_out_criterion, "time"))
+ {
+ CCTK_REAL const my_out_dt = out_dt == -2 ? IO_out_dt : out_dt;
+ if (out_dt == 0)
+ {
+ should_output = true;
+ }
+ else if (out_dt == -1)
+ {
+ should_output = false;
+ }
+ else
+ {
+ if (* this_iteration == cctk_iteration)
+ {
+ // we already decided to output this iteration
+ should_output = true;
+ }
+ else if (cctk_time / cctk_delta_time
+ >= * next_output_time / cctk_delta_time - dt_fudge)
+ {
+ // it is time for the next output
+ should_output = true;
+ * this_iteration = cctk_iteration;
+ * next_output_time = cctk_time + my_out_dt;
+ }
+ else
+ {
+ should_output = false;
+ }
+ }
+ }
+ else
+ {
+ CCTK_WARN (1, "internal error");
+ should_output = false;
+ }
+
+ if (should_output)
+ {
+ extending_t extending (cctkGH);
+ int const last_output_iteration
+ = (extending.get_last_output_iteration
+ (Carpet::mglevel, Carpet::reflevel, variable));
+ assert (last_output_iteration <= cctk_iteration);
+ if (last_output_iteration == cctk_iteration)
+ {
+ // Skipping output for variable, because this variable has
+ // already been output during the current iteration --
+ // probably via a trigger during the analysis stage
+ should_output = false;
+ }
+ else
+ {
+ extending.set_last_output_iteration
+ (Carpet::mglevel, Carpet::reflevel, variable, cctk_iteration);
+ }
+ }
+
+ return should_output;
+ }
+
+
+
+ int
+ TriggerOutput (cGH const * const cctkGH,
+ int const variable)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ assert (cctkGH != 0);
+ assert (variable >= 0 and variable < CCTK_NumVars());
+
+ char * const fullname = CCTK_FullName (variable);
+ assert (fullname);
+
+ if (verbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING, "TriggerOutput \"%s\"", fullname);
+ }
+
+ string const alias = generate_filename (cctkGH, variable);
+
+ int const ierr = OutputVarAs (cctkGH, fullname, alias.c_str());
+
+ free (fullname);
+
+ return ierr;
+ }
+
+
+
+ int
+ OutputVarAs (cGH const * const cctkGH,
+ char const * const varname,
+ char const * const alias)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ assert (cctkGH != 0);
+ assert (varname != 0);
+ assert (alias != 0);
+
+ if (verbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING, "OutputVarAs \"%s\" \"%s\"",
+ varname, alias);
+ }
+
+ int const variable = CCTK_VarIndex (varname);
+ if (variable < 0)
+ {
+ return Error_illegal_varname;
+ }
+ assert (variable >= 0 and variable < CCTK_NumVars());
+
+ int const group = CCTK_GroupIndexFromVarI (variable);
+ assert (group >= 0 and group < CCTK_NumGroups());
+
+ if (CCTK_ActiveTimeLevelsGI (cctkGH, group) == 0)
+ {
+ return Error_group_has_no_storage;
+ }
+
+ extending_t extending (cctkGH);
+
+ bool const use_IO_out_dir = strcmp (out_dir, "") == 0;
+ string const path = use_IO_out_dir ? IO_out_dir : out_dir;
+ string const basename = alias;
+
+ bool const did_truncate = extending.get_did_truncate (basename);
+ bool const do_truncate
+ = not did_truncate and IO_TruncateOutputFiles (cctkGH);
+ extending.set_did_truncate (basename);
+
+ int const proc = CCTK_MyProc (cctkGH);
+ bool have_metafile; // whether there is a metadata file
+ int metadata_processor; // the processor which outputs the metadata file
+ int output_processor; // the processor which outputs our data
+ if (CCTK_EQUALS (out_mode, "proc"))
+ {
+ have_metafile = true;
+ metadata_processor = 0;
+ output_processor = proc;
+ }
+ else if (CCTK_EQUALS (out_mode, "np"))
+ {
+ have_metafile = true;
+ metadata_processor = 0;
+ output_processor = proc / out_proc_every * out_proc_every;
+ }
+ else if (CCTK_EQUALS (out_mode, "onefile"))
+ {
+ have_metafile = false;
+ metadata_processor = 0;
+ output_processor = 0;
+ }
+ else
+ {
+ assert (0);
+ }
+
+ F5::file_t * metafile = NULL;
+ if (have_metafile and proc == metadata_processor)
+ {
+ metafile
+ = new F5::file_t (cctkGH, path, basename, string (out_extension),
+ do_truncate, true, false);
+ }
+
+ F5::file_t * file = NULL;
+ if (proc == output_processor)
+ {
+ file = new F5::file_t (cctkGH, path, basename, string (out_extension),
+ do_truncate, not have_metafile, true);
+ }
+
+ if (do_truncate)
+ {
+ // Output parameters once after the output file has been created
+ if (proc == metadata_processor)
+ {
+ if (CCTK_EQUALS (out_save_parameters, "all") or
+ CCTK_EQUALS (out_save_parameters, "only set"))
+ {
+ WriteParameters (have_metafile ? * metafile : * file);
+ }
+ else if (CCTK_EQUALS (out_save_parameters, "no"))
+ {
+ // do nothing
+ }
+ else
+ {
+ assert (0);
+ }
+ }
+ }
+
+ if (metafile)
+ {
+ writer_t writer (cctkGH, variable);
+ writer.write (* metafile);
+ delete metafile;
+ metafile = NULL;
+ }
+ {
+ writer_t writer (cctkGH, variable);
+#warning "TODO: handle the case where not all processors are writing to their own file"
+ assert (proc == output_processor);
+ assert (file);
+ writer.write (* file);
+ delete file;
+ file = NULL;
+ }
+
+ return Error_none;
+ }
+
+
+
+ void
+ WriteParameters (F5::file_t & file)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ cGH const * const cctkGH = file.get_cctkGH ();
+
+ hid_t const hdf5_file = file.get_hdf5_file();
+
+ hid_t const attribute_group
+ = F5::open_or_create_group (hdf5_file,
+ "Parameters and Global Attributes");
+ assert (attribute_group >= 0);
+
+ // unique configuration identifier
+ if (CCTK_IsFunctionAliased ("UniqueConfigID")) {
+ F5::write_or_check_attribute
+ (attribute_group, "config id",
+ static_cast<char const *> (UniqueConfigID (cctkGH)));
+ }
+
+ // unique build identifier
+ if (CCTK_IsFunctionAliased ("UniqueBuildID")) {
+ F5::write_or_check_attribute
+ (attribute_group, "build id",
+ static_cast<char const *> (UniqueBuildID (cctkGH)));
+ }
+
+ // unique simulation identifier
+ if (CCTK_IsFunctionAliased ("UniqueSimulationID")) {
+ F5::write_or_check_attribute
+ (attribute_group, "simulation id",
+ static_cast<char const *> (UniqueSimulationID (cctkGH)));
+ }
+
+ // unique run identifier
+ if (CCTK_IsFunctionAliased ("UniqueRunID")) {
+ F5::write_or_check_attribute
+ (attribute_group, "run id",
+ static_cast<char const *> (UniqueRunID (cctkGH)));
+ }
+
+ // Output Cactus parameters as single string
+ {
+ char * const parameters = IOUtil_GetAllParameters (cctkGH, true);
+ assert (parameters);
+ // Create a dataset, since the data may not fit into an attribute
+ hsize_t const size = strlen (parameters) + 1;
+ hid_t const dataspace = H5Screate_simple (1, & size, NULL);
+ assert (dataspace >= 0);
+ hid_t properties = H5Pcreate (H5P_DATASET_CREATE);
+ assert (properties >= 0);
+ check (not H5Pset_chunk (properties, 1, & size));
+ if (compression_level > 0)
+ {
+ check (not H5Pset_deflate (properties, compression_level));
+ }
+ if (write_checksum)
+ {
+ check (not H5Pset_fletcher32 (properties));
+ }
+ hid_t const dataset
+ = H5Dcreate (attribute_group, "All Parameters", H5T_NATIVE_CHAR,
+ dataspace, H5P_DEFAULT,
+ properties, H5P_DEFAULT);
+ assert (dataset >= 0);
+ check (not H5Dwrite (dataset, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, parameters));
+ check (not H5Dclose (dataset));
+ check (not H5Pclose (properties));
+ check (not H5Sclose (dataspace));
+ free (parameters);
+ }
+
+ check (not H5Gclose (attribute_group));
+
+ // This is far too slow to be useful
+#if 0
+ hid_t const parameter_group
+ = F5::open_or_create_group (hdf5_file, "Cactus parameters");
+ assert (parameter_group >= 0);
+
+ int first = 1;
+ for (;;)
+ {
+ cParamData const * parameter_data;
+ char * parameter_fullname;
+
+ int const ierr
+ = CCTK_ParameterWalk (first, 0,
+ & parameter_fullname, & parameter_data);
+ if (ierr > 0) break;
+ assert (ierr >= 0);
+
+ int type;
+ void const * const parameter_value
+ = CCTK_ParameterGet (parameter_data->name, parameter_data->thorn,
+ & type);
+ assert (type == parameter_data->type);
+ assert (parameter_value != 0);
+
+ switch (type)
+ {
+ case PARAMETER_BOOLEAN:
+ case PARAMETER_INT:
+ {
+ CCTK_INT const value
+ = * static_cast<CCTK_INT const *> (parameter_value);
+ F5::write_or_check_attribute
+ (parameter_group, parameter_fullname, value);
+ }
+ break;
+ case PARAMETER_REAL:
+ {
+ CCTK_REAL const value
+ = * static_cast<CCTK_REAL const *> (parameter_value);
+ F5::write_or_check_attribute
+ (parameter_group, parameter_fullname, value);
+ }
+ break;
+ case PARAMETER_KEYWORD:
+ case PARAMETER_STRING:
+ {
+ char const * const value
+ = * static_cast<char const * const *> (parameter_value);
+ F5::write_or_check_attribute
+ (parameter_group, parameter_fullname, value);
+ }
+ break;
+ default:
+ assert (0);
+ }
+
+ free (parameter_fullname);
+
+ first = 0;
+ }
+
+ check (not H5Gclose (parameter_group));
+#endif
+ }
+
+
+
+ string
+ generate_filename (cGH const * const cctkGH,
+ int const variable)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ assert (variable >= 0);
+
+ ostringstream filename_buf;
+
+ if (CCTK_EQUALS (file_content, "variable"))
+ {
+ char * const varname = CCTK_FullName (variable);
+ assert (varname);
+ for (char * p = varname; * p; ++ p)
+ {
+ *p = tolower (* p);
+ }
+ filename_buf << varname;
+ free (varname);
+ }
+ else if (CCTK_EQUALS (file_content, "group"))
+ {
+ char * const groupname = CCTK_GroupNameFromVarI (variable);
+ assert (groupname);
+ for (char * p = groupname; * p; ++ p)
+ {
+ *p = tolower (* p);
+ }
+ filename_buf << groupname;
+ free (groupname);
+ }
+ else if (CCTK_EQUALS (file_content, "thorn"))
+ {
+ char const * const impname = CCTK_ImpFromVarI (variable);
+ char * const thornname = strdup (impname);
+ assert (thornname);
+ char * const colon = strchr (thornname, ':');
+ assert (colon);
+ * colon = '\0';
+ for (char * p = thornname; * p; ++ p)
+ {
+ *p = tolower (* p);
+ }
+ filename_buf << thornname;
+ free (thornname);
+ }
+ else if (CCTK_EQUALS (file_content, "everything"))
+ {
+ filename_buf << out_filename;
+ }
+ else
+ {
+ assert (0);
+ }
+
+ if (out_timesteps_per_file > 0)
+ {
+ int const iteration = (cctkGH->cctk_iteration
+ / out_timesteps_per_file * out_timesteps_per_file);
+ filename_buf << ".it"
+ << setw (iteration_digits) << setfill ('0') << iteration;
+ }
+
+ return filename_buf.str();
+ }
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/coordinate_system.cc b/CarpetDev/CarpetIOF5_standalone/src/coordinate_system.cc
new file mode 100644
index 000000000..e030c08a9
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/coordinate_system.cc
@@ -0,0 +1,166 @@
+#include <sstream>
+#include <string>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "coordinate_system.hh"
+#include "utils.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ coordinate_system_t::
+ coordinate_system_t (topology_t & topology)
+ : m_topology (topology)
+ {
+ }
+
+
+
+ coordinate_system_t::
+ ~ coordinate_system_t ()
+ {
+ }
+
+
+
+ topology_t & coordinate_system_t::
+ get_topology ()
+ const
+ {
+ return m_topology;
+ }
+
+
+
+ hid_t coordinate_system_t::
+ get_hdf5_coordinate_system ()
+ const
+ {
+ return m_hdf5_coordinate_system;
+ }
+
+
+
+ bool coordinate_system_t::
+ invariant ()
+ const
+ {
+ return true;
+ }
+
+
+
+ Cartesian_coordinate_system_t::
+ Cartesian_coordinate_system_t (topology_t & topology,
+ vect<CCTK_REAL, dim> const & level_origin,
+ vect<CCTK_REAL, dim> const & level_delta)
+ : coordinate_system_t (topology),
+ m_level_origin (level_origin),
+ m_level_delta (level_delta)
+ {
+ assert (all (m_level_delta > (CCTK_REAL) 0));
+
+ init();
+
+ assert (invariant());
+ }
+
+
+
+ Cartesian_coordinate_system_t::
+ Cartesian_coordinate_system_t (topology_t & topology,
+ vect<CCTK_REAL, dim> const & coarse_origin,
+ vect<CCTK_REAL, dim> const & coarse_delta,
+ vect<int, dim> const & level_offset,
+ vect<int, dim> const & level_offset_denominator)
+ : coordinate_system_t (topology)
+ {
+ assert (all (coarse_delta > (CCTK_REAL) 0));
+ assert (all (level_offset_denominator > 0));
+
+ mesh_refinement_topology_t * mesh_refinement_topology
+ = dynamic_cast<mesh_refinement_topology_t *> (& topology);
+ assert (mesh_refinement_topology != 0);
+ mesh_refinement_topology
+ ->calculate_level_origin_delta (coarse_origin, coarse_delta,
+ level_offset, level_offset_denominator,
+ m_level_origin, m_level_delta);
+
+ init();
+
+ assert (invariant());
+ }
+
+
+
+ Cartesian_coordinate_system_t::
+ ~ Cartesian_coordinate_system_t ()
+ {
+ check (not H5Gclose (m_hdf5_coordinate_system));
+ }
+
+
+
+ void Cartesian_coordinate_system_t::
+ init ()
+ {
+ assert (all (m_level_delta > (CCTK_REAL) 0));
+
+ ostringstream namebuf;
+ namebuf << "Cartesian3D-"
+ << name_from_ivect (m_level_origin)
+ << "-"
+ << name_from_ivect (m_level_delta);
+ string const namestr = namebuf.str();
+ m_name = namestr;
+ char const * const name = namestr.c_str();
+
+ m_hdf5_coordinate_system
+ = open_or_create_group (m_topology.get_hdf5_topology(), name);
+ assert (m_hdf5_coordinate_system >= 0);
+
+#warning "TODO: don't output coordinates as attributes"
+ write_or_check_attribute
+ (m_hdf5_coordinate_system, "origin", m_level_origin);
+ write_or_check_attribute
+ (m_hdf5_coordinate_system, "delta", m_level_delta);
+ }
+
+
+
+ void coordinate_system_t::
+ get_link_destination (int const proc,
+ string & filename,
+ string & objectname)
+ const
+ {
+ get_topology().get_link_destination (proc, filename, objectname);
+ if (objectname.empty())
+ {
+ objectname = m_name;
+ }
+ else
+ {
+ objectname += string ("/") + m_name;
+ }
+ }
+
+
+
+ bool Cartesian_coordinate_system_t::
+ invariant ()
+ const
+ {
+ return (coordinate_system_t::invariant()
+ and all (m_level_delta > (CCTK_REAL) 0));
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/coordinate_system.hh b/CarpetDev/CarpetIOF5_standalone/src/coordinate_system.hh
new file mode 100644
index 000000000..2b67b4561
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/coordinate_system.hh
@@ -0,0 +1,104 @@
+#ifndef COORDINATE_SYSTEM_HH
+#define COORDINATE_SYSTEM_HH
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "defs.hh"
+#include "vect.hh"
+
+#include "topology.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ class coordinate_system_t {
+
+ coordinate_system_t ();
+ coordinate_system_t (coordinate_system_t const &);
+ coordinate_system_t operator= (coordinate_system_t const &);
+
+ protected:
+
+ topology_t & m_topology;
+
+ string m_name;
+
+ hid_t m_hdf5_coordinate_system;
+
+ coordinate_system_t (topology_t & topology);
+
+ public:
+
+ virtual
+ ~ coordinate_system_t ();
+
+ topology_t &
+ get_topology ()
+ const;
+
+ hid_t
+ get_hdf5_coordinate_system ()
+ const;
+
+ void
+ get_link_destination (int proc,
+ string & filename,
+ string & objectname)
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+
+ };
+
+
+
+ class Cartesian_coordinate_system_t : public coordinate_system_t {
+
+ vect<CCTK_REAL, dim> m_level_origin;
+ vect<CCTK_REAL, dim> m_level_delta;
+
+ Cartesian_coordinate_system_t ();
+ Cartesian_coordinate_system_t (Cartesian_coordinate_system_t const &);
+ Cartesian_coordinate_system_t
+ operator= (Cartesian_coordinate_system_t const &);
+
+ public:
+
+ Cartesian_coordinate_system_t (topology_t & topology,
+ vect<CCTK_REAL, dim> const & level_origin,
+ vect<CCTK_REAL, dim> const & level_delta);
+
+ Cartesian_coordinate_system_t (topology_t & topology,
+ vect<CCTK_REAL, dim> const & coarse_origin,
+ vect<CCTK_REAL, dim> const & coarse_delta,
+ vect<int, dim> const & level_offset,
+ vect<int, dim> const & level_offset_denominator);
+
+ private:
+
+ void
+ init ();
+
+ public:
+
+ virtual
+ ~ Cartesian_coordinate_system_t ();
+
+ virtual bool
+ invariant ()
+ const;
+
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef COORDINATE_SYSTEM_HH
diff --git a/CarpetDev/CarpetIOF5_standalone/src/data_region.cc b/CarpetDev/CarpetIOF5_standalone/src/data_region.cc
new file mode 100644
index 000000000..99b188323
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/data_region.cc
@@ -0,0 +1,91 @@
+#include <cassert>
+#include <cstdlib>
+#include <sstream>
+#include <string>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "carpet.hh"
+
+#include "data_region.hh"
+#include "utils.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ using std::ostringstream;
+
+
+
+ data_region_t::
+ data_region_t (physical_quantity_t & physical_quantity,
+ bbox<int, dim> const & region)
+ : m_physical_quantity (physical_quantity),
+ m_region (region),
+ m_name (string ("region-") + F5::name_from_ibbox (region))
+ {
+ assert (not region.empty());
+
+ m_hdf5_data_region
+ = open_or_create_group (m_physical_quantity
+ .get_hdf5_physical_quantity(),
+ m_name.c_str());
+ assert (m_hdf5_data_region >= 0);
+
+ assert (invariant());
+ }
+
+
+
+ data_region_t::
+ ~ data_region_t ()
+ {
+ herr_t const herr = H5Gclose (m_hdf5_data_region);
+ assert (not herr);
+ }
+
+
+
+ physical_quantity_t & data_region_t::
+ get_physical_quantity ()
+ const
+ {
+ return m_physical_quantity;
+ }
+
+
+
+ bbox<int, dim> const & data_region_t::
+ get_region ()
+ const
+ {
+ return m_region;
+ }
+
+
+
+ hid_t data_region_t::
+ get_hdf5_data_region ()
+ const
+ {
+ return m_hdf5_data_region;
+ }
+
+
+
+ bool data_region_t::
+ invariant ()
+ const
+ {
+ return (not m_region.empty()
+ and m_hdf5_data_region >= 0);
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/data_region.hh b/CarpetDev/CarpetIOF5_standalone/src/data_region.hh
new file mode 100644
index 000000000..35e5ecc79
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/data_region.hh
@@ -0,0 +1,64 @@
+#ifndef DATA_REGION_HH
+#define DATA_REGION_HH
+
+#include <string>
+
+#include <hdf5.h>
+
+#include "bbox.hh"
+#include "defs.hh"
+
+#include "physical_quantity.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ using std::string;
+
+ class data_region_t {
+
+ physical_quantity_t & m_physical_quantity;
+
+ bbox<int, dim> const m_region;
+ string const m_name;
+
+ hid_t m_hdf5_data_region;
+
+ data_region_t ();
+ data_region_t (data_region_t const &);
+ data_region_t operator= (data_region_t const &);
+
+ public:
+
+ data_region_t (physical_quantity_t & physical_quantity,
+ bbox<int, dim> const & region);
+
+ virtual
+ ~ data_region_t ();
+
+ physical_quantity_t &
+ get_physical_quantity ()
+ const;
+
+ bbox<int, dim> const &
+ get_region ()
+ const;
+
+ hid_t
+ get_hdf5_data_region ()
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef DATA_REGION_HH
diff --git a/CarpetDev/CarpetIOF5_standalone/src/extending.cc b/CarpetDev/CarpetIOF5_standalone/src/extending.cc
new file mode 100644
index 000000000..26d63cb60
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/extending.cc
@@ -0,0 +1,113 @@
+#include <cassert>
+#include <cstring>
+
+#include "cctk.h"
+
+#include "extending.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ char const * const extending_t::
+ extension_name = "CarpetIOF5";
+
+ int extending_t::
+ create (void * (* const Setup) (tFleshConfig * config,
+ int convlevel,
+ cGH * cctkGH))
+ {
+ int const handle = CCTK_RegisterGHExtension (extension_name);
+ assert (handle >= 0);
+ int const iflag = CCTK_RegisterGHExtensionSetupGH (handle, Setup);
+ assert (iflag);
+ return 0; // no error
+ }
+
+ void * extending_t::
+ setup (cGH * const cctkGH,
+ int (* const OutputGH) (cGH const * cctkGH),
+ int (* const TimeToOutput) (cGH const * cctkGH,
+ int variable),
+ int (* const TriggerOutput) (cGH const * cctkGH,
+ int variable),
+ int (* const OutputVarAs) (cGH const * cctkGH,
+ char const * varname,
+ char const * alias))
+ {
+ assert (cctkGH != 0);
+
+ int ierr;
+ int const io_method = CCTK_RegisterIOMethod (extension_name);
+ ierr = CCTK_RegisterIOMethodOutputGH (io_method, OutputGH);
+ assert (not ierr);
+ ierr = CCTK_RegisterIOMethodTimeToOutput (io_method, TimeToOutput);
+ assert (not ierr);
+ ierr = CCTK_RegisterIOMethodTriggerOutput (io_method, TriggerOutput);
+ assert (not ierr);
+ ierr = CCTK_RegisterIOMethodOutputVarAs (io_method, OutputVarAs);
+ assert (not ierr);
+
+ return new extension_t;
+ }
+
+ extending_t::
+ extending_t (cGH const * cctkGH)
+ {
+ assert (cctkGH);
+ void * const ext = CCTK_GHExtension (cctkGH, extension_name);
+ assert (ext != 0);
+ m_extension = static_cast<extension_t *> (ext);
+ }
+
+ bool extending_t::
+ get_did_truncate (string const name)
+ const
+ {
+ return (m_extension->did_truncate.find (name)
+ != m_extension->did_truncate.end());
+ }
+
+ void extending_t::
+ set_did_truncate (string const name)
+ {
+ m_extension->did_truncate.insert (name);
+ }
+
+ int extending_t::
+ get_last_output_iteration (int const ml, int const rl, int const vi)
+ const
+ {
+ resize_last_output_iteration (ml, rl, vi);
+ return m_extension->last_output_iteration.at(ml).at(rl).at(vi);
+ }
+
+ void extending_t::
+ set_last_output_iteration (int const ml, int const rl, int const vi,
+ int const iteration)
+ {
+ resize_last_output_iteration (ml, rl, vi);
+ m_extension->last_output_iteration.at(ml).at(rl).at(vi) = iteration;
+ }
+
+ void extending_t::
+ resize_last_output_iteration (int ml, int rl, int vi)
+ const
+ {
+ assert (ml >= 0);
+ if (size_t (ml) >= m_extension->last_output_iteration.size())
+ {
+ m_extension->last_output_iteration.resize (ml+1);
+ }
+ assert (rl >= 0);
+ if (size_t (rl) >= m_extension->last_output_iteration.at(ml).size())
+ {
+ m_extension->last_output_iteration.at(ml).resize (rl+1);
+ }
+ if (size_t (vi) >= m_extension->last_output_iteration.at(ml).at(rl).size())
+ {
+ m_extension->last_output_iteration.at(ml).at(rl).resize (vi+1, -1);
+ }
+ }
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/extending.hh b/CarpetDev/CarpetIOF5_standalone/src/extending.hh
new file mode 100644
index 000000000..4f9bc9cc1
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/extending.hh
@@ -0,0 +1,76 @@
+#ifndef EXTENDING_HH
+#define EXTENDING_HH
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "cctk.h"
+
+
+
+namespace CarpetIOF5 {
+
+ using std::set;
+ using std::string;
+ using std::vector;
+
+
+
+ class extending_t {
+
+ static char const * const extension_name;
+
+ struct extension_t {
+ set<string> did_truncate;
+ // [mglevel][reflevel][variable];
+ vector<vector<vector<int> > > last_output_iteration;
+ };
+
+ extension_t * m_extension;
+
+ public:
+
+ static int
+ create (void * (* Setup) (tFleshConfig * config,
+ int convlevel,
+ cGH * cctkGH));
+
+ static void *
+ setup (cGH * cctkGH,
+ int (* OutputGH) (cGH const * cctkGH),
+ int (* TimeToOutput) (cGH const * cctkGH,
+ int variable),
+ int (* TriggerOutput) (cGH const * cctkGH,
+ int variable),
+ int (* OutputVarAs) (cGH const * cctkGH,
+ char const * varname,
+ char const * alias));
+
+ extending_t (cGH const * cctkGH);
+
+ bool
+ get_did_truncate (string name)
+ const;
+
+ void
+ set_did_truncate (string name);
+
+ int
+ get_last_output_iteration (int ml, int rl, int vi)
+ const;
+
+ void
+ set_last_output_iteration (int ml, int rl, int vi, int iteration);
+
+ private:
+
+ void
+ resize_last_output_iteration (int ml, int rl, int vi)
+ const;
+
+ };
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef EXDENDING_HH
diff --git a/CarpetDev/CarpetIOF5_standalone/src/f5writer.cc b/CarpetDev/CarpetIOF5_standalone/src/f5writer.cc
new file mode 100644
index 000000000..b351c7391
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/f5writer.cc
@@ -0,0 +1,445 @@
+#include <sstream>
+#include <string>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+
+#include "carpet.hh"
+
+#include "data_region.hh"
+#include "f5writer.hh"
+#include "file.hh"
+#include "meta_data_region.hh"
+#include "physical_quantity.hh"
+#include "simulation.hh"
+#include "tensor_component.hh"
+#include "timestep.hh"
+#include "topology.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ f5writer_t::
+ f5writer_t (cGH const * const cctkGH,
+ int const variable)
+ : m_cctkGH (cctkGH),
+ m_variable (variable)
+ {
+ }
+
+
+
+ void f5writer_t::
+ write (F5::file_t & file)
+ const
+ {
+ write_meta (file, file.get_have_metafile());
+ }
+
+
+
+ void f5writer_t::
+ write_meta (F5::file_t & file,
+ bool const have_metafile)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_meta");
+ }
+
+ if (Carpet::is_meta_mode())
+ {
+ for (Carpet::mglevel_iterator mglevel_iter (m_cctkGH);
+ not mglevel_iter.done();
+ mglevel_iter.step())
+ {
+ write_one_mglevel (file, have_metafile);
+ }
+ }
+ else
+ {
+ write_one_mglevel (file, have_metafile);
+ }
+ }
+
+
+
+ void f5writer_t::
+ write_one_mglevel (F5::file_t & file,
+ bool const have_metafile)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_mglevel mglevel=%d",
+ Carpet::mglevel);
+ }
+
+ // ostringstream namebuf;
+ // namebuf << "convlevel=" << m_cctkGH->cctk_convlevel;
+ // string const namestr = namebuf.str();
+ // char const * const name = namestr.c_str();
+
+ int const grouptype = CCTK_GroupTypeFromVarI (m_variable);
+ assert (grouptype >= 0);
+ switch (grouptype)
+ {
+ case CCTK_ARRAY:
+ case CCTK_SCALAR:
+ {
+ if (Carpet::do_global_mode)
+ {
+ write_global (file, have_metafile);
+ }
+ }
+ break;
+ case CCTK_GF:
+ {
+ if (Carpet::is_global_mode())
+ {
+ for (Carpet::reflevel_iterator reflevel_iter (m_cctkGH);
+ not reflevel_iter.done();
+ reflevel_iter.step())
+ {
+ write_one_reflevel (file, have_metafile);
+ }
+ }
+ else
+ {
+ write_one_reflevel (simulation, have_metafile);
+ }
+ }
+ break;
+ default:
+ assert (0);
+ }
+ }
+
+
+
+ void f5writer_t::
+ write_global (F5::simulation_t & simulation,
+ bool const have_metafile)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_INFO ("OutputVarAs/write_global");
+ }
+
+ F5::unigrid_topology_t topology (simulation);
+
+ int const grouptype = CCTK_GroupTypeFromVarI (m_variable);
+ assert (grouptype >= 0);
+ assert (grouptype == CCTK_SCALAR or grouptype == CCTK_ARRAY);
+
+ vect<CCTK_REAL, dim> level_origin, level_delta;
+ for (int d=0; d<dim; ++d)
+ {
+ level_origin[d] = 0.0;
+ level_delta[d] = 1.0;
+ }
+ F5::Cartesian_coordinate_system_t coordinate_system
+ (topology, level_origin, level_delta);
+
+ int const group = CCTK_GroupIndexFromVarI (m_variable);
+ assert (group >= 0 and group < CCTK_NumGroups());
+ F5::physical_quantity_t physical_quantity (coordinate_system, group);
+
+ int const map = 0;
+ int const reflevel = 0;
+ int const myproc = CCTK_MyProc (m_cctkGH);
+ dh * const dd = Carpet::arrdata.at(group).at(map).dd;
+ dh::dboxes const & boxes
+ = dd->boxes.at(Carpet::mglevel).at(reflevel).at(myproc);
+ bbox<int, dim> const & region = determine_region (boxes);
+
+ if (have_metafile)
+ {
+ F5::meta_data_region_t meta_data_region (physical_quantity, region);
+ gh * const hh = Carpet::vhh.at(Carpet::map);
+ int const proc = hh->processor (Carpet::reflevel, Carpet::component);
+ meta_data_region.write (proc);
+ }
+
+ F5::data_region_t data_region (physical_quantity, region);
+
+ F5::tensor_component_t tensor_component (data_region, m_variable);
+ int const timelevel = 0;
+ void const * const varptr
+ = CCTK_VarDataPtrI (m_cctkGH, timelevel, m_variable);
+ assert (varptr != 0);
+ int const vartype = CCTK_VarTypeI (m_variable);
+ assert (vartype >= 0);
+ tensor_component.write (varptr, vartype);
+ }
+
+
+
+ void f5writer_t::
+ write_one_reflevel (F5::file_t & file,
+ bool const have_metafile)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_reflevel reflevel=%d",
+ Carpet::reflevel);
+ }
+
+ // int const grouptype = CCTK_GroupTypeFromVarI (m_variable);
+ // assert (grouptype >= 0);
+ // assert (grouptype == CCTK_GF);
+
+ // A name for the simulation
+ string sim_id;
+ if (CCTK_IsFunctionAliased ("UniqueSimulationID"))
+ {
+ sim_id = static_cast<char const *> (UniqueSimulationID (m_cctkGH));
+ }
+ else {
+ char parfilename[10000];
+ int const len = CCTK_ParameterFilename (sizeof parfilename, parfilename);
+ assert (len >= 0 and len < sizeof parfilename);
+ sim_id = parfilename;
+ if (sim_id.length() >= 4
+ and sim_id.substr (sim_id.length() - 4) == ".par")
+ {
+ sim_id = sim_id.substr (0, sim_id.length() - 4);
+ }
+ }
+
+ // Refinement factor of current refinement level
+ vect <hsize_t, dim> const current_refinement
+ = vect <int, dim>::ref (m_cctkGH->cctk_levfac);
+
+ // Refinement factor of root refinement level
+ vect <hsize_t, dim> const rootlevel_refinement (1);
+
+ // Remember time when the root level was output the last time
+ static CCTK_REAL rootlevel_time = 0.0;
+ if (all (current_refinement == 1))
+ {
+ rootlevel_time = m_cctkGH->cctk_time;
+ }
+
+ F5Path * refinement_path = NULL;
+ if (any (current_refinement != 1))
+ {
+ refinement_path
+ = F5Rcreate_relative_vertex_Qrefinement3D (file,
+ m_cctkGH->cctk_time,
+ sim_id.c_str(),
+ current_refinement,
+ rootlevel_time,
+ rootlevel_refinement);
+ }
+
+#warning "TODO: what is this doing?"
+ F5T_REFINEMENT3D_POINT = refinement_path->myChart->Point_hid_t;
+
+ if (Carpet::is_level_mode())
+ {
+ for (Carpet::map_iterator map_iter (m_cctkGH, grouptype);
+ not map_iter.done();
+ map_iter.step())
+ {
+ write_one_map (simulation, have_metafile);
+ }
+ }
+ else
+ {
+ write_one_map (simulation, have_metafile);
+ }
+ }
+
+
+
+ void f5writer_t::
+ write_one_map (F5::simulation_t & simulation,
+ bool const have_metafile)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_map map=%d", Carpet::map);
+ }
+
+ // F5::mesh_refinement_topology_t topology
+ // (simulation, Carpet::map, Carpet::reflevel, Carpet::maxreflevels,
+ // Carpet::spacereflevelfact, Carpet::maxspacereflevelfact);
+
+ // vect<CCTK_REAL, dim> level_origin, level_delta;
+ // for (int d=0; d<dim; ++d)
+ // {
+ // cGH const * const cctkGH = m_cctkGH;
+ // DECLARE_CCTK_ARGUMENTS;
+ // level_origin[d] = CCTK_ORIGIN_SPACE(d);
+ // level_delta[d] = CCTK_DELTA_SPACE(d);
+ // }
+ // F5::Cartesian_coordinate_system_t coordinate_system
+ // (topology, level_origin, level_delta);
+ //
+ // int const group = CCTK_GroupIndexFromVarI (m_variable);
+ // assert (group >= 0 and group < CCTK_NumGroups());
+ // F5::physical_quantity_t physical_quantity (coordinate_system, group);
+
+#warning "TODO: this should depend on the patch number"
+ char const * const coordinate_system = NULL;
+
+ // Depends on the refinement level
+ string const gridname = sim_id + "-" + current_refinement;
+
+ F5Path * const myPath
+ = F5Rcreate_vertex_refinement3D (file,
+ m_cctkGH->cctk_time,
+ sim_id.c_str(),
+ refinement,
+ coordinate_system);
+
+ if (not refinement_path)
+ {
+ // Make root level appear as unigrid topology as well, just to
+ // be nice to tools that do not understand AMR
+ F5Rlink_default_vertex_topology (myPath, current_refinement);
+ }
+
+ // Global information for this refinement level
+ vect <hsize_t, dim> const level_dims
+ = vect <int, dim>::ref (m_cctkGH->cctk_gsh);
+#warning "TODO: switch to double precision"
+ vect <float, dim> const level_min
+ (CCTK_ORIGIN_SPACE(0), CCTK_ORIGIN_SPACE(1), CCTK_ORIGIN_SPACE(2));
+ vect <float, dim> const level_spacing
+ (CCTK_DELTA_SPACE(0), CCTK_DELTA_SPACE(1), CCTK_DELTA_SPACE(2));
+ vect <float, dim> const level_max
+ = level_min + level_spacing * (level_dims - 1);
+
+ // Output geometric information for an entire level; it is
+ // uniformely covered in coordinate space
+ assert (dim == 3);
+ F5Fwrite_linear (myPath, FIBER_HDF5_POSITIONS_STRING,
+ dim, & level_dims [0],
+ F5T_COORD3_FLOAT, & level_min [0], & level_spacing [0]);
+
+ F5Fset_range (myPath, & level_min [0], & level_max [0]);
+
+#error "CONTINUE HERE"
+
+ if (Carpet::is_singlemap_mode())
+ {
+ int const grouptype = CCTK_GroupTypeI (group);
+ assert (grouptype >= 0);
+
+ for (Carpet::component_iterator component_iter (m_cctkGH, grouptype);
+ not component_iter.done();
+ component_iter.step())
+ {
+ write_one_component (physical_quantity, have_metafile);
+ }
+ }
+ else
+ {
+ write_one_component (physical_quantity, have_metafile);
+ }
+ }
+
+
+
+ void f5writer_t::
+ write_one_component (F5::physical_quantity_t & physical_quantity,
+ bool const have_metafile)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_component component=%d",
+ Carpet::component);
+ }
+
+ gh * const hh = Carpet::vhh.at(Carpet::map);
+ bool const is_local = hh->is_local (Carpet::reflevel, Carpet::component);
+ if (have_metafile or is_local)
+ {
+ dh * const dd = Carpet::vdd.at(Carpet::map);
+ bbox<int, dim> const & region
+ = (dd->boxes.at(Carpet::mglevel).at(Carpet::reflevel)
+ .at(Carpet::component).exterior);
+
+ if (have_metafile)
+ {
+ F5::meta_data_region_t meta_data_region (physical_quantity, region);
+ int const proc = hh->processor (Carpet::reflevel, Carpet::component);
+ meta_data_region.write (proc);
+ }
+
+ if (is_local)
+ {
+ F5::data_region_t data_region (physical_quantity, region);
+
+ F5::tensor_component_t tensor_component (data_region, m_variable);
+ int const timelevel = 0;
+ void const * const varptr
+ = CCTK_VarDataPtrI (m_cctkGH, timelevel, m_variable);
+ assert (varptr != 0);
+ int const vartype = CCTK_VarTypeI (m_variable);
+ assert (vartype >= 0);
+ tensor_component.write (varptr, vartype);
+ }
+ }
+ }
+
+
+
+ bbox<int,dim> const & f5writer_t::
+ determine_region (dh::dboxes const & boxes)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+#warning "TODO: use superregions instead of regions (? only if the regions are on the same processor?); use HDF5 chunks as well"
+
+ bbox<int,dim> dh::dboxes::* boxptr;
+ if (CCTK_EQUALS (output_regions, "exterior"))
+ {
+ boxptr = & dh::dboxes::exterior;
+ }
+ else if (CCTK_EQUALS (output_regions, "owned"))
+ {
+ boxptr = & dh::dboxes::owned;
+ }
+ else if (CCTK_EQUALS (output_regions, "interior"))
+ {
+ boxptr = & dh::dboxes::interior;
+ }
+ else
+ {
+ assert (0);
+ }
+
+ return boxes.*boxptr;
+ }
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/f5writer.hh b/CarpetDev/CarpetIOF5_standalone/src/f5writer.hh
new file mode 100644
index 000000000..ae016721e
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/f5writer.hh
@@ -0,0 +1,74 @@
+#ifndef F5WRITER_HH
+#define F5WRITER_HH
+
+#include "cctk.h"
+
+#include "bbox.hh"
+#include "defs.hh"
+#include "dh.hh"
+
+#include "file.hh"
+#include "physical_quantity.hh"
+#include "simulation.hh"
+#include "timestep.hh"
+#include "topology.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ class f5writer_t {
+
+ cGH const * const m_cctkGH;
+ int const m_variable;
+
+ public:
+
+ f5writer_t (cGH const * cctkGH,
+ int variable);
+
+ void
+ write (F5::file_t & file)
+ const;
+
+ private:
+
+ void
+ write_meta (F5::file_t & file,
+ bool have_metafile)
+ const;
+
+ void
+ write_one_mglevel (F5::timestep_t & timestep,
+ bool have_metafile)
+ const;
+
+ void
+ write_global (F5::simulation_t & simulation,
+ bool have_metafile)
+ const;
+
+ void
+ write_one_reflevel (F5::simulation_t & simulation,
+ bool have_metafile)
+ const;
+
+ void
+ write_one_map (F5::simulation_t & simulation,
+ bool have_metafile)
+ const;
+
+ void
+ write_one_component (F5::physical_quantity_t & physical_quantity,
+ bool have_metafile)
+ const;
+
+ bbox<int,dim> const &
+ determine_region (dh::dboxes const & boxes)
+ const;
+
+ };
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef F5WRITER_HH
diff --git a/CarpetDev/CarpetIOF5_standalone/src/file.cc b/CarpetDev/CarpetIOF5_standalone/src/file.cc
new file mode 100644
index 000000000..d78dcb001
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/file.cc
@@ -0,0 +1,272 @@
+#include <algorithm>
+#include <cassert>
+#include <iomanip>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+
+#include "defs.hh"
+
+#include "file.hh"
+#include "utils.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ using namespace std;
+
+ file_t::
+ file_t (cGH const * const cctkGH,
+ string const path,
+ string const basename,
+ string const extension,
+ bool const do_truncate,
+ bool const is_metafile,
+ bool const is_datafile)
+ : m_cctkGH (cctkGH),
+ m_path (path),
+ m_basename (basename),
+ m_extension (extension),
+ m_is_metafile (is_metafile),
+ m_is_datafile (is_datafile)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ assert (cctkGH);
+
+ // Create file names, creating subdirectories to avoid placing
+ // too many files into the same directory
+ check (CCTK_CreateDirectory (mode, path.c_str()) >= 0);
+ if (is_metafile)
+ {
+ m_filename = basename + extension;
+ }
+ else
+ {
+ int const myproc = CCTK_MyProc (cctkGH);
+ m_filename = create_filename (myproc, true);
+ }
+ string const filepath = m_path + "/" + m_filename;
+
+ htri_t is_hdf5;
+ H5E_BEGIN_TRY {
+ is_hdf5 = H5Fis_hdf5 (filepath.c_str());
+ } H5E_END_TRY;
+ bool const file_exists = is_hdf5 > 0;
+
+ if (do_truncate or not file_exists)
+ {
+ if (veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "H5Fcreate (name=\"%s\")", filepath.c_str());
+ }
+ m_hdf5_file
+ = H5Fcreate (filepath.c_str(),
+ H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ }
+ else
+ {
+ if (veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "H5Fopen (name=\"%s\")", filepath.c_str());
+ }
+ m_hdf5_file = H5Fopen (filepath.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
+ }
+ assert (m_hdf5_file >= 0);
+
+ m_hdf5_fiber_contents = -1;
+ m_hdf5_fiber_global_charts = -1;
+ m_hdf5_fiber_parameter_space = -1;
+ if (m_is_metafile)
+ {
+ create_or_check_version (m_hdf5_file);
+ m_hdf5_fiber_contents
+ = open_or_create_group (m_hdf5_file, "TableOfContents");
+ assert (m_hdf5_fiber_contents >= 0);
+ m_hdf5_fiber_global_charts
+ = open_or_create_group (m_hdf5_file, "Charts");
+ assert (m_hdf5_fiber_global_charts >= 0);
+ m_hdf5_fiber_parameter_space
+ = open_or_create_group (m_hdf5_fiber_contents, "Parameters");
+ assert (m_hdf5_fiber_parameter_space >= 0);
+
+ hid_t const hdf5_time_group
+ = open_or_create_group (m_hdf5_fiber_parameter_space, "Time");
+ assert (hdf5_time_group >= 0);
+ check (not H5Gclose (hdf5_time_group));
+ }
+
+ assert (invariant());
+ }
+
+
+
+ file_t::
+ ~ file_t()
+ {
+ if (m_is_metafile)
+ {
+ check (not H5Gclose (m_hdf5_fiber_parameter_space));
+ check (not H5Gclose (m_hdf5_fiber_contents));
+ check (not H5Gclose (m_hdf5_fiber_global_charts));
+ }
+ check (not H5Fclose (m_hdf5_file));
+ }
+
+
+
+ string file_t::
+ create_filename (int const proc, bool const create_directories)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ int const nprocs = CCTK_nProcs (m_cctkGH);
+ string extrapath;
+ if (create_subdirs)
+ {
+ if (nprocs >= 10000)
+ {
+ ostringstream buf;
+ buf << extrapath
+ << m_basename
+ << ".p" << setw (max (0, processor_digits - 4)) << setfill ('0')
+ << proc / 10000
+ << "nnnn/";
+ extrapath = buf.str();
+ if (create_directories)
+ {
+ string const filepath = m_path + "/" + extrapath;
+ check (CCTK_CreateDirectory (mode, filepath.c_str()) >= 0);
+ }
+ }
+ if (nprocs >= 100)
+ {
+ ostringstream buf;
+ buf << extrapath
+ << m_basename
+ << ".p" << setw (max (0, processor_digits - 2)) << setfill ('0')
+ << proc / 100
+ << "nn/";
+ extrapath = buf.str();
+ if (create_directories)
+ {
+ string const filepath = m_path + "/" + extrapath;
+ check (CCTK_CreateDirectory (mode, filepath.c_str()) >= 0);
+ }
+ }
+ }
+ if (one_dir_per_file and nprocs >= 1)
+ {
+ ostringstream buf;
+ buf << extrapath
+ << m_basename
+ << ".p" << setw (processor_digits) << setfill ('0')
+ << proc
+ << "/";
+ extrapath = buf.str();
+ if (create_directories)
+ {
+ string const filepath = m_path + "/" + extrapath;
+ check (CCTK_CreateDirectory (mode, filepath.c_str()) >= 0);
+ }
+ }
+ ostringstream buf;
+ buf << extrapath
+ << m_basename
+ << ".p" << setw (processor_digits) << setfill ('0') << proc
+ << m_extension;
+ return buf.str();
+ }
+
+
+
+ void file_t::
+ create_or_check_version (hid_t const hdf5_file)
+ {
+ hid_t const hdf5_group = open_or_create_group (hdf5_file, "version");
+ assert (hdf5_group >= 0);
+ string const version ("http://www.zib.de/visual/F5-0.1.2/");
+ write_or_check_attribute (hdf5_group, "version", version.c_str());
+ check (not H5Gclose (hdf5_group));
+ }
+
+
+
+ cGH const * file_t::
+ get_cctkGH ()
+ const
+ {
+ return m_cctkGH;
+ }
+
+
+
+ hid_t file_t::
+ get_hdf5_file ()
+ const
+ {
+ return m_hdf5_file;
+ }
+
+
+
+ hid_t file_t::
+ get_hdf5_fiber_parameter_space ()
+ const
+ {
+ return m_hdf5_fiber_parameter_space;
+ }
+
+
+
+ bool file_t::
+ get_is_metafile ()
+ const
+ {
+ return m_is_metafile;
+ }
+
+
+
+ bool file_t::
+ get_is_datafile ()
+ const
+ {
+ return m_is_datafile;
+ }
+
+
+
+ void file_t::
+ get_link_destination (int const proc,
+ string & filename,
+ string & objectname)
+ const
+ {
+ filename = create_filename (proc);
+ objectname = "";
+ }
+
+
+
+ bool file_t::
+ invariant()
+ const
+ {
+ return m_cctkGH != 0 and m_hdf5_file >= 0;
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/file.hh b/CarpetDev/CarpetIOF5_standalone/src/file.hh
new file mode 100644
index 000000000..44d8ce00c
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/file.hh
@@ -0,0 +1,103 @@
+#ifndef FILE_HH
+#define FILE_HH
+
+#include <string>
+#include <vector>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "extending.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ using std::string;
+ using std::vector;
+
+
+
+ namespace F5 {
+
+ class file_t {
+
+ // File mode for creating directories
+ static int const mode = 0755;
+
+ cGH const * const m_cctkGH;
+
+ string const m_path;
+ string const m_basename;
+ string const m_extension;
+ string m_filename;
+
+ bool const m_is_metafile;
+ bool const m_is_datafile;
+
+ hid_t m_hdf5_file;
+
+ hid_t m_hdf5_fiber_contents;
+ hid_t m_hdf5_fiber_global_charts;
+ hid_t m_hdf5_fiber_parameter_space;
+
+ file_t ();
+ file_t (file_t const &);
+ file_t operator= (file_t const &);
+
+ string
+ create_filename (int proc,
+ bool create_directories = false)
+ const;
+
+ static void
+ create_or_check_version (hid_t const hdf5_file);
+
+ public:
+
+ file_t (cGH const * cctkGH,
+ string path,
+ string basename,
+ string extension,
+ bool do_truncate,
+ bool is_metafile,
+ bool is_datafile);
+
+ virtual
+ ~ file_t ();
+
+ cGH const *
+ get_cctkGH ()
+ const;
+
+ hid_t
+ get_hdf5_file ()
+ const;
+
+ hid_t
+ get_hdf5_fiber_parameter_space ()
+ const;
+
+ bool get_is_metafile ()
+ const;
+
+ bool get_is_datafile ()
+ const;
+
+ void
+ get_link_destination (int proc,
+ string & filename,
+ string & objectname)
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef FILE_HH
diff --git a/CarpetDev/CarpetIOF5_standalone/src/make.code.defn b/CarpetDev/CarpetIOF5_standalone/src/make.code.defn
new file mode 100644
index 000000000..d0350d235
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/make.code.defn
@@ -0,0 +1,19 @@
+# Main make.code.defn file for thorn CarpetIOF5
+
+# Source files in this directory
+SRCS = IOF5.cc \
+ coordinate_system.cc \
+ data_region.cc \
+ extending.cc \
+ file.cc \
+ meta_data_region.cc \
+ physical_quantity.cc \
+ simulation.cc \
+ tensor_component.cc \
+ timestep.cc \
+ topology.cc \
+ utils.cc \
+ writer.cc
+
+# Subdirectories containing source files
+SUBDIRS =
diff --git a/CarpetDev/CarpetIOF5_standalone/src/meta_data_region.cc b/CarpetDev/CarpetIOF5_standalone/src/meta_data_region.cc
new file mode 100644
index 000000000..88963ec34
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/meta_data_region.cc
@@ -0,0 +1,116 @@
+#include <cassert>
+#include <cstdlib>
+#include <sstream>
+#include <string>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "carpet.hh"
+
+#include "defs.hh"
+
+#include "meta_data_region.hh"
+#include "utils.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ using std::ostringstream;
+
+
+
+ meta_data_region_t::
+ meta_data_region_t (physical_quantity_t & physical_quantity,
+ bbox<int, dim> const & region)
+ : m_physical_quantity (physical_quantity),
+ m_region (region),
+ m_name (string ("region-") + F5::name_from_ibbox (region))
+ {
+ assert (not region.empty());
+
+ assert (invariant());
+ }
+
+
+
+ meta_data_region_t::
+ ~ meta_data_region_t ()
+ {
+ }
+
+
+
+ physical_quantity_t & meta_data_region_t::
+ get_physical_quantity ()
+ const
+ {
+ return m_physical_quantity;
+ }
+
+
+
+ void meta_data_region_t::
+ write (int const proc)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ string filename;
+ string objectname;
+ get_physical_quantity().get_link_destination (proc, filename, objectname);
+
+ hid_t const hdf5_physical_quantity
+ = m_physical_quantity.get_hdf5_physical_quantity();
+
+ bool link_exists;
+ H5E_BEGIN_TRY {
+ H5L_info_t linkbuf;
+ herr_t const herr
+ = H5Lget_info (hdf5_physical_quantity, m_name.c_str(),
+ & linkbuf, H5P_DEFAULT);
+ link_exists = herr == 0;
+ } H5E_END_TRY;
+ if (veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "Link \"%s\" %s",
+ m_name.c_str(),
+ link_exists ? "exists" : "does not exist");
+ }
+
+ if (not link_exists)
+ {
+ if (veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "H5Lcreate_external "
+ "(filename=\"%s\", objectname=\"%s\", linkname=\"%s\")",
+ filename.c_str(),
+ objectname.c_str(),
+ m_name.c_str());
+ }
+ check (not H5Lcreate_external (filename.c_str(),
+ objectname.c_str(),
+ hdf5_physical_quantity,
+ m_name.c_str(),
+ H5P_DEFAULT, H5P_DEFAULT));
+ }
+ }
+
+
+
+ bool meta_data_region_t::
+ invariant ()
+ const
+ {
+ return not m_region.empty();
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/meta_data_region.hh b/CarpetDev/CarpetIOF5_standalone/src/meta_data_region.hh
new file mode 100644
index 000000000..ac59c18e2
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/meta_data_region.hh
@@ -0,0 +1,62 @@
+#ifndef META_DATA_REGION_HH
+#define META_DATA_REGION_HH
+
+#include <string>
+
+#include <hdf5.h>
+
+#include "bbox.hh"
+#include "defs.hh"
+
+#include "physical_quantity.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ using std::string;
+
+ class meta_data_region_t {
+
+ physical_quantity_t & m_physical_quantity;
+
+ bbox<int, dim> const m_region;
+ string const m_name;
+
+ hid_t m_properties;
+ hid_t m_dataset;
+ hid_t m_dataspace;
+
+ meta_data_region_t ();
+ meta_data_region_t (meta_data_region_t const &);
+ meta_data_region_t operator= (meta_data_region_t const &);
+
+ public:
+
+ meta_data_region_t (physical_quantity_t & physical_quantity,
+ bbox<int, dim> const & region);
+
+ virtual
+ ~ meta_data_region_t ();
+
+ physical_quantity_t &
+ get_physical_quantity ()
+ const;
+
+ void
+ write (int proc)
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef META_DATA_REGION_HH
diff --git a/CarpetDev/CarpetIOF5_standalone/src/physical_quantity.cc b/CarpetDev/CarpetIOF5_standalone/src/physical_quantity.cc
new file mode 100644
index 000000000..d0cb78dcd
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/physical_quantity.cc
@@ -0,0 +1,119 @@
+#include <cassert>
+#include <cstdlib>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "physical_quantity.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ physical_quantity_t::
+ physical_quantity_t (coordinate_system_t & coordinate_system,
+ int const group)
+ : m_coordinate_system (coordinate_system),
+ m_group (group)
+ {
+ assert (group >= 0 and group < CCTK_NumGroups());
+
+ char * const name = CCTK_GroupName (group);
+ assert (name != 0);
+ for (char * p = name; * p; ++ p)
+ {
+ * p = static_cast<char> (tolower (* p));
+ }
+ m_name = string (name);
+
+ m_hdf5_physical_quantity
+ = open_or_create_group (m_coordinate_system
+ .get_hdf5_coordinate_system(),
+ name);
+ assert (m_hdf5_physical_quantity >= 0);
+
+ free (name);
+
+ assert (invariant());
+ }
+
+
+
+ physical_quantity_t::
+ ~ physical_quantity_t ()
+ {
+ herr_t const herr = H5Gclose (m_hdf5_physical_quantity);
+ assert (not herr);
+ }
+
+
+
+ coordinate_system_t & physical_quantity_t::
+ get_coordinate_system ()
+ const
+ {
+ return m_coordinate_system;
+ }
+
+
+
+ int physical_quantity_t::
+ get_group ()
+ const
+ {
+ return m_group;
+ }
+
+
+
+ string physical_quantity_t::
+ get_name ()
+ const
+ {
+ return m_name;
+ }
+
+
+
+ hid_t physical_quantity_t::
+ get_hdf5_physical_quantity ()
+ const
+ {
+ return m_hdf5_physical_quantity;
+ }
+
+
+
+ void physical_quantity_t::
+ get_link_destination (int const proc,
+ string & filename,
+ string & objectname)
+ const
+ {
+ get_coordinate_system().get_link_destination (proc, filename, objectname);
+ if (objectname.empty())
+ {
+ objectname = m_name;
+ }
+ else
+ {
+ objectname += string ("/") + m_name;
+ }
+ }
+
+
+
+ bool physical_quantity_t::
+ invariant ()
+ const
+ {
+ return (m_group >= 0 and m_group < CCTK_NumGroups()
+ and m_hdf5_physical_quantity >= 0);
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/physical_quantity.hh b/CarpetDev/CarpetIOF5_standalone/src/physical_quantity.hh
new file mode 100644
index 000000000..e2b025b81
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/physical_quantity.hh
@@ -0,0 +1,67 @@
+#ifndef PHYSICAL_QUANTITY_HH
+#define PHYSICAL_QUANTITY_HH
+
+#include <hdf5.h>
+
+#include "coordinate_system.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ class physical_quantity_t {
+
+ coordinate_system_t & m_coordinate_system;
+
+ int const m_group;
+ string m_name;
+
+ hid_t m_hdf5_physical_quantity;
+
+ physical_quantity_t ();
+ physical_quantity_t (physical_quantity_t const &);
+ physical_quantity_t operator= (physical_quantity_t const &);
+
+ public:
+
+ physical_quantity_t (coordinate_system_t & coordinate_system,
+ int group);
+
+ virtual
+ ~ physical_quantity_t ();
+
+ coordinate_system_t &
+ get_coordinate_system ()
+ const;
+
+ int
+ get_group ()
+ const;
+
+ string
+ get_name ()
+ const;
+
+ hid_t
+ get_hdf5_physical_quantity ()
+ const;
+
+ void
+ get_link_destination (int proc,
+ string & filename,
+ string & objectname)
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef PHYSICAL_QUANTITY_HH
diff --git a/CarpetDev/CarpetIOF5_standalone/src/simulation.cc b/CarpetDev/CarpetIOF5_standalone/src/simulation.cc
new file mode 100644
index 000000000..1adde5e5a
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/simulation.cc
@@ -0,0 +1,96 @@
+#include <cassert>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "defs.hh"
+
+#include "simulation.hh"
+#include "utils.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ using std::ostringstream;
+
+
+
+ simulation_t::
+ simulation_t (timestep_t & timestep,
+ char const * const name)
+ : m_timestep (timestep),
+ m_name (name)
+ {
+ m_hdf5_simulation
+ = open_or_create_group (m_timestep.get_hdf5_timestep(),
+ m_name.c_str());
+ assert (m_hdf5_simulation >= 0);
+
+ cGH const * const cctkGH = m_timestep.get_file().get_cctkGH();
+ write_or_check_attribute
+ (m_hdf5_simulation, "TimeStep", cctkGH->cctk_iteration);
+
+ assert (invariant());
+ }
+
+
+
+ simulation_t::
+ ~ simulation_t()
+ {
+ check (not H5Gclose (m_hdf5_simulation));
+ }
+
+
+
+ timestep_t & simulation_t::
+ get_timestep ()
+ const
+ {
+ return m_timestep;
+ }
+
+
+
+ hid_t simulation_t::
+ get_hdf5_simulation()
+ const
+ {
+ return m_hdf5_simulation;
+ }
+
+
+
+ void simulation_t::
+ get_link_destination (int const proc,
+ string & filename,
+ string & objectname)
+ const
+ {
+ get_timestep().get_link_destination (proc, filename, objectname);
+ if (objectname.empty())
+ {
+ objectname = m_name;
+ }
+ else
+ {
+ objectname += string ("/") + m_name;
+ }
+ }
+
+
+
+ bool simulation_t::
+ invariant()
+ const
+ {
+ return m_hdf5_simulation >= 0;
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/simulation.hh b/CarpetDev/CarpetIOF5_standalone/src/simulation.hh
new file mode 100644
index 000000000..4c4639958
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/simulation.hh
@@ -0,0 +1,64 @@
+#ifndef SIMULATION_HH
+#define SIMULATION_HH
+
+#include <set>
+#include <string>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "timestep.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ using std::string;
+
+ namespace F5 {
+
+ class simulation_t {
+
+ timestep_t & m_timestep;
+
+ string const m_name;
+
+ hid_t m_hdf5_simulation;
+
+ simulation_t ();
+ simulation_t (simulation_t const &);
+ simulation_t operator= (simulation_t const &);
+
+ public:
+
+ simulation_t (timestep_t & timestep,
+ char const * name);
+
+ virtual
+ ~ simulation_t ();
+
+ timestep_t &
+ get_timestep ()
+ const;
+
+ hid_t
+ get_hdf5_simulation ()
+ const;
+
+ void
+ get_link_destination (int proc,
+ string & filename,
+ string & objectname)
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef SIMULATION_HH
diff --git a/CarpetDev/CarpetIOF5_standalone/src/tensor_component.cc b/CarpetDev/CarpetIOF5_standalone/src/tensor_component.cc
new file mode 100644
index 000000000..6cd2b6486
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/tensor_component.cc
@@ -0,0 +1,171 @@
+#include <cassert>
+#include <cstdlib>
+
+// force HDF5 1.8.x installations to use the new API
+#define H5Dcreate_vers 2
+
+#include <hdf5.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+
+#include "vect.hh"
+
+#include "tensor_component.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ tensor_component_t::
+ tensor_component_t (data_region_t & data_region,
+ int const variable)
+ : m_data_region (data_region),
+ m_variable (variable)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ assert (variable >= 0 and variable < CCTK_NumVars());
+
+ char const * const name = CCTK_VarName (variable);
+ assert (name != 0);
+ m_name = string (name);
+
+ int const vartype = CCTK_VarTypeI (variable);
+ assert (vartype >= 0);
+ hid_t const hdf5_datatype = hdf5_datatype_from_cactus_datatype (vartype);
+ assert (hdf5_datatype >= 0);
+
+ bbox<int, dim> const & region = m_data_region.get_region();
+
+ vect<hsize_t, dim> const dims
+ = (region.shape() / region.stride()).reverse();
+ m_dataspace = H5Screate_simple (dim, & dims [0], 0);
+ assert (m_dataspace >= 0);
+
+ m_properties = H5Pcreate (H5P_DATASET_CREATE);
+ assert (m_properties >= 0);
+ vect<int, dim> const user_chunk_size
+ (chunk_size_x, chunk_size_y, chunk_size_z);
+ bool const need_chunks
+ = any (user_chunk_size > 0) or compression_level > 0 or write_checksum;
+ if (need_chunks)
+ {
+ vect<hsize_t, dim> const chunk_size
+ = either (user_chunk_size > 0,
+ vect<hsize_t, dim> (user_chunk_size),
+ dims);
+ herr_t const herr = H5Pset_chunk (m_properties, dim, & chunk_size [0]);
+ assert (not herr);
+ }
+ if (compression_level > 0)
+ {
+ herr_t const herr = H5Pset_deflate (m_properties, compression_level);
+ assert (not herr);
+ }
+ if (write_checksum)
+ {
+ herr_t const herr = H5Pset_fletcher32 (m_properties);
+ assert (not herr);
+ }
+
+ m_dataset
+ = H5Dcreate (m_data_region.get_hdf5_data_region(), m_name.c_str(),
+ hdf5_datatype, m_dataspace,
+ H5P_DEFAULT, m_properties, H5P_DEFAULT);
+ assert (m_dataset >= 0);
+
+ write_or_check_attribute
+ (m_dataset, "iorigin", region.lower() / region.stride());
+
+ assert (invariant());
+ }
+
+
+
+ tensor_component_t::
+ ~ tensor_component_t ()
+ {
+ herr_t herr;
+
+ herr = H5Dclose (m_dataset);
+ assert (not herr);
+
+ herr = H5Sclose (m_dataspace);
+ assert (not herr);
+
+ herr = H5Pclose (m_properties);
+ assert (not herr);
+ }
+
+
+
+ data_region_t & tensor_component_t::
+ get_data_region ()
+ const
+ {
+ return m_data_region;
+ }
+
+
+
+ hid_t tensor_component_t::
+ get_variable ()
+ const
+ {
+ return m_variable;
+ }
+
+
+
+#warning "TODO: This assumes that the shape of data is the same as the shape of the region; this may not be so if not all of the data are written out"
+ void tensor_component_t::
+ write (void const * const data,
+ int const cactus_datatype)
+ const
+ {
+ hid_t const memory_hdf5_datatype
+ = hdf5_datatype_from_cactus_datatype (cactus_datatype);
+ assert (memory_hdf5_datatype >= 0);
+
+ bbox<int, dim> const & region = m_data_region.get_region();
+
+ vect<hsize_t, dim> const dims
+ = (region.shape() / region.stride()).reverse();
+ hid_t const memory_dataspace
+ = H5Screate_simple (dim, & dims [0], & dims [0]);
+ assert (memory_dataspace >= 0);
+
+ hid_t const transfer_properties = H5Pcreate (H5P_DATASET_XFER);
+ assert (transfer_properties >= 0);
+
+ herr_t herr;
+ herr
+ = H5Dwrite (m_dataset, memory_hdf5_datatype, memory_dataspace,
+ m_dataspace, transfer_properties, data);
+ assert (not herr);
+
+ herr = H5Pclose (transfer_properties);
+ assert (not herr);
+
+ herr = H5Sclose (memory_dataspace);
+ assert (not herr);
+ }
+
+
+
+ bool tensor_component_t::
+ invariant ()
+ const
+ {
+ return (m_variable >= 0 and m_variable < CCTK_NumVars()
+ and m_properties >= 0
+ and m_dataset >= 0
+ and m_dataspace >= 0);
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/tensor_component.hh b/CarpetDev/CarpetIOF5_standalone/src/tensor_component.hh
new file mode 100644
index 000000000..8a95d6faa
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/tensor_component.hh
@@ -0,0 +1,62 @@
+#ifndef TENSOR_COMPONENT_HH
+#define TENSOR_COMPONENT_HH
+
+#include <string>
+
+#include <hdf5.h>
+
+#include "data_region.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ class tensor_component_t {
+
+ data_region_t & m_data_region;
+
+ int const m_variable;
+ string m_name;
+
+ hid_t m_dataspace;
+ hid_t m_properties;
+ hid_t m_dataset;
+
+ tensor_component_t ();
+ tensor_component_t (tensor_component_t const &);
+ tensor_component_t operator= (tensor_component_t const &);
+
+ public:
+
+ tensor_component_t (data_region_t & data_region,
+ int variable);
+
+ virtual
+ ~ tensor_component_t ();
+
+ data_region_t &
+ get_data_region ()
+ const;
+
+ hid_t
+ get_variable ()
+ const;
+
+ void
+ write (void const * data,
+ int cactus_datatype)
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef TENSOR_COMPONENT_HH
diff --git a/CarpetDev/CarpetIOF5_standalone/src/timestep.cc b/CarpetDev/CarpetIOF5_standalone/src/timestep.cc
new file mode 100644
index 000000000..409f47221
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/timestep.cc
@@ -0,0 +1,124 @@
+#include <cassert>
+#include <iomanip>
+#include <limits>
+#include <string>
+#include <sstream>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+#include "cctk_Functions.h"
+
+#include "defs.hh"
+
+#include "timestep.hh"
+#include "utils.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ using std::numeric_limits;
+ using std::setprecision;
+ using std::ostringstream;
+
+
+
+ timestep_t::
+ timestep_t (file_t & file,
+ CCTK_REAL const time,
+ char const * const name)
+ : m_file (file),
+ m_time (time)
+ {
+ // Construct a group name from the simulation time
+ ostringstream buf;
+ if (name != 0)
+ {
+ // Use the name argument if it is present
+ buf << name;
+ }
+ else
+ {
+ // Create a string from the time without losing information
+ int const precision = numeric_limits<CCTK_REAL>::digits10 + 2;
+ buf << setprecision (precision) << "T=" << time;
+ }
+ m_name = buf.str();
+
+ m_hdf5_timestep
+ = open_or_create_group (m_file.get_hdf5_file(), m_name.c_str());
+ assert (m_hdf5_timestep >= 0);
+ write_or_check_attribute (m_hdf5_timestep, "Time", time);
+
+ assert (invariant());
+ }
+
+
+
+ timestep_t::
+ ~ timestep_t()
+ {
+ check (not H5Gclose (m_hdf5_timestep));
+ }
+
+
+
+ file_t & timestep_t::
+ get_file ()
+ const
+ {
+ return m_file;
+ }
+
+
+
+ CCTK_REAL timestep_t::
+ get_time ()
+ const
+ {
+ return m_time;
+ }
+
+
+
+ hid_t timestep_t::
+ get_hdf5_timestep()
+ const
+ {
+ return m_hdf5_timestep;
+ }
+
+
+
+ void timestep_t::
+ get_link_destination (int const proc,
+ string & filename,
+ string & objectname)
+ const
+ {
+ get_file().get_link_destination (proc, filename, objectname);
+ if (objectname.empty())
+ {
+ objectname = m_name;
+ }
+ else
+ {
+ objectname += string ("/") + m_name;
+ }
+ }
+
+
+
+ bool timestep_t::
+ invariant()
+ const
+ {
+ return m_hdf5_timestep >= 0;
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/timestep.hh b/CarpetDev/CarpetIOF5_standalone/src/timestep.hh
new file mode 100644
index 000000000..d70a00024
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/timestep.hh
@@ -0,0 +1,70 @@
+#ifndef TIMESTEP_HH
+#define TIMESTEP_HH
+
+#include <string>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "file.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ using std::string;
+
+ namespace F5 {
+
+ class timestep_t {
+
+ file_t & m_file;
+
+ CCTK_REAL const m_time;
+
+ string m_name;
+
+ hid_t m_hdf5_timestep;
+
+ timestep_t ();
+ timestep_t (timestep_t const &);
+ timestep_t operator= (timestep_t const &);
+
+ public:
+
+ timestep_t (file_t & file,
+ CCTK_REAL time,
+ char const * name = 0);
+
+ virtual
+ ~ timestep_t ();
+
+ file_t &
+ get_file ()
+ const;
+
+ CCTK_REAL
+ get_time ()
+ const;
+
+ hid_t
+ get_hdf5_timestep ()
+ const;
+
+ void
+ get_link_destination (int proc,
+ string & filename,
+ string & objectname)
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef TIMESTEP_HH
diff --git a/CarpetDev/CarpetIOF5_standalone/src/topology.cc b/CarpetDev/CarpetIOF5_standalone/src/topology.cc
new file mode 100644
index 000000000..bc05c73a7
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/topology.cc
@@ -0,0 +1,200 @@
+#include <cassert>
+#include <sstream>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "defs.hh"
+#include "vect.hh"
+
+#include "topology.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ topology_t::
+ topology_t (simulation_t & simulation)
+ : m_simulation (simulation)
+ {
+ }
+
+
+
+ topology_t::
+ ~ topology_t ()
+ {
+ }
+
+
+
+ simulation_t & topology_t::
+ get_simulation ()
+ const
+ {
+ return m_simulation;
+ }
+
+
+
+ hid_t topology_t::
+ get_hdf5_topology()
+ const
+ {
+ return m_hdf5_topology;
+ }
+
+
+
+ bool topology_t::
+ invariant()
+ const
+ {
+ return m_hdf5_topology >= 0;
+ }
+
+
+
+ unigrid_topology_t::
+ unigrid_topology_t (simulation_t & simulation)
+ : topology_t (simulation)
+ {
+ char const * const name = "uniform";
+ m_name = string (name);
+ m_hdf5_topology
+ = open_or_create_group (m_simulation.get_hdf5_simulation(), name);
+ assert (m_hdf5_topology >= 0);
+
+ assert (invariant());
+ }
+
+
+
+ unigrid_topology_t::
+ ~ unigrid_topology_t ()
+ {
+ herr_t const herr = H5Gclose (m_hdf5_topology);
+ assert (not herr);
+ }
+
+
+
+ bool unigrid_topology_t::
+ invariant()
+ const
+ {
+ return topology_t::invariant();
+ }
+
+
+
+ mesh_refinement_topology_t::
+ mesh_refinement_topology_t (simulation_t & simulation,
+ int const map,
+ int const maps,
+ int const refinement_level,
+ int const max_refinement_levels,
+ vect<int, dim> const & level_refinement_factor,
+ vect<int, dim> const & max_refinement_factor)
+ : topology_t (simulation),
+ m_refinement_level (refinement_level),
+ m_max_refinement_levels (max_refinement_levels),
+ m_level_refinement_factor (level_refinement_factor),
+ m_max_refinement_factor (max_refinement_factor)
+ {
+ assert (refinement_level >= 0);
+ assert (refinement_level < max_refinement_levels);
+ assert (all (level_refinement_factor > 0));
+ assert (all (level_refinement_factor <= max_refinement_factor));
+
+ ostringstream namebuf;
+ namebuf << "Vertices";
+ if (maps > 1)
+ {
+ namebuf << "-map" << map;
+ }
+ if (max_refinement_levels > 1)
+ {
+ namebuf << "-level" << refinement_level;
+ }
+ string const namestr = namebuf.str();
+ m_name = namestr;
+ char const * const name = namestr.c_str();
+
+ m_hdf5_topology
+ = open_or_create_group (m_simulation.get_hdf5_simulation(), name);
+ assert (m_hdf5_topology >= 0);
+
+ assert (invariant());
+ }
+
+
+
+ void mesh_refinement_topology_t::
+ calculate_level_origin_delta (vect<CCTK_REAL, dim> const & coarse_origin,
+ vect<CCTK_REAL, dim> const & coarse_delta,
+ vect<int, dim> const & level_offset,
+ vect<int, dim> const & level_offset_denominator,
+ vect<CCTK_REAL, dim> & level_origin,
+ vect<CCTK_REAL, dim> & level_delta)
+ const
+ {
+ assert (all (coarse_delta > (CCTK_REAL) 0));
+ assert (all (level_offset_denominator > 0));
+
+ level_delta
+ = coarse_delta / vect<CCTK_REAL, dim> (m_level_refinement_factor);
+ level_origin
+ = (coarse_origin
+ + (vect<CCTK_REAL, dim> (level_offset)
+ / vect<CCTK_REAL, dim> (level_offset_denominator)
+ / vect<CCTK_REAL, dim> (m_max_refinement_factor)));
+ }
+
+
+
+ mesh_refinement_topology_t::
+ ~ mesh_refinement_topology_t ()
+ {
+ herr_t const herr = H5Gclose (m_hdf5_topology);
+ assert (not herr);
+ }
+
+
+
+ void topology_t::
+ get_link_destination (int const proc,
+ string & filename,
+ string & objectname)
+ const
+ {
+ get_simulation().get_link_destination (proc, filename, objectname);
+ if (objectname.empty())
+ {
+ objectname = m_name;
+ }
+ else
+ {
+ objectname += string ("/") + m_name;
+ }
+ }
+
+
+
+ bool mesh_refinement_topology_t::
+ invariant()
+ const
+ {
+ return (topology_t::invariant()
+ and m_refinement_level >= 0
+ and m_refinement_level < m_max_refinement_levels
+ and all (m_level_refinement_factor > 0)
+ and all (m_level_refinement_factor <= m_max_refinement_factor));
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/topology.hh b/CarpetDev/CarpetIOF5_standalone/src/topology.hh
new file mode 100644
index 000000000..e179e71db
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/topology.hh
@@ -0,0 +1,133 @@
+#ifndef TOPOLOGY_HH
+#define TOPOLOGY_HH
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "defs.hh"
+#include "vect.hh"
+
+#include "simulation.hh"
+#include "utils.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ class topology_t {
+
+ topology_t ();
+ topology_t (topology_t const &);
+ topology_t operator= (topology_t const &);
+
+ protected:
+
+ simulation_t & m_simulation;
+
+ string m_name;
+
+ hid_t m_hdf5_topology;
+
+ topology_t (simulation_t & simulation);
+
+ public:
+
+ virtual
+ ~ topology_t ();
+
+ public:
+
+ simulation_t &
+ get_simulation ()
+ const;
+
+ void
+ get_link_destination (int proc,
+ string & filename,
+ string & objectname)
+ const;
+
+ hid_t
+ get_hdf5_topology ()
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+ };
+
+
+
+ class unigrid_topology_t : public topology_t {
+
+ unigrid_topology_t ();
+ unigrid_topology_t (unigrid_topology_t const &);
+ unigrid_topology_t operator= (unigrid_topology_t const &);
+
+ public:
+
+ // Create unigrid topology
+ unigrid_topology_t (simulation_t & simulation);
+
+ virtual
+ ~ unigrid_topology_t ();
+
+ virtual bool
+ invariant ()
+ const;
+ };
+
+
+
+ class mesh_refinement_topology_t : public topology_t {
+
+ int const m_refinement_level;
+ int const m_max_refinement_levels;
+ vect<int, dim> const m_level_refinement_factor;
+ vect<int, dim> const m_max_refinement_factor;
+
+ mesh_refinement_topology_t ();
+ mesh_refinement_topology_t (mesh_refinement_topology_t const &);
+ mesh_refinement_topology_t
+ operator= (mesh_refinement_topology_t const &);
+
+ public:
+
+ mesh_refinement_topology_t (simulation_t & simulation,
+ int map,
+ int maps,
+ int refinement_level,
+ int max_refinement_levels,
+ vect<int, dim> const & level_refinement_factors,
+ vect<int, dim> const & max_refinement_factors);
+
+ void
+ calculate_level_origin_delta (vect<CCTK_REAL, dim> const & coarse_origin,
+ vect<CCTK_REAL, dim> const & coarse_delta,
+ vect<int, dim> const & level_offset,
+ vect<int, dim> const & level_offset_denominator,
+ vect<CCTK_REAL, dim> & level_origin,
+ vect<CCTK_REAL, dim> & level_delta)
+ const;
+
+ virtual
+ ~ mesh_refinement_topology_t ();
+
+ void
+ get_link_destination (string & filename,
+ string & objectname)
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef TOPOLOGY_HH
diff --git a/CarpetDev/CarpetIOF5_standalone/src/utils.cc b/CarpetDev/CarpetIOF5_standalone/src/utils.cc
new file mode 100644
index 000000000..d311f0992
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/utils.cc
@@ -0,0 +1,512 @@
+#include <cassert>
+#include <complex>
+#include <cstring>
+#include <sstream>
+#include <vector>
+
+// force HDF5 1.8.x installations to use the new API
+#define H5Acreate_vers 2
+#define H5Gcreate_vers 2
+#define H5Gopen_vers 2
+#define H5Tarray_create_vers 2
+
+#include <hdf5.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+
+#include "bbox.hh"
+#include "defs.hh"
+#include "vect.hh"
+
+#include "utils.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ using std::complex;
+ using std::vector;
+
+
+
+ hid_t
+ hdf5_datatype_from_dummy (signed char const & dummy)
+ {
+ return H5T_NATIVE_SCHAR;
+ }
+
+ hid_t
+ hdf5_datatype_from_dummy (short const & dummy)
+ {
+ return H5T_NATIVE_SHORT;
+ }
+
+ hid_t
+ hdf5_datatype_from_dummy (int const & dummy)
+ {
+ return H5T_NATIVE_INT;
+ }
+
+ hid_t
+ hdf5_datatype_from_dummy (long const & dummy)
+ {
+ return H5T_NATIVE_LONG;
+ }
+
+ hid_t
+ hdf5_datatype_from_dummy (long long const & dummy)
+ {
+ return H5T_NATIVE_LLONG;
+ }
+
+ hid_t
+ hdf5_datatype_from_dummy (float const & dummy)
+ {
+ return H5T_NATIVE_FLOAT;
+ }
+
+ hid_t
+ hdf5_datatype_from_dummy (double const & dummy)
+ {
+ return H5T_NATIVE_DOUBLE;
+ }
+
+ hid_t
+ hdf5_datatype_from_dummy (long double const & dummy)
+ {
+ return H5T_NATIVE_LDOUBLE;
+ }
+
+#ifdef HAVE_CCTK_COMPLEX8
+ hid_t
+ hdf5_datatype_from_dummy (CCTK_COMPLEX8 const & dummy)
+ {
+ CCTK_REAL4 real;
+ return hdf5_complex_datatype_from_dummy (dummy, real);
+ }
+#endif
+
+#ifdef HAVE_CCTK_COMPLEX16
+ hid_t
+ hdf5_datatype_from_dummy (CCTK_COMPLEX16 const & dummy)
+ {
+ CCTK_REAL8 real;
+ return hdf5_complex_datatype_from_dummy (dummy, real);
+ }
+#endif
+
+#ifdef HAVE_CCTK_COMPLEX32
+ hid_t
+ hdf5_datatype_from_dummy (CCTK_COMPLEX32 const & dummy)
+ {
+ CCTK_REAL16 real;
+ return hdf5_complex_datatype_from_dummy (dummy, real);
+ }
+#endif
+
+ template<typename T, typename R>
+ hid_t
+ hdf5_complex_datatype_from_dummy (T const & dummy, R const & real)
+ {
+ static bool initialised = false;
+ static hid_t hdf_complex_datatype;
+
+ if (not initialised)
+ {
+ initialised = true;
+
+ hsize_t const cdim[1] = { 2 };
+
+ hdf_complex_datatype
+ = H5Tarray_create (hdf5_datatype_from_dummy (real), 1, cdim);
+ assert (hdf_complex_datatype >= 0);
+ }
+
+ return hdf_complex_datatype;
+ }
+
+
+
+ hid_t
+ hdf5_datatype_from_cactus_datatype (int const cactus_datatype)
+ {
+ switch (cactus_datatype) {
+ case CCTK_VARIABLE_VOID : return H5I_INVALID_HID;
+#define CASE(TYPEID, TYPE) \
+ case TYPEID: \
+ { \
+ TYPE dummy; \
+ return hdf5_datatype_from_dummy (dummy); \
+ } \
+ break
+ CASE (CCTK_VARIABLE_BYTE , CCTK_BYTE );
+ CASE (CCTK_VARIABLE_INT , CCTK_INT );
+#ifdef HAVE_CCTK_INT1
+ CASE (CCTK_VARIABLE_INT1 , CCTK_INT1 );
+#endif
+#ifdef HAVE_CCTK_INT1
+ CASE (CCTK_VARIABLE_INT2 , CCTK_INT2 );
+#endif
+#ifdef HAVE_CCTK_INT2
+ CASE (CCTK_VARIABLE_INT4 , CCTK_INT4 );
+#endif
+#ifdef HAVE_CCTK_INT4
+ CASE (CCTK_VARIABLE_INT8 , CCTK_INT8 );
+#endif
+ CASE (CCTK_VARIABLE_REAL , CCTK_REAL );
+#ifdef HAVE_CCTK_REAL4
+ CASE (CCTK_VARIABLE_REAL4 , CCTK_REAL4 );
+#endif
+#ifdef HAVE_CCTK_REAL8
+ CASE (CCTK_VARIABLE_REAL8 , CCTK_REAL8 );
+#endif
+#ifdef HAVE_CCTK_REAL16
+ CASE (CCTK_VARIABLE_REAL16 , CCTK_REAL16 );
+#endif
+ CASE (CCTK_VARIABLE_COMPLEX , CCTK_COMPLEX );
+#ifdef HAVE_CCTK_COMPLEX8
+ CASE (CCTK_VARIABLE_COMPLEX8 , CCTK_COMPLEX8 );
+#endif
+#ifdef HAVE_CCTK_COMPLEX16
+ CASE (CCTK_VARIABLE_COMPLEX16, CCTK_COMPLEX16);
+#endif
+#ifdef HAVE_CCTK_COMPLEX32
+ CASE (CCTK_VARIABLE_COMPLEX32, CCTK_COMPLEX32);
+#endif
+#undef CASE
+ case CCTK_VARIABLE_CHAR : return H5I_INVALID_HID;
+ case CCTK_VARIABLE_STRING : return H5I_INVALID_HID;
+ case CCTK_VARIABLE_POINTER : return H5I_INVALID_HID;
+ case CCTK_VARIABLE_FPOINTER : return H5I_INVALID_HID;
+ }
+ return H5I_INVALID_HID;
+ }
+
+
+
+ template <typename T, int D>
+ string
+ name_from_ivect (vect <T, D> const & ivect)
+ {
+ ostringstream buf;
+ for (int d = 0; d < dim; ++ d)
+ {
+ if (d > 0)
+ {
+ buf << ":";
+ }
+ buf << ivect[d];
+ }
+ return buf.str ();
+ }
+
+ template
+ string
+ name_from_ivect (vect <int, dim> const & ivect);
+
+ template
+ string
+ name_from_ivect (vect <CCTK_REAL, dim> const & ivect);
+
+
+
+ template <typename T, int D>
+ string
+ name_from_ibbox (bbox <T, D> const & ibbox)
+ {
+ ostringstream buf;
+ buf << name_from_ivect (ibbox.lower ())
+ << "-"
+ << name_from_ivect (ibbox.upper ())
+ << "-"
+ << name_from_ivect (ibbox.stride ());
+ return buf.str ();
+ }
+
+ template
+ string
+ name_from_ibbox (bbox <int, dim> const & ivect);
+
+
+
+ hid_t
+ open_or_create_group (hid_t const where,
+ char const * const name)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ assert (where >= 0);
+ assert (name != 0);
+
+ // bool group_exists;
+ // H5E_BEGIN_TRY {
+ // H5G_stat_t statbuf;
+ // herr_t const herr = H5Gget_objinfo (where, name, true, & statbuf);
+ // group_exists = herr == 0;
+ // } H5E_END_TRY;
+ bool group_exists;
+ H5E_BEGIN_TRY {
+ H5G_info_t groupinfo;
+ herr_t const herr
+ = H5Gget_info_by_name (where, name, & groupinfo, H5P_DEFAULT);
+ group_exists = herr == 0;
+ } H5E_END_TRY;
+ if (veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "Group \"%s\" %s",
+ name,
+ group_exists ? "exists" : "does not exist");
+ }
+
+ hid_t group;
+ if (group_exists)
+ {
+ if (veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING, "H5Gopen (name=\"%s\")", name);
+ }
+ group = H5Gopen (where, name, H5P_DEFAULT);
+ }
+ else
+ {
+ if (veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING, "H5Gcreate (name=\"%s\")", name);
+ }
+ group = H5Gcreate (where, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ }
+
+ return group;
+ }
+
+
+
+ template<typename T>
+ void
+ write_or_check_attribute (hid_t const where,
+ char const * const name,
+ T const * const values,
+ int const num_values)
+ {
+ assert (where >= 0);
+ assert (name != 0);
+ assert (num_values >= 0);
+ assert (num_values == 0 or values != 0);
+
+ T dummy;
+ hid_t const datatype = hdf5_datatype_from_dummy (dummy);
+
+ hid_t attribute;
+ H5E_BEGIN_TRY {
+ attribute = H5Aopen_name (where, name);
+ } H5E_END_TRY;
+
+ if (attribute < 0)
+ {
+ // The attribute does not yet exist; create it
+ hsize_t const adim = num_values;
+ hid_t const dataspace = H5Screate_simple (1, & adim, & adim);
+ assert (dataspace >= 0);
+ attribute = H5Acreate (where, name, datatype, dataspace,
+ H5P_DEFAULT, H5P_DEFAULT);
+ assert (attribute >= 0);
+ herr_t herr;
+ herr = H5Awrite (attribute, datatype, values);
+ assert (not herr);
+ herr = H5Aclose (attribute);
+ assert (not herr);
+ herr = H5Sclose (dataspace);
+ assert (not herr);
+ }
+ else
+ {
+ // The attribute already exists; read and check it
+ hid_t const dataspace = H5Aget_space (attribute);
+ htri_t const is_simple = H5Sis_simple (dataspace);
+ assert (is_simple >= 0);
+ assert (is_simple > 0);
+ int const ndims = H5Sget_simple_extent_ndims (dataspace);
+ assert (ndims == 1);
+ hsize_t adim;
+ herr_t herr;
+ herr = H5Sget_simple_extent_dims (dataspace, & adim, 0);
+ assert (adim == hsize_t (num_values));
+ vector<T> buf (adim);
+ herr = H5Aread (attribute, datatype, & buf.front());
+ assert (not herr);
+ herr = H5Sclose (dataspace);
+ assert (not herr);
+ herr = H5Aclose (attribute);
+ assert (not herr);
+ for (int n = 0; n < num_values; ++ n)
+ {
+ assert (values [n] == buf [n]);
+ }
+ }
+ }
+
+#if SIZEOF_INT != CCTK_INTEGER_PRECISION
+ template
+ void
+ write_or_check_attribute (hid_t const where,
+ char const * const name,
+ int const * const values,
+ int const num_values);
+#endif
+ template
+ void
+ write_or_check_attribute (hid_t const where,
+ char const * const name,
+ CCTK_INT const * const values,
+ int const num_values);
+ template
+ void
+ write_or_check_attribute (hid_t const where,
+ char const * const name,
+ CCTK_REAL const * const values,
+ int const num_values);
+
+
+
+ template<typename T>
+ void
+ write_or_check_attribute (hid_t const where,
+ char const * const name,
+ T const & value)
+ {
+ assert (where >= 0);
+ assert (name != 0);
+
+ write_or_check_attribute (where, name, & value, 1);
+ }
+
+#if SIZEOF_INT != CCTK_INTEGER_PRECISION
+ template
+ void
+ write_or_check_attribute (hid_t const where,
+ char const * const name,
+ int const & value);
+#endif
+ template
+ void
+ write_or_check_attribute (hid_t const where,
+ char const * const name,
+ CCTK_INT const & value);
+ template
+ void
+ write_or_check_attribute (hid_t const where,
+ char const * const name,
+ CCTK_REAL const & value);
+
+
+
+ template<typename T, int D>
+ void
+ write_or_check_attribute (hid_t where,
+ char const * name,
+ vect<T,D> const & value)
+ {
+ assert (where >= 0);
+ assert (name != 0);
+
+ write_or_check_attribute (where, name, & value [0], D);
+ }
+
+#if SIZEOF_INT != CCTK_INTEGER_PRECISION
+ template
+ void
+ write_or_check_attribute (hid_t where,
+ char const * name,
+ vect<int, dim> const & value);
+#endif
+ template
+ void
+ write_or_check_attribute (hid_t where,
+ char const * name,
+ vect<CCTK_INT, dim> const & value);
+ template
+ void
+ write_or_check_attribute (hid_t where,
+ char const * name,
+ vect<CCTK_REAL, dim> const & value);
+
+
+
+ template<>
+ void
+ write_or_check_attribute (hid_t const where,
+ char const * const name,
+ char const * const & value)
+ {
+ assert (where >= 0);
+ assert (name != 0);
+ assert (value != 0);
+
+ hid_t attribute;
+ H5E_BEGIN_TRY {
+ attribute = H5Aopen_name (where, name);
+ } H5E_END_TRY;
+
+ if (attribute < 0)
+ {
+ // The attribute does not yet exist; create it
+ hid_t const datatype = H5Tcopy (H5T_C_S1);
+ assert (datatype >= 0);
+ herr_t herr;
+ int const length = strlen (value) + 1;
+ herr = H5Tset_size (datatype, length);
+ assert (not herr);
+ hsize_t const dim = 1;
+ hid_t const dataspace = H5Screate_simple (1, & dim, & dim);
+ assert (dataspace >= 0);
+ attribute = H5Acreate (where, name, datatype, dataspace,
+ H5P_DEFAULT, H5P_DEFAULT);
+ assert (attribute >= 0);
+ herr = H5Awrite (attribute, datatype, value);
+ assert (not herr);
+ herr = H5Aclose (attribute);
+ assert (not herr);
+ herr = H5Sclose (dataspace);
+ assert (not herr);
+ herr = H5Tclose (datatype);
+ assert (not herr);
+ }
+ else
+ {
+ // The attribute already exists; read and check it
+ hid_t datatype = H5Aget_type (attribute);
+ assert (datatype >= 0);
+ hid_t typeclass = H5Tget_class (datatype);
+ assert (typeclass == H5T_STRING);
+ int const length = H5Tget_size (datatype);
+ assert (length >= 0);
+ hid_t const dataspace = H5Aget_space (attribute);
+ htri_t const is_simple = H5Sis_simple (dataspace);
+ assert (is_simple >= 0);
+ assert (is_simple > 0);
+ int const ndims = H5Sget_simple_extent_ndims (dataspace);
+ assert (ndims == 1);
+ hsize_t dim;
+ herr_t herr;
+ herr = H5Sget_simple_extent_dims (dataspace, & dim, 0);
+ assert (dim == 1);
+ vector<char> buf (length);
+ herr = H5Aread (attribute, datatype, & buf.front());
+ assert (not herr);
+ herr = H5Sclose (dataspace);
+ assert (not herr);
+ herr = H5Aclose (attribute);
+ assert (not herr);
+ herr = H5Tclose (datatype);
+ assert (not herr);
+ assert (strcmp (& buf.front(), value) == 0);
+ }
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/utils.hh b/CarpetDev/CarpetIOF5_standalone/src/utils.hh
new file mode 100644
index 000000000..8d9d0a925
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/utils.hh
@@ -0,0 +1,93 @@
+#ifndef UTILS_HH
+#define UTILS_HH
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "vect.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ hid_t
+ hdf5_datatype_from_dummy (signed char const & dummy);
+ hid_t
+ hdf5_datatype_from_dummy (short const & dummy);
+ hid_t
+ hdf5_datatype_from_dummy (int const & dummy);
+ hid_t
+ hdf5_datatype_from_dummy (long const & dummy);
+ hid_t
+ hdf5_datatype_from_dummy (long long const & dummy);
+ hid_t
+ hdf5_datatype_from_dummy (float const & dummy);
+ hid_t
+ hdf5_datatype_from_dummy (double const & dummy);
+ hid_t
+ hdf5_datatype_from_dummy (long double const & dummy);
+#ifdef HAVE_CCTK_COMPLEX8
+ hid_t
+ hdf5_datatype_from_dummy (CCTK_COMPLEX8 const & dummy);
+#endif
+#ifdef HAVE_CCTK_COMPLEX16
+ hid_t
+ hdf5_datatype_from_dummy (CCTK_COMPLEX16 const & dummy);
+#endif
+#ifdef HAVE_CCTK_COMPLEX32
+ hid_t
+ hdf5_datatype_from_dummy (CCTK_COMPLEX32 const & dummy);
+#endif
+
+ template<typename T, typename R>
+ hid_t
+ hdf5_complex_datatype_from_dummy (T const & dummy, R const & real);
+
+ hid_t
+ hdf5_datatype_from_cactus_datatype (int cactus_datatype);
+
+
+
+ template <typename T, int D>
+ string
+ name_from_ivect (vect <T, D> const & ivect);
+
+ template <typename T, int D>
+ string
+ name_from_ibbox (bbox <T, D> const & ibbox);
+
+
+
+ hid_t
+ open_or_create_group (hid_t where,
+ char const * name);
+
+
+
+ template<typename T>
+ void
+ write_or_check_attribute (hid_t where,
+ char const * name,
+ T const * values,
+ int num_values);
+
+ template<typename T>
+ void
+ write_or_check_attribute (hid_t where,
+ char const * name,
+ T const & value);
+
+ template<typename T, int D>
+ void
+ write_or_check_attribute (hid_t where,
+ char const * name,
+ vect<T,D> const & value);
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef UTILS_HH
diff --git a/CarpetDev/CarpetIOF5_standalone/src/writer-old.cc b/CarpetDev/CarpetIOF5_standalone/src/writer-old.cc
new file mode 100644
index 000000000..4c4f639a8
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/writer-old.cc
@@ -0,0 +1,511 @@
+#include <cstdlib>
+#include <sstream>
+#include <string>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+
+#include "carpet.hh"
+
+#include "data_region.hh"
+#include "file.hh"
+#include "meta_data_region.hh"
+#include "physical_quantity.hh"
+#include "simulation.hh"
+#include "tensor_component.hh"
+#include "timestep.hh"
+#include "topology.hh"
+#include "writer.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ writer_t::
+ writer_t (cGH const * const cctkGH,
+ int const variable)
+ : m_cctkGH (cctkGH),
+ m_variable (variable)
+ {
+ }
+
+
+
+ void writer_t::
+ write (F5::file_t & file)
+ const
+ {
+ write_meta (file);
+ }
+
+
+
+ void writer_t::
+ write_meta (F5::file_t & file)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_meta");
+ }
+
+ F5::timestep_t timestep (file, m_cctkGH->cctk_time);
+
+ if (Carpet::is_meta_mode())
+ {
+ for (Carpet::mglevel_iterator mglevel_iter (m_cctkGH);
+ not mglevel_iter.done();
+ mglevel_iter.step())
+ {
+ write_one_mglevel (timestep);
+ }
+ }
+ else
+ {
+ write_one_mglevel (timestep);
+ }
+ }
+
+
+
+ void writer_t::
+ write_one_mglevel (F5::timestep_t & timestep)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_mglevel mglevel=%d",
+ Carpet::mglevel);
+ }
+
+ // ostringstream namebuf;
+ // namebuf << sim_id;
+ // if (m_cctkGH->cctk_convlevel != 0)
+ // {
+ // namebuf << "-convlevel" << m_cctkGH->cctk_convlevel;
+ // }
+ // string const name = namebuf.str();
+ // F5::simulation_t simulation (timestep, name.c_str());
+
+ int const grouptype = CCTK_GroupTypeFromVarI (m_variable);
+ assert (grouptype >= 0);
+ switch (grouptype)
+ {
+ case CCTK_ARRAY:
+ case CCTK_SCALAR:
+ {
+ if (Carpet::is_global_mode())
+ {
+ int const rl = 0;
+ enter_level_mode (m_cctkGH, rl);
+ write_global_reflevel (timestep);
+ leave_level_mode (m_cctkGH);
+ }
+ else
+ {
+ if (Carpet::do_global_mode)
+ {
+ write_global_reflevel (timestep);
+ }
+ }
+ }
+ break;
+ case CCTK_GF:
+ {
+ if (Carpet::is_global_mode())
+ {
+ for (Carpet::reflevel_iterator reflevel_iter (m_cctkGH);
+ not reflevel_iter.done();
+ reflevel_iter.step())
+ {
+ write_one_reflevel (timestep);
+ }
+ }
+ else
+ {
+ write_one_reflevel (simulation);
+ }
+ }
+ break;
+ default:
+ assert (0);
+ }
+ }
+
+
+
+ void writer_t::
+ write_global_reflevel (F5::timestep_t & timestep)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_INFO ("OutputVarAs/write_global_reflevel");
+ }
+
+ if (Carpet::is_level_mode())
+ {
+ for (Carpet::map_iterator map_iter (m_cctkGH, grouptype);
+ not map_iter.done();
+ map_iter.step())
+ {
+ write_global_map (timestep);
+ }
+ }
+ else
+ {
+ write_global_map (timestep);
+ }
+ }
+
+
+
+ void writer_t::
+ write_global_map (F5::timestep_t & timestep)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_INFO ("OutputVarAs/write_global_map");
+ }
+
+ write_global_component (timestep);
+ }
+
+
+
+ void writer_t::
+ write_global_component (F5::timestep_t & timestep)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_INFO ("OutputVarAs/write_global_component");
+ }
+
+ int const group = CCTK_GroupIndexFromVarI (m_variable);
+ assert (group >= 0 and group < CCTK_NumGroups());
+ cGroup groupdata;
+ check (not CCTK_GropuData (group, & groupdata));
+ assert (groupdata.grouptype == CCTK_SCALAR
+ or groupdata.grouptype == CCTK_ARRAY);
+
+ for (Carpet::component_iterator component_iter (m_cctkGH, grouptype);
+ not component_iter.done();
+ component_iter.step())
+
+
+
+ int const myproc = CCTK_MyProc (m_cctkGH);
+ if (groupdata.disttype == CCTK_DISTRIB_CONSTANT and myproc != 0)
+ {
+ // Output DISTRIB=constant groups only on the root processor
+ return;
+ }
+
+ // Name the grid after the variable group
+ char * const c_name = CCTK_GroupNameFromVarI (m_variable);
+ string const name = c_name;
+ free (c_name);
+ F5::simulation_t simulation (timestep, name.c_str());
+
+ F5::unigrid_topology_t topology (simulation);
+
+ vect<CCTK_REAL, dim> const level_origin (0.0), level_delta (1.0);
+ F5::Cartesian_coordinate_system_t coordinate_system
+ (topology, level_origin, level_delta);
+
+ F5::physical_quantity_t physical_quantity (coordinate_system, group);
+
+ int const map = 0;
+ int const reflevel = 0;
+ dh * const dd = Carpet::arrdata.at(group).at(map).dd;
+ dh::dboxes const & boxes
+ = dd->boxes.at(Carpet::mglevel).at(reflevel).at(myproc);
+ bbox<int, dim> const & region = determine_region (boxes);
+
+ F5::file_t & file = timestep.get_file();
+ bool const have_metafile
+ = file.get_is_metafile() and not file.get_is_datafile();
+ if (have_metafile)
+ {
+ F5::meta_data_region_t meta_data_region (physical_quantity, region);
+ gh * const hh = Carpet::vhh.at(Carpet::map);
+ int const proc = hh->processor (Carpet::reflevel, Carpet::component);
+ meta_data_region.write (proc);
+ }
+
+ F5::data_region_t data_region (physical_quantity, region);
+
+ F5::tensor_component_t tensor_component (data_region, m_variable);
+ int const timelevel = 0;
+ void const * const varptr
+ = CCTK_VarDataPtrI (m_cctkGH, timelevel, m_variable);
+ assert (varptr != 0);
+ int const vartype = CCTK_VarTypeI (m_variable);
+ assert (vartype >= 0);
+ tensor_component.write (varptr, vartype);
+ }
+
+
+
+ void writer_t::
+ write_global (F5::timestep_t & timestep)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_INFO ("OutputVarAs/write_global");
+ }
+
+ int const group = CCTK_GroupIndexFromVarI (m_variable);
+ assert (group >= 0 and group < CCTK_NumGroups());
+ cGroup groupdata;
+ check (not CCTK_GropuData (group, & groupdata));
+ assert (groupdata.grouptype == CCTK_SCALAR
+ or groupdata.grouptype == CCTK_ARRAY);
+
+ for (Carpet::component_iterator component_iter (m_cctkGH, grouptype);
+ not component_iter.done();
+ component_iter.step())
+
+
+
+ int const myproc = CCTK_MyProc (m_cctkGH);
+ if (groupdata.disttype == CCTK_DISTRIB_CONSTANT and myproc != 0)
+ {
+ // Output DISTRIB=constant groups only on the root processor
+ return;
+ }
+
+ // Name the grid after the variable group
+ char * const c_name = CCTK_GroupNameFromVarI (m_variable);
+ string const name = c_name;
+ free (c_name);
+ F5::simulation_t simulation (timestep, name.c_str());
+
+ F5::unigrid_topology_t topology (simulation);
+
+ vect<CCTK_REAL, dim> const level_origin (0.0), level_delta (1.0);
+ F5::Cartesian_coordinate_system_t coordinate_system
+ (topology, level_origin, level_delta);
+
+ F5::physical_quantity_t physical_quantity (coordinate_system, group);
+
+ int const map = 0;
+ int const reflevel = 0;
+ dh * const dd = Carpet::arrdata.at(group).at(map).dd;
+ dh::dboxes const & boxes
+ = dd->boxes.at(Carpet::mglevel).at(reflevel).at(myproc);
+ bbox<int, dim> const & region = determine_region (boxes);
+
+ F5::file_t & file = timestep.get_file();
+ bool const have_metafile
+ = file.get_is_metafile() and not file.get_is_datafile();
+ if (have_metafile)
+ {
+ F5::meta_data_region_t meta_data_region (physical_quantity, region);
+ gh * const hh = Carpet::vhh.at(Carpet::map);
+ int const proc = hh->processor (Carpet::reflevel, Carpet::component);
+ meta_data_region.write (proc);
+ }
+
+ F5::data_region_t data_region (physical_quantity, region);
+
+ F5::tensor_component_t tensor_component (data_region, m_variable);
+ int const timelevel = 0;
+ void const * const varptr
+ = CCTK_VarDataPtrI (m_cctkGH, timelevel, m_variable);
+ assert (varptr != 0);
+ int const vartype = CCTK_VarTypeI (m_variable);
+ assert (vartype >= 0);
+ tensor_component.write (varptr, vartype);
+ }
+
+
+
+ void writer_t::
+ write_one_map (F5::simulation_t & simulation)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_map map=%d", Carpet::map);
+ }
+
+ F5::mesh_refinement_topology_t topology
+ (simulation, Carpet::map, Carpet::reflevel, Carpet::maxreflevels,
+ Carpet::spacereflevelfact, Carpet::maxspacereflevelfact);
+
+ vect<CCTK_REAL, dim> level_origin, level_delta;
+ for (int d=0; d<dim; ++d)
+ {
+ cGH const * const cctkGH = m_cctkGH;
+ DECLARE_CCTK_ARGUMENTS;
+ level_origin[d] = CCTK_ORIGIN_SPACE(d);
+ level_delta[d] = CCTK_DELTA_SPACE(d);
+ }
+ F5::Cartesian_coordinate_system_t coordinate_system
+ (topology, level_origin, level_delta);
+
+ int const group = CCTK_GroupIndexFromVarI (m_variable);
+ assert (group >= 0 and group < CCTK_NumGroups());
+ F5::physical_quantity_t physical_quantity (coordinate_system, group);
+
+ if (Carpet::is_singlemap_mode())
+ {
+ int const grouptype = CCTK_GroupTypeI (group);
+ assert (grouptype >= 0);
+
+ for (Carpet::component_iterator component_iter (m_cctkGH, grouptype);
+ not component_iter.done();
+ component_iter.step())
+ {
+ write_one_component (physical_quantity);
+ }
+ }
+ else
+ {
+ write_one_component (physical_quantity);
+ }
+ }
+
+
+
+ void writer_t::
+ write_one_reflevel (F5::simulation_t & simulation)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_reflevel reflevel=%d",
+ Carpet::reflevel);
+ }
+
+ int const grouptype = CCTK_GroupTypeFromVarI (m_variable);
+ assert (grouptype >= 0);
+ assert (grouptype == CCTK_GF);
+
+ if (Carpet::is_level_mode())
+ {
+ for (Carpet::map_iterator map_iter (m_cctkGH, grouptype);
+ not map_iter.done();
+ map_iter.step())
+ {
+ write_one_map (simulation);
+ }
+ }
+ else
+ {
+ write_one_map (simulation);
+ }
+ }
+
+
+
+ void writer_t::
+ write_one_component (F5::physical_quantity_t & physical_quantity)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_component component=%d",
+ Carpet::component);
+ }
+
+ F5::file_t & file
+ = (physical_quantity.get_coordinate_system().get_topology()
+ .get_simulation().get_timestep().get_file());
+ bool const have_metafile
+ = file.get_is_metafile() and not file.get_is_datafile();
+ gh * const hh = Carpet::vhh.at(Carpet::map);
+ bool const is_local = hh->is_local (Carpet::reflevel, Carpet::component);
+ if (have_metafile or is_local)
+ {
+ dh * const dd = Carpet::vdd.at(Carpet::map);
+ bbox<int, dim> const & region
+ = (dd->boxes.at(Carpet::mglevel).at(Carpet::reflevel)
+ .at(Carpet::component).exterior);
+
+ if (have_metafile)
+ {
+ F5::meta_data_region_t meta_data_region (physical_quantity, region);
+ int const proc = hh->processor (Carpet::reflevel, Carpet::component);
+ meta_data_region.write (proc);
+ }
+
+ if (is_local)
+ {
+ F5::data_region_t data_region (physical_quantity, region);
+
+ F5::tensor_component_t tensor_component (data_region, m_variable);
+ int const timelevel = 0;
+ void const * const varptr
+ = CCTK_VarDataPtrI (m_cctkGH, timelevel, m_variable);
+ assert (varptr != 0);
+ int const vartype = CCTK_VarTypeI (m_variable);
+ assert (vartype >= 0);
+ tensor_component.write (varptr, vartype);
+ }
+ }
+ }
+
+
+
+ bbox<int,dim> const & writer_t::
+ determine_region (dh::dboxes const & boxes)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ // TODO: use superregions instead of regions (? only if the
+ // regions are on the same processor?)
+
+ bbox<int,dim> dh::dboxes::* boxptr;
+ if (CCTK_EQUALS (output_regions, "exterior"))
+ {
+ boxptr = & dh::dboxes::exterior;
+ }
+ else if (CCTK_EQUALS (output_regions, "owned"))
+ {
+ boxptr = & dh::dboxes::owned;
+ }
+ else if (CCTK_EQUALS (output_regions, "interior"))
+ {
+ boxptr = & dh::dboxes::interior;
+ }
+ else
+ {
+ assert (0);
+ }
+
+ return boxes.*boxptr;
+ }
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/writer.cc b/CarpetDev/CarpetIOF5_standalone/src/writer.cc
new file mode 100644
index 000000000..a07e1d94f
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/writer.cc
@@ -0,0 +1,400 @@
+#include <cstdlib>
+#include <sstream>
+#include <string>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+
+#include "carpet.hh"
+#include "modes.hh"
+
+#include "data_region.hh"
+#include "file.hh"
+#include "meta_data_region.hh"
+#include "physical_quantity.hh"
+#include "simulation.hh"
+#include "tensor_component.hh"
+#include "timestep.hh"
+#include "topology.hh"
+#include "utils.hh"
+#include "writer.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ writer_t::
+ writer_t (cGH const * const cctkGH,
+ int const variable)
+ : m_cctkGH (cctkGH),
+ m_variable (variable)
+ {
+ }
+
+
+
+ void writer_t::
+ write (F5::file_t & file)
+ const
+ {
+ write_meta (file);
+ }
+
+
+
+ void writer_t::
+ write_meta (F5::file_t & file)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose) {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_meta");
+ }
+
+ F5::timestep_t timestep (file, m_cctkGH->cctk_time);
+
+ if (Carpet::is_meta_mode())
+ {
+ BEGIN_MGLEVEL_LOOP (m_cctkGH)
+ {
+ write_one_mglevel (timestep);
+ }
+ END_MGLEVEL_LOOP;
+ }
+ else
+ {
+ write_one_mglevel (timestep);
+ }
+ }
+
+
+
+ void writer_t::
+ write_one_mglevel (F5::timestep_t & timestep)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_mglevel mglevel=%d",
+ Carpet::mglevel);
+ }
+
+ int const grouptype = CCTK_GroupTypeFromVarI (m_variable);
+ assert (grouptype >= 0);
+ switch (grouptype)
+ {
+ case CCTK_ARRAY:
+ case CCTK_SCALAR:
+ {
+ if (Carpet::is_global_mode())
+ {
+ ENTER_LEVEL_MODE (m_cctkGH, 0)
+ {
+ write_global (timestep);
+ }
+ LEAVE_LEVEL_MODE;
+ }
+ else
+ {
+ if (Carpet::do_global_mode)
+ {
+ write_global (timestep);
+ }
+ }
+ }
+ break;
+ case CCTK_GF:
+ {
+ if (Carpet::is_global_mode())
+ {
+ BEGIN_REFLEVEL_LOOP (m_cctkGH)
+ {
+ write_one_reflevel (timestep);
+ }
+ END_REFLEVEL_LOOP;
+ }
+ else
+ {
+ write_one_reflevel (timestep);
+ }
+ }
+ break;
+ default:
+ assert (0);
+ }
+ }
+
+
+
+ void writer_t::
+ write_global (F5::timestep_t & timestep)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_global");
+ }
+
+ int const grouptype = CCTK_GroupTypeFromVarI (m_variable);
+ assert (grouptype == CCTK_SCALAR or grouptype == CCTK_ARRAY);
+
+ BEGIN_MAP_LOOP (m_cctkGH, grouptype)
+ {
+
+ // Name the grid after the variable group
+ ostringstream namebuf;
+ char * const c_name = CCTK_GroupNameFromVarI (m_variable);
+ namebuf << "Cactus-" << c_name;
+ free (c_name);
+ string const name = namebuf.str();
+ F5::simulation_t simulation (timestep, name.c_str());
+
+ F5::unigrid_topology_t topology (simulation);
+
+ vect<CCTK_REAL, dim> const level_origin (0.0), level_delta (1.0);
+ F5::Cartesian_coordinate_system_t coordinate_system
+ (topology, level_origin, level_delta);
+
+ int const group = CCTK_GroupIndexFromVarI (m_variable);
+ assert (group >= 0 and group < CCTK_NumGroups());
+ F5::physical_quantity_t physical_quantity (coordinate_system, group);
+
+ int const myproc = CCTK_MyProc (m_cctkGH);
+
+ F5::file_t & file = timestep.get_file();
+ bool const write_metafile
+ = file.get_is_metafile() and not file.get_is_datafile();
+ if (write_metafile)
+ {
+
+ BEGIN_COMPONENT_LOOP (m_cctkGH, grouptype)
+ {
+ dh * const dd = Carpet::arrdata.at(group).at(Carpet::map).dd;
+ dh::light_dboxes const & light_boxes
+ = dd->light_boxes.at(Carpet::mglevel).at(Carpet::reflevel).at(myproc);
+ bbox<int, dim> const & region = determine_region (light_boxes);
+ F5::meta_data_region_t meta_data_region (physical_quantity, region);
+
+ gh * const hh = Carpet::vhh.at(Carpet::map);
+ int const proc = hh->processor (Carpet::reflevel, Carpet::component);
+ meta_data_region.write (proc);
+ }
+ END_COMPONENT_LOOP;
+
+ }
+ else // if not write_metafile
+ {
+
+ BEGIN_LOCAL_COMPONENT_LOOP (m_cctkGH, grouptype)
+ {
+ dh * const dd = Carpet::arrdata.at(group).at(Carpet::map).dd;
+ dh::light_dboxes const & light_boxes
+ = dd->light_boxes.at(Carpet::mglevel).at(Carpet::reflevel).at(myproc);
+ bbox<int, dim> const & region = determine_region (light_boxes);
+ F5::data_region_t data_region (physical_quantity, region);
+
+ F5::tensor_component_t tensor_component (data_region, m_variable);
+ int const timelevel = 0;
+ void const * const varptr
+ = CCTK_VarDataPtrI (m_cctkGH, timelevel, m_variable);
+ assert (varptr != 0);
+ int const vartype = CCTK_VarTypeI (m_variable);
+ assert (vartype >= 0);
+ tensor_component.write (varptr, vartype);
+ }
+ END_LOCAL_COMPONENT_LOOP;
+
+ } // if not write_metafile
+
+ }
+ END_MAP_LOOP;
+ }
+
+
+
+ void writer_t::
+ write_one_reflevel (F5::timestep_t & timestep)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_reflevel reflevel=%d",
+ Carpet::reflevel);
+ }
+
+ int const grouptype = CCTK_GroupTypeFromVarI (m_variable);
+ assert (grouptype == CCTK_GF);
+
+ if (Carpet::is_level_mode())
+ {
+ BEGIN_MAP_LOOP (m_cctkGH, grouptype)
+ {
+ write_one_map (timestep);
+ }
+ END_MAP_LOOP;
+ }
+ else
+ {
+ write_one_map (timestep);
+ }
+ }
+
+
+
+ void writer_t::
+ write_one_map (F5::timestep_t & timestep)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_map map=%d", Carpet::map);
+ }
+
+ // Name the grid after the map number
+ ostringstream namebuf;
+ namebuf << "Carpet";
+ if (Carpet::maps > 1)
+ {
+ namebuf << "-map" << Carpet::map;
+ }
+ string const name = namebuf.str();
+ F5::simulation_t simulation (timestep, name.c_str());
+
+ F5::mesh_refinement_topology_t topology
+ (simulation,
+ Carpet::map, Carpet::maps, Carpet::reflevel, Carpet::maxreflevels,
+ Carpet::spacereflevelfact, Carpet::maxspacereflevelfact);
+
+ vect<CCTK_REAL, dim> level_origin, level_delta;
+ for (int d=0; d<dim; ++d)
+ {
+ cGH const * const cctkGH = m_cctkGH;
+ DECLARE_CCTK_ARGUMENTS;
+ level_origin[d] = CCTK_ORIGIN_SPACE(d);
+ level_delta[d] = CCTK_DELTA_SPACE(d);
+ }
+ F5::Cartesian_coordinate_system_t coordinate_system
+ (topology, level_origin, level_delta);
+
+ int const group = CCTK_GroupIndexFromVarI (m_variable);
+ assert (group >= 0 and group < CCTK_NumGroups());
+ F5::physical_quantity_t physical_quantity (coordinate_system, group);
+
+ if (Carpet::is_singlemap_mode())
+ {
+ int const grouptype = CCTK_GroupTypeI (group);
+ assert (grouptype >= 0);
+
+ BEGIN_COMPONENT_LOOP (m_cctkGH, grouptype)
+ {
+ write_one_component (physical_quantity);
+ }
+ END_COMPONENT_LOOP;
+ }
+ else
+ {
+ write_one_component (physical_quantity);
+ }
+ }
+
+
+
+ void writer_t::
+ write_one_component (F5::physical_quantity_t & physical_quantity)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_component component=%d",
+ Carpet::component);
+ }
+
+ gh * const hh = Carpet::vhh.at(Carpet::map);
+ bool const is_local = hh->is_local (Carpet::reflevel, Carpet::component);
+
+ F5::file_t & file
+ = (physical_quantity.get_coordinate_system().get_topology()
+ .get_simulation().get_timestep().get_file());
+ bool const write_metafile
+ = file.get_is_metafile() and not file.get_is_datafile();
+ if (write_metafile or is_local)
+ {
+ dh * const dd = Carpet::vdd.at(Carpet::map);
+ bbox<int, dim> const & region
+ = (dd->light_boxes.at(Carpet::mglevel).at(Carpet::reflevel)
+ .at(Carpet::component).exterior);
+
+ if (write_metafile)
+ {
+ F5::meta_data_region_t meta_data_region (physical_quantity, region);
+ int const proc = hh->processor (Carpet::reflevel, Carpet::component);
+ meta_data_region.write (proc);
+ }
+ else if (is_local)
+ {
+ F5::data_region_t data_region (physical_quantity, region);
+
+ F5::tensor_component_t tensor_component (data_region, m_variable);
+ int const timelevel = 0;
+ void const * const varptr
+ = CCTK_VarDataPtrI (m_cctkGH, timelevel, m_variable);
+ assert (varptr != 0);
+ int const vartype = CCTK_VarTypeI (m_variable);
+ assert (vartype >= 0);
+ tensor_component.write (varptr, vartype);
+ }
+ }
+ }
+
+
+
+ bbox<int,dim> const & writer_t::
+ determine_region (dh::light_dboxes const & light_boxes)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ // TODO: use superregions instead of regions (? only if the
+ // regions are on the same processor?)
+
+ bbox<int,dim> dh::light_dboxes::* boxptr;
+ if (CCTK_EQUALS (output_regions, "exterior"))
+ {
+ boxptr = & dh::light_dboxes::exterior;
+ }
+ else if (CCTK_EQUALS (output_regions, "owned"))
+ {
+ boxptr = & dh::light_dboxes::owned;
+ }
+ else if (CCTK_EQUALS (output_regions, "interior"))
+ {
+ boxptr = & dh::light_dboxes::interior;
+ }
+ else
+ {
+ assert (0);
+ }
+
+ return light_boxes.*boxptr;
+ }
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5_standalone/src/writer.hh b/CarpetDev/CarpetIOF5_standalone/src/writer.hh
new file mode 100644
index 000000000..d3a6611aa
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/writer.hh
@@ -0,0 +1,70 @@
+#ifndef WRITER_HH
+#define WRITER_HH
+
+#include "cctk.h"
+
+#include "bbox.hh"
+#include "defs.hh"
+#include "dh.hh"
+#include "vect.hh"
+
+#include "file.hh"
+#include "physical_quantity.hh"
+#include "simulation.hh"
+#include "timestep.hh"
+#include "topology.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ class writer_t {
+
+ cGH const * const m_cctkGH;
+ int const m_variable;
+
+ public:
+
+ writer_t (cGH const * cctkGH,
+ int variable);
+
+ void
+ write (F5::file_t & file)
+ const;
+
+ private:
+
+ void
+ write_meta (F5::file_t & file)
+ const;
+
+ void
+ write_one_mglevel (F5::timestep_t & timestep)
+ const;
+
+ void
+ write_global (F5::timestep_t & timestep)
+ const;
+
+ void
+ write_one_reflevel (F5::timestep_t & timestep)
+ const;
+
+ void
+ write_one_map (F5::timestep_t & timestep)
+ const;
+
+ void
+ write_one_component (F5::physical_quantity_t & physical_quantity)
+ const;
+
+
+
+ static bbox<int,dim> const &
+ determine_region (dh::light_dboxes const & light_boxes);
+
+ };
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef WRITER_HH