aboutsummaryrefslogtreecommitdiff
path: root/CarpetDev
diff options
context:
space:
mode:
authorErik Schnetter <schnetter@aei.mpg.de>2005-04-25 16:10:00 +0000
committerErik Schnetter <schnetter@aei.mpg.de>2005-04-25 16:10:00 +0000
commitc3697a07c1256db7185c24750a4d3ca0506436d4 (patch)
tree207d09d80c0a369522f3ab83677d46fd8f0fa86d /CarpetDev
parent384d2acbe1f33481841c38823853fbd22976903c (diff)
CarpetIOF5: Start an I/O thorn that uses the F5 file format
darcs-hash:20050425161012-891bb-e7d03751330723d007d3dc97b0d56addc3ccda48.gz
Diffstat (limited to 'CarpetDev')
-rw-r--r--CarpetDev/CarpetIOF5/README8
-rw-r--r--CarpetDev/CarpetIOF5/configuration.ccl3
-rw-r--r--CarpetDev/CarpetIOF5/doc/documentation.tex144
-rw-r--r--CarpetDev/CarpetIOF5/interface.ccl23
-rw-r--r--CarpetDev/CarpetIOF5/param.ccl17
-rw-r--r--CarpetDev/CarpetIOF5/schedule.ccl1
-rw-r--r--CarpetDev/CarpetIOF5/src/coordinate_system.cc132
-rw-r--r--CarpetDev/CarpetIOF5/src/coordinate_system.hh83
-rw-r--r--CarpetDev/CarpetIOF5/src/data_region.cc124
-rw-r--r--CarpetDev/CarpetIOF5/src/data_region.hh50
-rw-r--r--CarpetDev/CarpetIOF5/src/extending.cc50
-rw-r--r--CarpetDev/CarpetIOF5/src/extending.hh50
-rw-r--r--CarpetDev/CarpetIOF5/src/file.cc81
-rw-r--r--CarpetDev/CarpetIOF5/src/file.hh45
-rw-r--r--CarpetDev/CarpetIOF5/src/make.code.defn15
-rw-r--r--CarpetDev/CarpetIOF5/src/physical_quantity.cc67
-rw-r--r--CarpetDev/CarpetIOF5/src/physical_quantity.hh44
-rw-r--r--CarpetDev/CarpetIOF5/src/simulation.cc68
-rw-r--r--CarpetDev/CarpetIOF5/src/simulation.hh50
-rw-r--r--CarpetDev/CarpetIOF5/src/tensor_component.cc76
-rw-r--r--CarpetDev/CarpetIOF5/src/tensor_component.hh48
-rw-r--r--CarpetDev/CarpetIOF5/src/timestep.cc85
-rw-r--r--CarpetDev/CarpetIOF5/src/timestep.hh52
-rw-r--r--CarpetDev/CarpetIOF5/src/topology.cc156
-rw-r--r--CarpetDev/CarpetIOF5/src/topology.hh100
-rw-r--r--CarpetDev/CarpetIOF5/src/utils.cc303
-rw-r--r--CarpetDev/CarpetIOF5/src/utils.hh77
27 files changed, 1952 insertions, 0 deletions
diff --git a/CarpetDev/CarpetIOF5/README b/CarpetDev/CarpetIOF5/README
new file mode 100644
index 000000000..db04ce1ad
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/README
@@ -0,0 +1,8 @@
+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.
diff --git a/CarpetDev/CarpetIOF5/configuration.ccl b/CarpetDev/CarpetIOF5/configuration.ccl
new file mode 100644
index 000000000..b098a4df2
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/configuration.ccl
@@ -0,0 +1,3 @@
+# Configuration definitions for thorn CarpetIOF5
+
+REQUIRES CarpetLib HDF5 IOUtil
diff --git a/CarpetDev/CarpetIOF5/doc/documentation.tex b/CarpetDev/CarpetIOF5/doc/documentation.tex
new file mode 100644
index 000000000..9d8b3d19e
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/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/interface.ccl b/CarpetDev/CarpetIOF5/interface.ccl
new file mode 100644
index 000000000..a5cfb62ea
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/interface.ccl
@@ -0,0 +1,23 @@
+# Interface definition for thorn CarpetIOF5
+
+IMPLEMENTS: IOF5
+
+USES INCLUDE: bbox.hh defs.hh vect.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
diff --git a/CarpetDev/CarpetIOF5/param.ccl b/CarpetDev/CarpetIOF5/param.ccl
new file mode 100644
index 000000000..726a09b0d
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/param.ccl
@@ -0,0 +1,17 @@
+# Parameter definitions for thorn CarpetIOF5
+
+STRING out_dir "Output directory, overrides 'IO::out_dir'" STEERABLE = ALWAYS
+{
+ "^$" :: "Empty: use IO::out_dir"
+ ".+" :: "Not empty: directory name"
+} ""
+
+STRING out_extension "File extension for CarpetIOF5 output" STEERABLE = ALWAYS
+{
+ ".*" :: "File extension (including a leading dot, if desired)"
+} ".f5"
+
+STRING out_vars "Variables and groups which should be output in the F5 file format" STEERABLE = ALWAYS
+{
+ .* :: "List of group or variable names"
+} ""
diff --git a/CarpetDev/CarpetIOF5/schedule.ccl b/CarpetDev/CarpetIOF5/schedule.ccl
new file mode 100644
index 000000000..0d936d041
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/schedule.ccl
@@ -0,0 +1 @@
+# Schedule definitions for thorn CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5/src/coordinate_system.cc b/CarpetDev/CarpetIOF5/src/coordinate_system.cc
new file mode 100644
index 000000000..c0371f0ca
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/coordinate_system.cc
@@ -0,0 +1,132 @@
+#include <sstream>
+
+#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 ()
+ {
+ }
+
+
+
+ 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 > 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 > 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 ()
+ {
+ herr_t const herr = H5Gclose (m_hdf5_coordinate_system);
+ assert (! herr);
+ }
+
+
+
+ void Cartesian_coordinate_system_t::
+ init ()
+ {
+ assert (all (m_level_delta > 0));
+
+ ostringstream buf;
+ buf << "Cartesian 3D, x0=" << m_level_origin << ", dx=" << m_level_delta;
+ char const * const name = buf.str().c_str();
+
+ m_hdf5_coordinate_system
+ = open_or_create_group (m_topology.get_hdf5_topology(), name);
+ assert (m_hdf5_coordinate_system >= 0);
+
+ write_or_check_attribute
+ (m_hdf5_coordinate_system, "origin", m_level_origin);
+ write_or_check_attribute
+ (m_hdf5_coordinate_system, "delta", m_level_delta);
+ }
+
+
+
+ bool Cartesian_coordinate_system_t::
+ invariant ()
+ const
+ {
+ return (coordinate_system_t::invariant()
+ and all (m_level_delta > 0));
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5/src/coordinate_system.hh b/CarpetDev/CarpetIOF5/src/coordinate_system.hh
new file mode 100644
index 000000000..c0362119e
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/coordinate_system.hh
@@ -0,0 +1,83 @@
+#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 {
+
+ protected:
+
+ topology_t & m_topology;
+
+ hid_t m_hdf5_coordinate_system;
+
+ coordinate_system_t (topology_t & topology);
+
+ public:
+
+ virtual
+ ~ coordinate_system_t ();
+
+ hid_t
+ get_hdf5_coordinate_system ()
+ 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;
+
+ 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/src/data_region.cc b/CarpetDev/CarpetIOF5/src/data_region.cc
new file mode 100644
index 000000000..77fe28485
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/data_region.cc
@@ -0,0 +1,124 @@
+#include <cassert>
+#include <cstdlib>
+#include <sstream>
+
+#include "cctk.h"
+
+#include "data_region.hh"
+#include "utils.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ using std::ostringstream;
+
+
+
+ data_region_t::
+ data_region_t (tensor_component_t & tensor_component,
+ bbox<int, dim> const & region)
+ : m_tensor_component (tensor_component),
+ m_region (region)
+ {
+ assert (! region.empty());
+
+ ostringstream buf;
+ buf << "Region " << m_region;
+ char const * const name = buf.str().c_str();
+ assert (name != 0);
+
+ int const vartype = CCTK_VarTypeI (m_tensor_component.get_variable());
+ assert (vartype >= 0);
+ hid_t const datatype = hdf5_datatype_from_cactus (vartype);
+ assert (datatype >= 0);
+
+ m_properties = H5Pcreate (H5P_DATASET_CREATE);
+ assert (m_properties >= 0);
+
+ vect<hsize_t, dim> const dims
+ = (region.shape() / region.stride()).reverse();
+ m_dataspace = H5Screate_simple (dim, & dims [0], & dims [0]);
+ assert (m_dataspace >= 0);
+
+ m_dataset
+ = H5Dcreate (m_dataspace, name, datatype, m_dataspace, m_properties);
+ assert (m_dataset >= 0);
+
+ write_or_check_attribute
+ (m_dataset, "iorigin", region.lower() / region.stride());
+
+ assert (invariant());
+ }
+
+
+
+ data_region_t::
+ ~ data_region_t ()
+ {
+ herr_t herr;
+
+ herr = H5Dclose (m_dataset);
+ assert (! herr);
+
+ herr = H5Sclose (m_dataspace);
+ assert (! herr);
+
+ herr = H5Pclose (m_properties);
+ assert (! herr);
+ }
+
+
+
+ template<typename T>
+ void data_region_t::
+ write (T const * const data)
+ const
+ {
+ T dummy;
+ hid_t const memory_datatype = hdf5_datatype (dummy);
+ assert (memory_datatype >= 0);
+
+ vect<hsize_t, dim> const dims
+ = (m_region.shape() / m_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_datatype, memory_dataspace,
+ m_dataspace, transfer_properties, data);
+ assert (! herr);
+
+ herr = H5Pclose (transfer_properties);
+ assert (! herr);
+
+ herr = H5Sclose (memory_dataspace);
+ assert (! herr);
+ }
+
+ template void data_region_t::write (CCTK_INT const * const data) const;
+ template void data_region_t::write (CCTK_REAL const * const data) const;
+ template void data_region_t::write (CCTK_COMPLEX const * const data) const;
+
+
+
+ bool data_region_t::
+ invariant ()
+ const
+ {
+ return (! m_region.empty()
+ and m_properties >= 0
+ and m_dataset >= 0
+ and m_dataspace >= 0);
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5/src/data_region.hh b/CarpetDev/CarpetIOF5/src/data_region.hh
new file mode 100644
index 000000000..f7c1713cc
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/data_region.hh
@@ -0,0 +1,50 @@
+#ifndef DATA_REGION_HH
+#define DATA_REGION_HH
+
+#include <hdf5.h>
+
+#include "bbox.hh"
+#include "defs.hh"
+
+#include "tensor_component.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ class data_region_t {
+
+ tensor_component_t & m_tensor_component;
+
+ bbox<int, dim> const m_region;
+
+ hid_t m_properties;
+ hid_t m_dataset;
+ hid_t m_dataspace;
+
+ public:
+
+ data_region_t (tensor_component_t & tensor_component,
+ bbox<int, dim> const & region);
+
+ virtual
+ ~ data_region_t ();
+
+ template<typename T>
+ void
+ write (T const * data)
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef DATA_REGION_HH
diff --git a/CarpetDev/CarpetIOF5/src/extending.cc b/CarpetDev/CarpetIOF5/src/extending.cc
new file mode 100644
index 000000000..129a96847
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/extending.cc
@@ -0,0 +1,50 @@
+#include <cassert>
+
+#include "cctk.h"
+
+#include "extending.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ char const * const extending::
+ extension_name = "CarpetIOF5";
+
+ void extending::
+ create (cGH * cctkGH)
+ {
+ assert (cctkGH);
+ int const handle = CCTK_RegisterGHExtension (extension_name);
+ assert (handle >= 0);
+ int const ierr = CCTK_RegisterGHExtensionSetupGH (handle, setup);
+ assert (! ierr);
+ }
+
+ void * extending::
+ setup (tFleshConfig * const config,
+ int const convlevel,
+ cGH * const cctkGH)
+ {
+ assert (config);
+ assert (cctkGH);
+ return new extension_t;
+ }
+
+ extending::
+ extending (cGH const * cctkGH)
+ {
+ assert (cctkGH);
+ void * const ext = CCTK_GHExtension (cctkGH, extension_name);
+ assert (ext != 0);
+ m_extension = static_cast<extension_t *> (ext);
+ }
+
+ set<char const *> extending::
+ get_did_truncate()
+ const
+ {
+ return m_extension->did_truncate;
+ }
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5/src/extending.hh b/CarpetDev/CarpetIOF5/src/extending.hh
new file mode 100644
index 000000000..5d25aaabd
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/extending.hh
@@ -0,0 +1,50 @@
+#ifndef EXTENDING_HH
+#define EXTENDING_HH
+
+#include <set>
+
+#include "cctk.h"
+
+
+
+namespace CarpetIOF5 {
+
+ using std::set;
+
+
+
+ class extending {
+
+ static char const * const extension_name;
+
+ struct extension_t {
+ set<char const *> did_truncate;
+ };
+
+ extension_t * m_extension;
+
+ public:
+
+ static void
+ create (cGH * cctkGH);
+
+ private:
+
+ static void *
+ setup (tFleshConfig * config,
+ int convlevel,
+ cGH * cctkGH);
+
+ public:
+
+ extending (cGH const * cctkGH);
+
+ set<char const *>
+ get_did_truncate ()
+ const;
+
+ };
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef EXDENDING_HH
diff --git a/CarpetDev/CarpetIOF5/src/file.cc b/CarpetDev/CarpetIOF5/src/file.cc
new file mode 100644
index 000000000..987592383
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/file.cc
@@ -0,0 +1,81 @@
+#include <cassert>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "file.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ file_t::
+ file_t (cGH const * const cctkGH,
+ char const * const filename)
+ : m_cctkGH (cctkGH),
+ m_filename (filename)
+ {
+ assert (cctkGH);
+ assert (filename);
+
+ extending extension (cctkGH);
+
+ bool const should_truncate = IO_TruncateOutputFiles (cctkGH);
+
+ bool const did_truncate
+ = (extension.get_did_truncate().find (filename)
+ != extension.get_did_truncate().end());
+
+ htri_t is_hdf5 = H5Fis_hdf5 (filename);
+ assert (is_hdf5 >= 0);
+ bool const file_exists = is_hdf5 > 0;
+
+ if ((should_truncate and ! did_truncate) or ! file_exists)
+ {
+ m_hdf5_file
+ = H5Fcreate (filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ extension.get_did_truncate().insert (filename);
+ }
+ else
+ {
+ m_hdf5_file = H5Fopen (filename, H5F_ACC_RDWR, H5P_DEFAULT);
+ }
+
+ assert (invariant());
+ }
+
+
+
+ file_t::
+ ~ file_t()
+ {
+ herr_t const herr = H5Fclose (m_hdf5_file);
+ assert (! herr);
+ }
+
+
+
+ hid_t file_t::
+ get_hdf5_file()
+ const
+ {
+ return m_hdf5_file;
+ }
+
+
+
+ bool file_t::
+ invariant()
+ const
+ {
+ return (m_cctkGH != 0
+ and m_filename != 0
+ and m_hdf5_file >= 0);
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5/src/file.hh b/CarpetDev/CarpetIOF5/src/file.hh
new file mode 100644
index 000000000..73c3b8508
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/file.hh
@@ -0,0 +1,45 @@
+#ifndef FILE_HH
+#define FILE_HH
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "extending.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ class file_t {
+
+ cGH const * const m_cctkGH;
+
+ char const * const m_filename;
+
+ hid_t m_hdf5_file;
+
+ public:
+
+ file_t (cGH const * cctkGH,
+ char const * filename);
+
+ virtual
+ ~ file_t ();
+
+ hid_t
+ get_hdf5_file ()
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef FILE_HH
diff --git a/CarpetDev/CarpetIOF5/src/make.code.defn b/CarpetDev/CarpetIOF5/src/make.code.defn
new file mode 100644
index 000000000..bed641c27
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/make.code.defn
@@ -0,0 +1,15 @@
+# Main make.code.defn file for thorn CarpetIOF5
+
+# Source files in this directory
+SRCS = coordinate_system.cc \
+ data_region.cc \
+ extending.cc file.cc \
+ physical_quantity.cc \
+ simulation.cc \
+ tensor_component.cc \
+ timestep.cc \
+ topology.cc \
+ utils.cc
+
+# Subdirectories containing source files
+SUBDIRS =
diff --git a/CarpetDev/CarpetIOF5/src/physical_quantity.cc b/CarpetDev/CarpetIOF5/src/physical_quantity.cc
new file mode 100644
index 000000000..0d6640442
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/physical_quantity.cc
@@ -0,0 +1,67 @@
+#include <cassert>
+#include <cstdlib>
+
+#include "cctk.h"
+
+#include "physical_quantity.hh"
+#include "utils.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);
+
+ 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 (! herr);
+ }
+
+
+
+ hid_t physical_quantity_t::
+ get_hdf5_physical_quantity ()
+ const
+ {
+ return m_hdf5_physical_quantity;
+ }
+
+
+
+ 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/src/physical_quantity.hh b/CarpetDev/CarpetIOF5/src/physical_quantity.hh
new file mode 100644
index 000000000..9367c8dd0
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/physical_quantity.hh
@@ -0,0 +1,44 @@
+#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;
+
+ hid_t m_hdf5_physical_quantity;
+
+ public:
+
+ physical_quantity_t (coordinate_system_t & coordinate_system,
+ int group);
+
+ virtual
+ ~ physical_quantity_t ();
+
+ hid_t
+ get_hdf5_physical_quantity ()
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef PHYSICAL_QUANTITY_HH
diff --git a/CarpetDev/CarpetIOF5/src/simulation.cc b/CarpetDev/CarpetIOF5/src/simulation.cc
new file mode 100644
index 000000000..7db365ddd
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/simulation.cc
@@ -0,0 +1,68 @@
+#include <cassert>
+#include <string>
+#include <sstream>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#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)
+ {
+ ostringstream buf;
+ buf << name;
+ m_name = buf.str();
+
+ m_hdf5_simulation
+ = open_or_create_group (m_timestep.get_hdf5_timestep(),
+ m_name.c_str());
+ assert (m_hdf5_simulation >= 0);
+
+ assert (invariant());
+ }
+
+
+
+ simulation_t::
+ ~ simulation_t()
+ {
+ herr_t const herr = H5Gclose (m_hdf5_simulation);
+ assert (! herr);
+ }
+
+
+
+ hid_t simulation_t::
+ get_hdf5_simulation()
+ const
+ {
+ return m_hdf5_simulation;
+ }
+
+
+
+ bool simulation_t::
+ invariant()
+ const
+ {
+ return m_hdf5_simulation >= 0;
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5/src/simulation.hh b/CarpetDev/CarpetIOF5/src/simulation.hh
new file mode 100644
index 000000000..33be7c2cf
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/simulation.hh
@@ -0,0 +1,50 @@
+#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 m_name;
+
+ hid_t m_hdf5_simulation;
+
+ public:
+
+ simulation_t (timestep_t & timestep,
+ char const * name);
+
+ virtual
+ ~ simulation_t ();
+
+ hid_t
+ get_hdf5_simulation ()
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef SIMULATION_HH
diff --git a/CarpetDev/CarpetIOF5/src/tensor_component.cc b/CarpetDev/CarpetIOF5/src/tensor_component.cc
new file mode 100644
index 000000000..37d013e18
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/tensor_component.cc
@@ -0,0 +1,76 @@
+#include <cassert>
+#include <cstdlib>
+
+#include "cctk.h"
+
+#include "tensor_component.hh"
+#include "utils.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ tensor_component_t::
+ tensor_component_t (physical_quantity_t & physical_quantity,
+ int const variable)
+ : m_physical_quantity (physical_quantity),
+ m_variable (variable)
+ {
+ assert (variable >= 0 and variable < CCTK_NumVars());
+
+ char * const name = CCTK_FullName (variable);
+ assert (name != 0);
+
+ m_hdf5_tensor_component
+ = open_or_create_group (m_physical_quantity
+ .get_hdf5_physical_quantity(),
+ name);
+ assert (m_hdf5_tensor_component >= 0);
+
+ free (name);
+
+ assert (invariant());
+ }
+
+
+
+ tensor_component_t::
+ ~ tensor_component_t ()
+ {
+ herr_t const herr = H5Gclose (m_hdf5_tensor_component);
+ assert (! herr);
+ }
+
+
+
+ hid_t tensor_component_t::
+ get_variable ()
+ const
+ {
+ return m_variable;
+ }
+
+
+
+ hid_t tensor_component_t::
+ get_hdf5_tensor_component ()
+ const
+ {
+ return m_hdf5_tensor_component;
+ }
+
+
+
+ bool tensor_component_t::
+ invariant ()
+ const
+ {
+ return (m_variable >= 0 and m_variable < CCTK_NumVars()
+ and m_hdf5_tensor_component >= 0);
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5/src/tensor_component.hh b/CarpetDev/CarpetIOF5/src/tensor_component.hh
new file mode 100644
index 000000000..39a8ecf23
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/tensor_component.hh
@@ -0,0 +1,48 @@
+#ifndef TENSOR_COMPONENT_HH
+#define TENSOR_COMPONENT_HH
+
+#include <hdf5.h>
+
+#include "physical_quantity.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ class tensor_component_t {
+
+ physical_quantity_t & m_physical_quantity;
+
+ int const m_variable;
+
+ hid_t m_hdf5_tensor_component;
+
+ public:
+
+ tensor_component_t (physical_quantity_t & physical_quantity,
+ int variable);
+
+ virtual
+ ~ tensor_component_t ();
+
+ hid_t
+ get_variable ()
+ const;
+
+ hid_t
+ get_hdf5_tensor_component ()
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef TENSOR_COMPONENT_HH
diff --git a/CarpetDev/CarpetIOF5/src/timestep.cc b/CarpetDev/CarpetIOF5/src/timestep.cc
new file mode 100644
index 000000000..ffed82efc
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/timestep.cc
@@ -0,0 +1,85 @@
+#include <cassert>
+#include <iomanip>
+#include <limits>
+#include <string>
+#include <sstream>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#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()
+ {
+ herr_t const herr = H5Gclose (m_hdf5_timestep);
+ assert (! herr);
+ }
+
+
+
+ hid_t timestep_t::
+ get_hdf5_timestep()
+ const
+ {
+ return m_hdf5_timestep;
+ }
+
+
+
+ bool timestep_t::
+ invariant()
+ const
+ {
+ return m_hdf5_timestep >= 0;
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5/src/timestep.hh b/CarpetDev/CarpetIOF5/src/timestep.hh
new file mode 100644
index 000000000..f02db1916
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/timestep.hh
@@ -0,0 +1,52 @@
+#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;
+
+ public:
+
+ timestep_t (file_t & file,
+ CCTK_REAL time,
+ char const * name = 0);
+
+ virtual
+ ~ timestep_t ();
+
+ hid_t
+ get_hdf5_timestep ()
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef TIMESTEP_HH
diff --git a/CarpetDev/CarpetIOF5/src/topology.cc b/CarpetDev/CarpetIOF5/src/topology.cc
new file mode 100644
index 000000000..20c8c8db7
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/topology.cc
@@ -0,0 +1,156 @@
+#include <cassert>
+#include <sstream>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "topology.hh"
+#include "utils.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ topology_t::
+ topology_t (simulation_t & simulation)
+ : m_simulation (simulation)
+ {
+ }
+
+
+
+ topology_t::
+ ~ topology_t ()
+ {
+ }
+
+
+
+ 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 = "Vertices";
+ 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 (! herr);
+ }
+
+
+
+ bool unigrid_topology_t::
+ invariant()
+ const
+ {
+ return topology_t::invariant();
+ }
+
+
+
+ mesh_refinement_topology_t::
+ mesh_refinement_topology_t (simulation_t & simulation,
+ int const refinement_level,
+ int const max_refinement_levels,
+ int const level_refinement_factor,
+ int 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 (level_refinement_factor > 0);
+ assert (level_refinement_factor <= max_refinement_factor);
+
+ ostringstream buf;
+ buf << "Vertices level " << refinement_level;
+ char const * const name = buf.str().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 > 0));
+ assert (all (level_offset_denominator > 0));
+
+ CCTK_REAL const one = 1;
+ level_delta = coarse_delta / m_level_refinement_factor;
+ level_origin
+ = (coarse_origin
+ + (level_offset * one / level_offset_denominator
+ / m_max_refinement_factor));
+ }
+
+
+
+ mesh_refinement_topology_t::
+ ~ mesh_refinement_topology_t ()
+ {
+ herr_t const herr = H5Gclose (m_hdf5_topology);
+ assert (! herr);
+ }
+
+
+
+ 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 m_level_refinement_factor > 0
+ and m_level_refinement_factor <= m_max_refinement_factor);
+ }
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5/src/topology.hh b/CarpetDev/CarpetIOF5/src/topology.hh
new file mode 100644
index 000000000..13e879e89
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/topology.hh
@@ -0,0 +1,100 @@
+#ifndef TOPOLOGY_HH
+#define TOPOLOGY_HH
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "defs.hh"
+#include "vect.hh"
+
+#include "simulation.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ class topology_t {
+
+ protected:
+
+ simulation_t & m_simulation;
+
+ hid_t m_hdf5_topology;
+
+ topology_t (simulation_t & simulation);
+
+ public:
+
+ virtual
+ ~ topology_t ();
+
+ public:
+
+ hid_t
+ get_hdf5_topology ()
+ const;
+
+ virtual bool
+ invariant ()
+ const;
+ };
+
+
+
+ class unigrid_topology_t : public topology_t {
+
+ 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;
+ int const m_level_refinement_factor;
+ int const m_max_refinement_factor;
+
+ public:
+
+ mesh_refinement_topology_t (simulation_t & simulation,
+ int refinement_level,
+ int max_refinement_levels,
+ int level_refinement_factor,
+ int max_refinement_factor);
+
+ 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 ();
+
+ virtual bool
+ invariant ()
+ const;
+ };
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
+
+#endif // #ifndef TOPOLOGY_HH
diff --git a/CarpetDev/CarpetIOF5/src/utils.cc b/CarpetDev/CarpetIOF5/src/utils.cc
new file mode 100644
index 000000000..6bd4c4b0e
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/utils.cc
@@ -0,0 +1,303 @@
+#include <cassert>
+#include <complex>
+#include <vector>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "defs.hh"
+
+#include "utils.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ using std::complex;
+ using std::vector;
+
+
+
+ hid_t
+ hdf5_datatype (signed char const & dummy)
+ {
+ return H5T_NATIVE_SCHAR;
+ }
+
+ hid_t
+ hdf5_datatype (short const & dummy)
+ {
+ return H5T_NATIVE_SHORT;
+ }
+
+ hid_t
+ hdf5_datatype (int const & dummy)
+ {
+ return H5T_NATIVE_INT;
+ }
+
+ hid_t
+ hdf5_datatype (long const & dummy)
+ {
+ return H5T_NATIVE_LONG;
+ }
+
+ hid_t
+ hdf5_datatype (long long const & dummy)
+ {
+ return H5T_NATIVE_LLONG;
+ }
+
+ hid_t
+ hdf5_datatype (float const & dummy)
+ {
+ return H5T_NATIVE_FLOAT;
+ }
+
+ hid_t
+ hdf5_datatype (double const & dummy)
+ {
+ return H5T_NATIVE_DOUBLE;
+ }
+
+ hid_t
+ hdf5_datatype (long double const & dummy)
+ {
+ return H5T_NATIVE_LDOUBLE;
+ }
+
+ hid_t
+ hdf5_datatype (CCTK_COMPLEX8 const & dummy)
+ {
+ CCTK_REAL4 real;
+ return hdf5_complex_datatype (dummy, real);
+ }
+
+ hid_t
+ hdf5_datatype (CCTK_COMPLEX16 const & dummy)
+ {
+ CCTK_REAL8 real;
+ return hdf5_complex_datatype (dummy, real);
+ }
+
+ hid_t
+ hdf5_datatype (CCTK_COMPLEX32 const & dummy)
+ {
+ CCTK_REAL16 real;
+ return hdf5_complex_datatype (dummy, real);
+ }
+
+ template<typename T, typename R>
+ hid_t
+ hdf5_complex_datatype (T const & dummy, R const & real)
+ {
+ static bool initialised = false;
+ static hid_t hdf_complex;
+
+ if (! initialised)
+ {
+ initialised = true;
+
+ hsize_t const dim = 2;
+ int const perm = 0;
+
+ hdf_complex = H5Tarray_create (hdf5_datatype (real), 1, & dim, & perm);
+ assert (hdf_complex >= 0);
+ }
+
+ return hdf_complex;
+ }
+
+
+
+ hid_t
+ hdf5_datatype_from_cactus (int const cactus_type)
+ {
+ switch (cactus_type) {
+ case CCTK_VARIABLE_VOID : return H5I_INVALID_HID;
+ case CCTK_VARIABLE_BYTE : { CCTK_BYTE const dummy = 0; return hdf5_datatype (dummy); }
+ case CCTK_VARIABLE_INT : { CCTK_INT const dummy = 0; return hdf5_datatype (dummy); }
+ case CCTK_VARIABLE_INT1 : { CCTK_INT1 const dummy = 0; return hdf5_datatype (dummy); }
+ case CCTK_VARIABLE_INT2 : { CCTK_INT2 const dummy = 0; return hdf5_datatype (dummy); }
+ case CCTK_VARIABLE_INT4 : { CCTK_INT4 const dummy = 0; return hdf5_datatype (dummy); }
+ case CCTK_VARIABLE_INT8 : { CCTK_INT8 const dummy = 0; return hdf5_datatype (dummy); }
+ case CCTK_VARIABLE_REAL : { CCTK_REAL const dummy = 0; return hdf5_datatype (dummy); }
+ case CCTK_VARIABLE_REAL4 : { CCTK_REAL4 const dummy = 0; return hdf5_datatype (dummy); }
+ case CCTK_VARIABLE_REAL8 : { CCTK_REAL8 const dummy = 0; return hdf5_datatype (dummy); }
+ case CCTK_VARIABLE_REAL16 : { CCTK_REAL16 const dummy = 0; return hdf5_datatype (dummy); }
+ case CCTK_VARIABLE_COMPLEX : { CCTK_COMPLEX dummy ; return hdf5_datatype (dummy); }
+ case CCTK_VARIABLE_COMPLEX8 : { CCTK_COMPLEX8 dummy ; return hdf5_datatype (dummy); }
+ case CCTK_VARIABLE_COMPLEX16: { CCTK_COMPLEX16 dummy ; return hdf5_datatype (dummy); }
+ case CCTK_VARIABLE_COMPLEX32: { CCTK_COMPLEX32 dummy ; return hdf5_datatype (dummy); }
+ 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;
+ }
+
+
+
+ hid_t
+ open_or_create_group (hid_t const where,
+ char const * const name)
+ {
+ 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;
+
+ hid_t group;
+ if (group_exists)
+ {
+ group = H5Gopen (where, name);
+ }
+ else
+ {
+ group = H5Gcreate (where, name, 0);
+ }
+
+ 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 (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 dim = num_values;
+ hid_t const dataspace = H5Screate_simple (1, & dim, & dim);
+ assert (dataspace >= 0);
+ attribute = H5Acreate (where, name, datatype, dataspace, H5P_DEFAULT);
+ assert (attribute >= 0);
+ herr_t herr;
+ herr = H5Awrite (attribute, datatype, values);
+ assert (! herr);
+ herr = H5Aclose (attribute);
+ assert (! herr);
+ herr = H5Sclose (dataspace);
+ assert (! 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 dim;
+ herr_t herr;
+ herr = H5Sget_simple_extent_dims (dataspace, & dim, 0);
+ assert (dim == num_values);
+ vector<T> buf (dim);
+ herr = H5Aread (attribute, datatype, & buf.front());
+ assert (! herr);
+ herr = H5Sclose (dataspace);
+ assert (! herr);
+ herr = H5Aclose (attribute);
+ assert (! herr);
+ for (int n = 0; n < num_values; ++ n)
+ {
+ assert (values [n] == buf [n]);
+ }
+ }
+ }
+
+ template
+ void
+ write_or_check_attribute (hid_t const where,
+ char const * const name,
+ 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);
+ }
+
+ template
+ void
+ write_or_check_attribute (hid_t const where,
+ char const * const name,
+ 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);
+ }
+
+ template
+ void
+ write_or_check_attribute (hid_t where,
+ char const * name,
+ vect<int, dim> const & value);
+ template
+ void
+ write_or_check_attribute (hid_t where,
+ char const * name,
+ vect<CCTK_REAL, dim> const & value);
+
+ } // namespace F5
+
+} // namespace CarpetIOF5
diff --git a/CarpetDev/CarpetIOF5/src/utils.hh b/CarpetDev/CarpetIOF5/src/utils.hh
new file mode 100644
index 000000000..28b6e044f
--- /dev/null
+++ b/CarpetDev/CarpetIOF5/src/utils.hh
@@ -0,0 +1,77 @@
+#ifndef utils_HH
+#define utils_HH
+
+#include <hdf5.h>
+
+#include "cctk.h"
+
+#include "vect.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ namespace F5 {
+
+ hid_t
+ hdf5_datatype (signed char const & dummy);
+ hid_t
+ hdf5_datatype (short const & dummy);
+ hid_t
+ hdf5_datatype (int const & dummy);
+ hid_t
+ hdf5_datatype (long const & dummy);
+ hid_t
+ hdf5_datatype (long long const & dummy);
+ hid_t
+ hdf5_datatype (float const & dummy);
+ hid_t
+ hdf5_datatype (double const & dummy);
+ hid_t
+ hdf5_datatype (long double const & dummy);
+ hid_t
+ hdf5_datatype (CCTK_COMPLEX8 const & dummy);
+ hid_t
+ hdf5_datatype (CCTK_COMPLEX16 const & dummy);
+ hid_t
+ hdf5_datatype (CCTK_COMPLEX32 const & dummy);
+
+ template<typename T, typename R>
+ hid_t
+ hdf5_complex_datatype (T const & dummy, R const & real);
+
+ hid_t
+ hdf5_datatype_from_cactus (int cactus_type);
+
+
+
+ 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