diff options
Diffstat (limited to 'CarpetDev/CarpetIOF5_standalone')
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 |