aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortradke <tradke@3af55ef0-e5e4-43b4-b020-ca5761ff09b2>2004-06-14 11:12:42 +0000
committertradke <tradke@3af55ef0-e5e4-43b4-b020-ca5761ff09b2>2004-06-14 11:12:42 +0000
commitca0c7731de7c3d2bc45175af5b521c539bd66228 (patch)
tree3e7fb5f604817d8c717e13a8cd692e96c08fac1c
parentd754a1ddfe40636e42e2c0367c687b99f917fcd4 (diff)
New I/O thorn for 1D/2D/3D output of datasets in SDF file format.
git-svn-id: http://svn.cactuscode.org/arrangements/CactusIO/IOSDF/trunk@2 3af55ef0-e5e4-43b4-b020-ca5761ff09b2
-rw-r--r--COPYRIGHT352
-rw-r--r--ConfigureWithSDF.pl30
-rw-r--r--README31
-rw-r--r--configuration.ccl10
-rw-r--r--doc/documentation.tex172
-rw-r--r--interface.ccl48
-rw-r--r--param.ccl224
-rw-r--r--schedule.ccl25
-rw-r--r--src/ChooseOutput.c149
-rw-r--r--src/Output1D.c378
-rw-r--r--src/Output2D.c382
-rw-r--r--src/Output3D.c383
-rw-r--r--src/Startup.c251
-rw-r--r--src/Write1D.c436
-rw-r--r--src/Write2D.c371
-rw-r--r--src/Write3D.c292
-rw-r--r--src/ioSDFGH.h87
-rw-r--r--src/make.code.defn6
18 files changed, 3627 insertions, 0 deletions
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644
index 0000000..57b2896
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,352 @@
+
+
+This thorn is (c) Copyright the authors listed in the sources files. This
+thorn is distributed under the GNU GPL with the specific exception that
+the GNU GPL does not migrate to code linking to or using infrastructure
+from this thorn.
+
+- The Cactus Team <cactus@cactuscode.org>
+
+**************************************************************************
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+
diff --git a/ConfigureWithSDF.pl b/ConfigureWithSDF.pl
new file mode 100644
index 0000000..0c65c5d
--- /dev/null
+++ b/ConfigureWithSDF.pl
@@ -0,0 +1,30 @@
+#! /usr/bin/perl -w
+#/*@@
+# @file ConfigureWithSDF.pl
+# @date Sat 12 Jube 2004
+# @author Thomas Radke
+# @desc
+# Configures IOSDF with external SDF installation
+# @enddesc
+# @version $Header$
+#@@*/
+
+# SDF_DIR must be given be the user
+my $bbhutil_dir = $ENV{'SDF_DIR'};
+if (! $bbhutil_dir)
+{
+ print "BEGIN ERROR\n";
+ print "IOSDF requires an external SDF installation. Please specify " .
+ "SDF_DIR to point to this installation or remove thorn IOSDF " .
+ "from your ThornList !\n";
+ print "END ERROR\n";
+ exit (-1);
+}
+
+print <<EOF;
+INCLUDE_DIRECTORY $bbhutil_dir/include
+LIBRARY bbhutil sv
+LIBRARY_DIRECTORY $bbhutil_dir/lib
+EOF
+
+exit (0);
diff --git a/README b/README
new file mode 100644
index 0000000..c300c69
--- /dev/null
+++ b/README
@@ -0,0 +1,31 @@
+Cactus Code Thorn IOSDF
+Authors : Thomas Radke (tradke@aei.mpg.de)
+CVS info : $Header$
+--------------------------------------------------------------------------
+
+1. Purpose of the thorn
+
+This thorn does 1D, 2D, and 3D output of grid variables in SDF file format.
+
+1D output slices through the edge (in octant mode) or center
+(in all origin-centered modes) of the grid in the x,y, and z directions.
+If the grid is cubed it will also slice in the diagonal direction.
+
+2D output is done for the xy, xz, and yz plane.
+
+3D output is simply done for the full 3D grid variables.
+
+The IO methods "IOSDF_1D", "IOSDF_2D", and "IOSDF_3D" are registered
+which can be called by other thorns via CCTK_OutputVarAsByMethod()
+to output a variable without specifying it in the parameter file.
+
+
+2. Additional information
+
+See the thorn documentation and check out the "Data Visualization with DV and
+xvs" webpage http://localhost/CactusWebSite/VizTools/DataVaultXVSutils.html.
+
+
+3. Acknowledgements
+
+Thanks to Luis Lehner who had the idea for this thorn.
diff --git a/configuration.ccl b/configuration.ccl
new file mode 100644
index 0000000..162dc04
--- /dev/null
+++ b/configuration.ccl
@@ -0,0 +1,10 @@
+# Configuration definitions for thorn IOSDF
+# $Header$
+
+PROVIDES SDF
+{
+ SCRIPT ConfigureWithSDF.pl
+ LANG perl
+}
+
+REQUIRES SDF
diff --git a/doc/documentation.tex b/doc/documentation.tex
new file mode 100644
index 0000000..d509105
--- /dev/null
+++ b/doc/documentation.tex
@@ -0,0 +1,172 @@
+\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/ThornGuide/cactus}
+
+\begin{document}
+
+\title{SDF Output with {\tt IOSDF}}
+\author{Thomas Radke}
+\date{$ $Date$ $}
+
+\maketitle
+
+% Do not delete next line
+% START CACTUS THORNGUIDE
+
+\begin{abstract}
+Thorn {\tt IOSDF} provides I/O methods for 1D, 2D, and 3D output of
+grid arrays and grid functions into files in SDF format. The precise
+format is designed for visualisation using the clients {\tt xvs} and
+{\tt DV} (see \url{http://localhost/CactusWebSite/VizTools/DataVaultXVSutils.html} for details).
+\end{abstract}
+
+\section{Purpose}
+Thorn {\tt IOSDF} registers three I/O methods named {\tt
+IOSDF\_1D}, {\tt IOSDF\_2D}, and {\tt IOSDF\_3D} with the I/O
+interface in the flesh.
+
+\begin{itemize}
+ \item {\tt IOSDF\_1D}\\
+ creates one-dimensional output of 1D, 2D and
+ 3D grid functions and arrays by slicing through the edge (in the
+ octant case) or center (in all origin centered cases) of the grid in
+ the coordinate directions. In addition, output is provided
+ along a diagonal of the grid, in this case the diagonal always starts
+ at the first grid point (that is, in Fortran notation {\tt var(1,1,1)})
+ and the line taken uses grid points increasing by 1 in each direction.
+ [NOTE: The diagonal output is not available for staggered variables].\\
+ Output for each direction can be selected individually via parameters.\\
+ Data is written in SDF format and goes into files with the names:
+ \begin{center}
+ {\tt <variable\_name>\_<slice>\_<center\_i><center\_j>.sdf}
+ \end{center}
+ and for diagonals:
+ \begin{center}{\tt <variable\_name>\_3D\_diagonal.sdf}
+ \end{center}
+ These files can be processed directly by {\tt xvs} and {\tt DV}.
+
+ \item {\tt IOSDF\_2D}
+ outputs two-dimensional slices of grid functions and arrays planes.
+ Again, slicing is done through the edge (in the octant case) or center
+ (in all origin centered cases).\\
+ Data is written in SDF format and goes into files named
+\begin{center}
+ {\tt <variable\_name>\_<plane>\_<center>.sdf}
+\end{center}
+ These files can be visualized by {\tt DV}.
+
+ \item {\tt IOSDF\_3D}
+ outputs three-dimensional grid functions and arrays as a whole.\\
+ Data is written in SDF format and goes into files named
+\begin{center}
+ {\tt <variable\_name>\_3D.sdf}
+\end{center}
+ These files can be visualized by {\tt DV}.
+\end{itemize}
+%
+%
+\section{{\tt IOSDF} Parameters}
+%
+General parameters to control all {\tt IOSDF}'s I/O methods are:
+\begin{itemize}
+ \item {\tt IOSDF::out[123]D\_every} (steerable)\\
+ How often to do periodic {\tt IOSDF} output. If this parameter is set in the
+ parameter file, it will override the setting of the shared
+ {\tt IO::out\_every} parameter. The output frequency can also be set
+ for individual variables using the {\tt out\_every} option in an option string appended to the {\tt IOSDF::out[123]D\_vars} parameter.
+ \item {\tt IOSDF::out[123]D\_vars} (steerable)\\
+ The list of variables to output using an {\tt IOSDF} I/O method.
+ The variables must be given by their fully qualified variable or group
+ name. The special keyword {\it all} requests {\tt IOSDF} output for
+ all variables. Multiple names must be separated by whitespaces.\\
+ An option string can be appended in curly braces to the
+ group/variable name. The only option supported so far is {\tt out\_every}
+ which sets the output frequency for an individual variable (overriding
+ {\tt IOSDF::out[123]D\_every} and {\tt IO::out\_every}).
+ \item {\tt IOSDF::out[123]D\_dir}\\
+ The directory in which to place the {\tt IOSDF} output files.
+ If the directory doesn't exist at startup it will be created.\\
+ If this parameter is set to an empty string {\tt IOSDF} output will go
+ to the standard output directory as specified in {\tt IO::out\_dir}.
+\end{itemize}
+%
+Additional parameters to control the {\tt IOSDF\_1D} I/O method are:
+\begin{itemize}
+ \item {\tt IOSDF::out1D\_[xyzd]} (steerable)\\
+ Chooses the directions to output in 1D {\tt IOSDF} format ({\tt d}
+ stands for diagonal direction).
+ \item {\tt IOSDF::out1D\_[xyz]line\_[xyz], IOSDF::out1D\_[xyz]line\_[xyz]i}\\
+ Chooses the slice centers for 1D lines from {\tt IOSDF\_1D}. These
+ can be set either in physical or index coordinates. If they are set
+ these parameters will override the default slice center parameters
+ {\tt IO::out\_[xyz]line[xyz], IO::out\_[xyz]line[xyz]i}.\\
+ Note that the slice center can only be set for grid functions so far.
+ For {\tt CCTK\_ARRAY} variables the slices will always start in the
+ origin, ie. (0, 0, 0) in C ordering.
+\end{itemize}
+%
+Additional parameters to control the {\tt IOSDF\_2D} I/O method are:
+\begin{itemize}
+ \item {\tt IOSDF::out2D\_[{xy}{xz}{yz}]plane\_[xyz], IOSDF::out2D\_[{xy}{xz}{yz}]plane\_[xyz]i}\\
+ Chooses the slice centers for 2D planes from {\tt IOSDF\_2D}. These
+ can be set either in physical or index coordinates. If they are set
+ these parameters will override the default slice center parameters
+ {\tt IO::out\_[{xy}{xz}{yz}]plane[xyz], IO::out\_[{xy}{xz}{yz}]plane[xyz]i}.
+\end{itemize}
+%
+Additional {\tt IOUtil} parameters to control the {\tt IOSDF\_[123]D} I/O methods are:
+\begin{itemize}
+ \item {\tt IO::out\_downsample\_[xyz]}\\
+ Chooses downsampling factors for individual dimensions (default is 1
+ meaning no downsampling).
+\end{itemize}
+%
+%
+\section{Comments}
+%
+{\bf Getting Output from {\tt IOSDF}'s I/O Mehtods}\\
+%
+You obtain output by an I/O method by either
+%
+\begin{itemize}
+ \item setting the appropriate I/O parameters
+ \item calling one the routines of the I/O function interface provided by the flesh
+\end{itemize}
+%
+For a description of basic I/O parameters and the I/O function interface to
+invoke I/O methods by application thorns please see the documentation of thorn
+{\tt IOUtil} and the flesh.\\[3ex]
+%
+{\bf Building Cactus configurations with {\tt IOSDF}}\\
+%
+In order to build thorn {\tt IOSDF} an external SDF installation (with includes
+and libraries) is required. You must specify the location of this SDF
+installation via the configure-time option\\
+\centerline{\tt SDF\_LOCATION=<your\_SDF\_installation\_dir>}.
+
+Since {\tt IOSDF} uses parameters from {\tt IOUtil} it also needs this I/O
+helper thorn be compiled into Cactus and activated at runtime in the
+{\tt ActiveThorns} parameter in your parameter file.
+%
+%
+\begin{thebibliography}{9}
+
+\bibitem{DataVaultXVSutils_package}
+\url{http://www.cactuscode.org/VizTools/DataVaultXVSutils.html}
+
+\bibitem{xvs_documentation}
+\url{http://laplace.physics.ubc.ca/\~matt/410/Doc/xvs/}
+
+\bibitem{DV_tutorial}
+\url{http://laplace.physics.ubc.ca/Doc/DV/}
+\end{thebibliography}
+
+
+% Do not delete next line
+% END CACTUS THORNGUIDE
+
+\end{document}
diff --git a/interface.ccl b/interface.ccl
new file mode 100644
index 0000000..2c84453
--- /dev/null
+++ b/interface.ccl
@@ -0,0 +1,48 @@
+# Interface definition for thorn IOSDF
+# $Header$
+
+implements: IOSDF
+inherits: IO
+
+CCTK_INT FUNCTION \
+ Hyperslab_GetList (CCTK_POINTER_TO_CONST IN cctkGH, \
+ CCTK_INT IN mapping_handle, \
+ CCTK_INT IN num_arrays, \
+ CCTK_INT ARRAY IN procs, \
+ CCTK_INT ARRAY IN vindices, \
+ CCTK_INT ARRAY IN timelevels, \
+ CCTK_INT ARRAY IN hdatatypes, \
+ CCTK_POINTER ARRAY IN hdata, \
+ CCTK_INT ARRAY OUT retvals)
+
+CCTK_INT FUNCTION \
+ Hyperslab_GlobalMappingByIndex (CCTK_POINTER_TO_CONST IN cctkGH, \
+ CCTK_INT IN vindex, \
+ CCTK_INT IN hdim, \
+ CCTK_INT ARRAY IN direction, \
+ CCTK_INT ARRAY IN origin, \
+ CCTK_INT ARRAY IN extent, \
+ CCTK_INT ARRAY IN downsample, \
+ CCTK_INT IN table_handle, \
+ CCTK_INT CCTK_FPOINTER IN \
+ conversion_fn (CCTK_INT IN nelems, \
+ CCTK_INT IN src_stride, \
+ CCTK_INT IN dst_stride, \
+ CCTK_INT IN src_type, \
+ CCTK_INT IN dst_type, \
+ CCTK_POINTER_TO_CONST IN from, \
+ CCTK_POINTER IN to), \
+ CCTK_INT ARRAY OUT hsize)
+
+CCTK_INT FUNCTION Hyperslab_FreeMapping (CCTK_INT IN mapping_handle)
+
+
+REQUIRES FUNCTION Hyperslab_GetList
+REQUIRES FUNCTION Hyperslab_GlobalMappingByIndex
+REQUIRES FUNCTION Hyperslab_FreeMapping
+
+CCTK_INT FUNCTION Coord_GroupSystem \
+ (CCTK_POINTER_TO_CONST IN GH, \
+ CCTK_STRING IN groupname)
+
+REQUIRES FUNCTION Coord_GroupSystem
diff --git a/param.ccl b/param.ccl
new file mode 100644
index 0000000..7331e0b
--- /dev/null
+++ b/param.ccl
@@ -0,0 +1,224 @@
+# Parameter definitions for thorn IOSDF
+# $Header$
+
+
+#############################################################################
+### declare IOSDF parameters
+#############################################################################
+private:
+
+##########################
+# Directories to output to
+##########################
+STRING out1D_dir "Output directory for 1D IOSDF files, overrides IO::out_dir" STEERABLE = RECOVER
+{
+ ".+" :: "A valid directory name"
+ "^$" :: "An empty string to choose the default from IO::out_dir"
+} ""
+STRING out2D_dir "Output directory for 2D IOSDF files, overrides out_dir" STEERABLE = RECOVER
+{
+ ".+" :: "A valid directory name"
+ "^$" :: "An empty string to choose the default from IO::out_dir"
+} ""
+STRING out3D_dir "Output directory for 3D IOSDF files, overrides IO::out_dir" STEERABLE = RECOVER
+{
+ ".+" :: "A valid directory name"
+ "^$" :: "An empty string to choose the default from IO::out_dir"
+} ""
+
+
+##########################
+# What variables to output
+##########################
+STRING out1D_vars "Variables to output in 1D IOSDF file format" STEERABLE = ALWAYS
+{
+ ".+" :: "Space-separated list of fully qualified variable/group names"
+ "^$" :: "An empty string to output nothing"
+} ""
+STRING out2D_vars "Variables to output in 2D IOSDF file format" STEERABLE = ALWAYS
+{
+ ".+" :: "Space-separated list of fully qualified variable/group names"
+ "^$" :: "An empty string to output nothing"
+} ""
+STRING out3D_vars "Variables to output in 3D IOSDF file format" STEERABLE = ALWAYS
+{
+ ".+" :: "Space-separated list of fully qualified variable/group names"
+ "^$" :: "An empty string to output nothing"
+} ""
+
+
+########################
+# How often to do output
+########################
+INT out1D_every "How often to do 1D IOSDF output, overrides IO::out_every" STEERABLE = ALWAYS
+{
+ 1:* :: "Every so many iterations"
+ 0: :: "Disable 1D IOSDF output"
+ -1: :: "Default to IO::out_every"
+} -1
+INT out2D_every "How often to do 2D IOSDF output, overrides IO::out_every" STEERABLE = ALWAYS
+{
+ 1:* :: "Every so many iterations"
+ 0: :: "Disable 2D IOSDF output"
+ -1: :: "Default to IO::out_every"
+} -1
+INT out3D_every "How often to do 3D IOSDF output, overrides IO::out_every" STEERABLE = ALWAYS
+{
+ 1:* :: "Every so many iterations"
+ 0: :: "Disable 3D IOSDF output"
+ -1: :: "Default to IO::out_every"
+} -1
+
+
+############################
+# Specific to 1D output
+# Choosing what output to do
+############################
+BOOLEAN out1D_x "Do 1D IOSDF output in the x-direction" STEERABLE = ALWAYS
+{
+} "yes"
+BOOLEAN out1D_y "Do 1D IOSDF output in the y-direction" STEERABLE = ALWAYS
+{
+} "yes"
+BOOLEAN out1D_z "Do 1D IOSDF output in the z-direction" STEERABLE = ALWAYS
+{
+} "yes"
+BOOLEAN out1D_d "Do 1D IOSDF output in the diagonal-direction" STEERABLE = ALWAYS
+{
+} "yes"
+
+################################
+# Choosing what slices to output
+################################
+REAL out1D_xline_y "y-coord for 1D lines in x-direction" STEERABLE = RECOVER
+{
+ *:* :: "A value between [ymin, ymax]"
+ -424242: :: "Default to IO::out_xline_y"
+} -424242
+REAL out1D_xline_z "z-coord for 1D lines in x-direction" STEERABLE = RECOVER
+{
+ *:* :: "A value between [zmin, zmax]"
+ -424242: :: "Default to IO::out_xline_z"
+} -424242
+REAL out1D_yline_x "x-coord for 1D lines in y-direction" STEERABLE = RECOVER
+{
+ *:* :: "A value between [xmin, xmax]"
+ -424242: :: "Default to IO::out_yline_x"
+} -424242
+REAL out1D_yline_z "z-coord for 1D lines in y-direction" STEERABLE = RECOVER
+{
+ *:* :: "A value between [zmin, zmax]"
+ -424242: :: "Default to IO::out_yline_z"
+} -424242
+REAL out1D_zline_x "x-coord for 1D lines in z-direction" STEERABLE = RECOVER
+{
+ *:* :: "A value between [xmin, xmax]"
+ -424242: :: "Default to IO::out_zline_x"
+} -424242
+REAL out1D_zline_y "y-coord for 1D lines in z-direction" STEERABLE = RECOVER
+{
+ *:* :: "A value between [ymin, ymax]"
+ -424242: :: "Default to IO::out_zline_y"
+} -424242
+
+INT out1D_xline_yi "y-index (from 0) for 1D lines in x-direction" STEERABLE = RECOVER
+{
+ 0:* :: "An index between [0, ny)"
+ -1: :: "Choose the default from IO::out_xline_yi"
+} -1
+INT out1D_xline_zi "z-index (from 0) for 1D lines in x-direction" STEERABLE = RECOVER
+{
+ 0:* :: "An index between [0, nz)"
+ -1: :: "Choose the default from IO::out_xline_zi"
+} -1
+
+INT out1D_yline_xi "x-index (from 0) for 1D lines in y-direction" STEERABLE = RECOVER
+{
+ 0:* :: "An index between [0, nx)"
+ -1: :: "Choose the default from IO::out_yline_xi"
+} -1
+INT out1D_yline_zi "z-index (from 0) for 1D lines in y-direction" STEERABLE = RECOVER
+{
+ 0:* :: "An index between [0, nz)"
+ -1: :: "Choose the default from IO::out_yline_zi"
+} -1
+
+INT out1D_zline_xi "x-index (from 0) for 1D lines in z-direction" STEERABLE = RECOVER
+{
+ 0:* :: "An index between [0, nx)"
+ -1: :: "Choose the default from IO::out_zline_xi"
+} -1
+INT out1D_zline_yi "y-index (from 0) for 1D lines in z-direction" STEERABLE = RECOVER
+{
+ 0:* :: "An index between [0, ny)"
+ -1: :: "Choose the default from IO::out_zline_yi"
+} -1
+
+
+################################
+# Specific to 2D output
+# Choosing what planes to output
+################################
+REAL out2D_yzplane_x "x-coord for 2D planes in yz" STEERABLE = RECOVER
+{
+ *:* :: "A value between [xmin, xmax]"
+ -424242: :: "Default to IO::out_yzplane_x"
+} -424242
+REAL out2D_xzplane_y "y-coord for 2D planes in xz" STEERABLE = RECOVER
+{
+ *:* :: "A value between [ymin, ymax]"
+ -424242: :: "Default to IO::out_xzplane_y"
+} -424242
+REAL out2D_xyplane_z "z-coord for 2D planes in xy" STEERABLE = RECOVER
+{
+ *:* :: "A value between [zmin, zmax]"
+ -424242: :: "Default to IO::out_xyplane_z"
+} -424242
+
+INT out2D_yzplane_xi "x-index (from 0) for 2D planes in yz" STEERABLE = RECOVER
+{
+ 0:* :: "An index between [0, nx)"
+ -1: :: "Choose the default from IO::out_yzplane_xi"
+} -1
+INT out2D_xzplane_yi "y-index (from 0) for 2D planes in xz" STEERABLE = RECOVER
+{
+ 0:* :: "An index between [0, ny)"
+ -1: :: "Choose the default from IO::out_xzplane_yi"
+} -1
+INT out2D_xyplane_zi "z-index (from 0) for 2D planes in xy" STEERABLE = RECOVER
+{
+ 0:* :: "An index between [0, nz)"
+ -1: :: "Choose the default from IO::out_xyplane_zi"
+} -1
+
+
+#############################################################################
+### import IOUtil parameters
+#############################################################################
+shares: IO
+
+USES STRING out_dir
+USES INT out_every
+USES REAL out_xline_y
+USES REAL out_xline_z
+USES REAL out_yline_x
+USES REAL out_yline_z
+USES REAL out_zline_x
+USES REAL out_zline_y
+USES INT out_xline_yi
+USES INT out_xline_zi
+USES INT out_yline_xi
+USES INT out_yline_zi
+USES INT out_zline_xi
+USES INT out_zline_yi
+USES REAL out_yzplane_x
+USES REAL out_xzplane_y
+USES REAL out_xyplane_z
+USES INT out_yzplane_xi
+USES INT out_xzplane_yi
+USES INT out_xyplane_zi
+USES INT out_downsample_x
+USES INT out_downsample_y
+USES INT out_downsample_z
+USES KEYWORD verbose
+USES BOOLEAN strict_io_parameter_check
diff --git a/schedule.ccl b/schedule.ccl
new file mode 100644
index 0000000..de179c8
--- /dev/null
+++ b/schedule.ccl
@@ -0,0 +1,25 @@
+# Schedule definitions for thorn IOSDF
+# $Header$
+
+########################################################################
+### register IOSDF routines
+########################################################################
+schedule IOSDF_Startup at STARTUP after IOUtil_Startup
+{
+ LANG:C
+} "Startup routine"
+
+schedule IOSDF_Choose1D at BASEGRID after SpatialCoordinates
+{
+ LANG:C
+} "Choose 1D output lines"
+
+schedule IOSDF_Choose2D at BASEGRID after SpatialCoordinates
+{
+ LANG:C
+} "Choose 2D output planes"
+
+schedule IOSDF_Terminate at TERMINATE
+{
+ LANG:C
+} "Close all open SDF output files"
diff --git a/src/ChooseOutput.c b/src/ChooseOutput.c
new file mode 100644
index 0000000..00ae902
--- /dev/null
+++ b/src/ChooseOutput.c
@@ -0,0 +1,149 @@
+/*@@
+ @file ChooseOutput.c
+ @author Thomas Radke
+ @date 12 June 2004
+ @desc
+ Choose what 1D slices and 2D planes to output by IOSDF.
+ @enddesc
+
+ @version $Id$
+ @@*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "CactusBase/IOUtil/src/ioutil_Utils.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Header$";
+CCTK_FILEVERSION(CactusIO_IOSDF_ChooseOutput_c)
+
+
+/********************************************************************
+ ******************** Macro Definitions ************************
+ ********************************************************************/
+/* macro to choose origin according actual parameter settings:
+ 1. Indices from IOSDF
+ 2. Indices from IOUtil
+ 3. Coords from IOSDF
+ 4. Coords from IOUtil
+ */
+#define GET_SLICE(IOSDF_param, IOUtil_param, index, coord) \
+ { \
+ index = IOSDF_param##i >= 0 ? IOSDF_param##i : IOUtil_param##i; \
+ coord = IOSDF_param != -424242 ? IOSDF_param : IOUtil_param; \
+ }
+
+
+/*@@
+ @routine IOSDF_Choose1D
+ @author Thomas Radke
+ @date 12 June 2004
+ @desc
+ Use parameters to choose the 1D slices through the output data.
+ @enddesc
+
+ @calls IOUtil_1DLines
+
+ @var GH
+ @vdesc pointer to CCTK grid hierarchy
+ @vtype const cGH *
+ @vio in
+ @endvar
+@@*/
+void IOSDF_Choose1D (const cGH *GH)
+{
+ int i, j, maxdim;
+ ioSDFGH *myGH;
+ int *origin_index[3];
+ CCTK_REAL *origin_phys[3];
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* allocate arrays for origins */
+ origin_phys[0] = malloc (3 * 3 * sizeof (CCTK_REAL));
+ origin_phys[1] = origin_phys[0] + 3;
+ origin_phys[2] = origin_phys[1] + 3;
+ origin_index[0] = malloc (3 * 3 * sizeof (int));
+ origin_index[1] = origin_index[0] + 3;
+ origin_index[2] = origin_index[1] + 3;
+
+ /* get slice points */
+ GET_SLICE (out1D_xline_y, out_xline_y, origin_index[0][1], origin_phys[0][1]);
+ GET_SLICE (out1D_xline_z, out_xline_z, origin_index[0][2], origin_phys[0][2]);
+ GET_SLICE (out1D_yline_x, out_yline_x, origin_index[1][0], origin_phys[1][0]);
+ GET_SLICE (out1D_yline_z, out_yline_z, origin_index[1][2], origin_phys[1][2]);
+ GET_SLICE (out1D_zline_x, out_zline_x, origin_index[2][0], origin_phys[2][0]);
+ GET_SLICE (out1D_zline_y, out_zline_y, origin_index[2][1], origin_phys[2][1]);
+
+ maxdim = CCTK_MaxDim ();
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ myGH->spxyz = malloc (maxdim * sizeof (int **));
+
+ for (i = 0; i < maxdim; i++)
+ {
+ myGH->spxyz[i] = malloc ((i + 1) * sizeof (int *));
+
+ for (j = 0; j <= i; j++)
+ {
+ myGH->spxyz[i][j] = calloc (i + 1, sizeof (int));
+ }
+
+ if (i < 3)
+ {
+ IOUtil_1DLines (GH, i + 1, origin_index, origin_phys, myGH->spxyz[i]);
+ }
+ }
+
+ /* free allocated resources */
+ free (origin_phys[0]);
+ free (origin_index[0]);
+}
+
+
+/*@@
+ @routine IOSDF_Choose2D
+ @author Thomas Radke
+ @date 12 June 2004
+ @desc
+ Use parameters to choose the 2D slices through the output data.
+ @enddesc
+
+ @calls IOUtil_2DPlanes
+
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @@*/
+void IOSDF_Choose2D (const cGH *GH)
+{
+ int i, maxdim;
+ ioSDFGH *myGH;
+ int origin_index[3];
+ CCTK_REAL origin_phys[3];
+ DECLARE_CCTK_PARAMETERS
+
+
+ GET_SLICE (out2D_xyplane_z, out_xyplane_z, origin_index[0], origin_phys[0]);
+ GET_SLICE (out2D_xzplane_y, out_xzplane_y, origin_index[1], origin_phys[1]);
+ GET_SLICE (out2D_yzplane_x, out_yzplane_x, origin_index[2], origin_phys[2]);
+
+ maxdim = CCTK_MaxDim ();
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ myGH->sp2xyz = malloc (3 * sizeof (int *));
+
+ for (i = 0; i < maxdim; i++)
+ {
+ myGH->sp2xyz[i] = calloc (i + 1, sizeof (int));
+
+ if (i == 2)
+ {
+ IOUtil_2DPlanes (GH, i + 1, origin_index, origin_phys, myGH->sp2xyz[i]);
+ }
+ }
+}
diff --git a/src/Output1D.c b/src/Output1D.c
new file mode 100644
index 0000000..1f572f9
--- /dev/null
+++ b/src/Output1D.c
@@ -0,0 +1,378 @@
+ /*@@
+ @file Output1D.c
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Functions to deal with 1D SDF output of variables
+ @enddesc
+ @version $Id$
+ @@*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "util_String.h"
+#include "CactusBase/IOUtil/src/ioutil_Utils.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Id$";
+CCTK_FILEVERSION(CactusIO_IOSDF_Output1D_c)
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static int CheckOutputVar (int vindex);
+static void SetOutputFlag (int vindex, const char *optstring, void *arg);
+
+
+/*@@
+ @routine IOSDF_Output1DGH
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Loops over all variables and outputs them if necessary
+ @enddesc
+ @calls IOSDF_TimeFor1D
+ IOSDF_Write1D
+
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ the number of variables which were output at this iteration
+ (or 0 if it wasn't time to output yet)
+ @endreturndesc
+@@*/
+int IOSDF_Output1DGH (const cGH *GH)
+{
+ int vindex, retval;
+ const ioSDFGH *myGH;
+
+
+ retval = 0;
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ /* loop over all variables */
+ for (vindex = CCTK_NumVars () - 1; vindex >= 0; vindex--)
+ {
+ if (IOSDF_TimeFor1D (GH, vindex) &&
+ IOSDF_Write1D (GH, vindex, CCTK_VarName (vindex)) == 0)
+ {
+ /* register variable as having 1D output this iteration */
+ myGH->out1D_last[vindex] = GH->cctk_iteration;
+ retval++;
+ }
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_Output1DVarAs
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Unconditional output of a variable
+ using the IOSDF output method
+ @enddesc
+ @calls IOSDF_Write1D
+
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var fullname
+ @vdesc complete name of variable to output
+ @vtype const char *
+ @vio in
+ @endvar
+ @var alias
+ @vdesc alias name of variable to output
+ (used to generate output filename)
+ @vtype const char *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine IOSDF_Write1D, or<BR>
+ -1 if variable cannot be output by IOSDF_1D
+ @endreturndesc
+@@*/
+int IOSDF_Output1DVarAs (const cGH *GH, const char *fullname, const char *alias)
+{
+ int vindex, retval;
+
+
+ retval = -1;
+ vindex = CCTK_VarIndex (fullname);
+ if (vindex < 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "There is no such variable %s. Ignoring IOSDF 1D output.",
+ fullname);
+ }
+ else if (CheckOutputVar (vindex))
+ {
+ retval = IOSDF_Write1D (GH, vindex, alias);
+ }
+
+ return (retval);
+}
+
+
+ /*@@
+ @routine IOSDF_TimeFor1D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Decides if it is time to output a variable
+ using the IO 1D output method
+ @enddesc
+
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ 1 if output should take place at this iteration, or<BR>
+ 0 if not
+ @endreturndesc
+@@*/
+int IOSDF_TimeFor1D (const cGH *GH, int vindex)
+{
+ int retval;
+ char *fullname;
+ ioSDFGH *myGH;
+
+
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ IOSDF_CheckSteerableParameters1D (myGH);
+
+ /* check if this variable should be output */
+ retval = myGH->out1D_every[vindex] > 0 &&
+ GH->cctk_iteration % myGH->out1D_every[vindex] == 0;
+ if (retval)
+ {
+ /* check if this variable wasn't already output this iteration */
+ if (myGH->out1D_last[vindex] == GH->cctk_iteration)
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Already done IOSDF 1D output for '%s' in current "
+ "iteration (probably via triggers)", fullname);
+ free (fullname);
+ retval = 0;
+ }
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_TriggerOutput1D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Triggers the output a variable
+ using the IOSDF output method method
+ @enddesc
+ @calls IOSDF_Write1D
+
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable to output
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine IOSDF_Write1D
+ @endreturndesc
+@@*/
+int IOSDF_TriggerOutput1D (const cGH *GH, int vindex)
+{
+ int retval;
+ ioSDFGH *myGH;
+
+
+ retval = IOSDF_Write1D (GH, vindex, CCTK_VarName (vindex));
+ if (retval == 0)
+ {
+ /* register variables as having 1D output this iteration */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ myGH->out1D_last[vindex] = GH->cctk_iteration;
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_CheckSteerableParameters1D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Check if steerable IOSDF 1D parameters have changed
+ @enddesc
+ @calls CCTK_TraverseString
+
+ @var myGH
+ @vdesc Pointer to IOSDF GH
+ @vtype ioSDFGH *
+ @vio inout
+ @endvar
+@@*/
+void IOSDF_CheckSteerableParameters1D (ioSDFGH *myGH)
+{
+ int i, num_vars;
+ char *fullname, *msg;
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* how often to output */
+ i = myGH->out1D_every_default;
+ myGH->out1D_every_default = out1D_every >= 0 ? out1D_every : out_every;
+
+ /* report if frequency changed */
+ if (myGH->out1D_every_default != i && ! CCTK_Equals (verbose, "none"))
+ {
+ if (myGH->out1D_every_default > 0)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING, "Periodic 1D output every %d "
+ "iterations", myGH->out1D_every_default);
+ }
+ else
+ {
+ CCTK_INFO ("Periodic 1D output turned off");
+ }
+ }
+
+ /* re-parse the 'out1D_vars' parameter if it was changed */
+ if (strcmp (out1D_vars, myGH->out1D_vars) || myGH->out1D_every_default != i)
+ {
+ num_vars = CCTK_NumVars ();
+ memset (myGH->out1D_every, 0, num_vars * sizeof (CCTK_INT));
+ if (CCTK_TraverseString (out1D_vars, SetOutputFlag, myGH,
+ CCTK_GROUP_OR_VAR) < 0)
+ {
+ CCTK_WARN (myGH->stop_on_parse_errors ? 0 : 1,
+ "error while parsing parameter 'IOSDF::out1D_vars'");
+ }
+
+ if (myGH->out1D_every_default == i || ! CCTK_Equals (verbose, "none"))
+ {
+ msg = NULL;
+ for (i = 0; i < num_vars; i++)
+ {
+ if (myGH->out1D_every[i] > 0)
+ {
+ fullname = CCTK_FullName (i);
+ if (! msg)
+ {
+ Util_asprintf (&msg, "Periodic 1D output requested for "
+ "'%s'", fullname);
+ }
+ else
+ {
+ Util_asprintf (&msg, "%s, '%s'", msg, fullname);
+ }
+ free (fullname);
+ }
+ }
+ if (msg)
+ {
+ CCTK_INFO (msg);
+ free (msg);
+ }
+ }
+
+ /* save the last setting of 'out1D_vars' parameter */
+ free (myGH->out1D_vars);
+ myGH->out1D_vars = strdup (out1D_vars);
+ }
+}
+
+
+/**************************** local functions ******************************/
+/* check if this variable can be output (static conditions) */
+static int CheckOutputVar (int vindex)
+{
+ int groupindex;
+ cGroup groupinfo;
+ char *fullname;
+ const char *errormsg;
+
+
+ /* get the variable group information */
+ groupindex = CCTK_GroupIndexFromVarI (vindex);
+ CCTK_GroupData (groupindex, &groupinfo);
+
+ errormsg = NULL;
+ if (groupinfo.grouptype != CCTK_GF && groupinfo.grouptype != CCTK_ARRAY)
+ {
+ errormsg = "not a grid function or array";
+ }
+ else if (strncmp (CCTK_VarTypeName (groupinfo.vartype),
+ "CCTK_VARIABLE_REAL", 18) ||
+ CCTK_VarTypeSize (groupinfo.vartype) != sizeof (double))
+ {
+ errormsg = "not a double-precision floating-point grid function or array";
+ }
+
+ if (errormsg)
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "No IOSDF 1D output for '%s': %s", fullname, errormsg);
+ free (fullname);
+ }
+
+ return (errormsg == NULL);
+}
+
+
+/* callback for CCTK_TraverseString() to set the output flag
+ for the given variable */
+static void SetOutputFlag (int vindex, const char *optstring, void *arg)
+{
+ const ioSDFGH *myGH = arg;
+
+
+ if (CheckOutputVar (vindex))
+ {
+ myGH->out1D_every[vindex] = myGH->out1D_every_default;
+
+ if (optstring)
+ {
+ IOUtil_ParseOutputFrequency ("1D IOSDF", "IOSDF::out1D_vars",
+ myGH->stop_on_parse_errors,
+ vindex, optstring,
+ &myGH->out1D_every[vindex]);
+ }
+ }
+}
diff --git a/src/Output2D.c b/src/Output2D.c
new file mode 100644
index 0000000..5eb5161
--- /dev/null
+++ b/src/Output2D.c
@@ -0,0 +1,382 @@
+ /*@@
+ @file Output2D.c
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Functions to deal with 2D SDF output of variables
+ @enddesc
+ @version $Id$
+ @@*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "util_String.h"
+#include "CactusBase/IOUtil/src/ioutil_Utils.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Id$";
+CCTK_FILEVERSION(CactusIO_IOSDF_Output2D_c)
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static int CheckOutputVar (int vindex);
+static void SetOutputFlag (int vindex, const char *optstring, void *arg);
+
+
+/*@@
+ @routine IOSDF_Output2DGH
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Loops over all variables and outputs them if necessary
+ @enddesc
+ @calls IOSDF_TimeFor2D
+ IOSDF_Write2D
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ the number of variables which were output at this iteration
+ (or 0 if it wasn't time to output yet)
+ @endreturndesc
+@@*/
+int IOSDF_Output2DGH (const cGH *GH)
+{
+ int vindex, retval;
+ const ioSDFGH *myGH;
+
+
+ retval = 0;
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ /* loop over all variables */
+ for (vindex = CCTK_NumVars () - 1; vindex >= 0; vindex--)
+ {
+ if (IOSDF_TimeFor2D (GH, vindex) &&
+ IOSDF_Write2D (GH, vindex, CCTK_VarName (vindex)) == 0)
+ {
+ /* register variable as having 2D output this iteration */
+ myGH->out2D_last[vindex] = GH->cctk_iteration;
+ retval++;
+ }
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_Output2DVarAs
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Unconditional output of a variable
+ using the IOSDF 2D output method
+ @enddesc
+ @calls IOSDF_Write2D
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var fullname
+ @vdesc complete name of variable to output
+ @vtype const char *
+ @vio in
+ @endvar
+ @var alias
+ @vdesc alias name of variable to output
+ (used to generate output filename)
+ @vtype const char *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine IOSDF_Write2D, or<BR>
+ -1 if variable cannot be output by IOSDF_2D
+ @endreturndesc
+@@*/
+int IOSDF_Output2DVarAs (const cGH *GH, const char *fullname, const char *alias)
+{
+ int vindex, retval;
+
+
+ retval = -1;
+ vindex = CCTK_VarIndex (fullname);
+ if (vindex<0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "There is no such variable %s. Ignoring IOSDF 2D output.",
+ fullname);
+ } else if (CheckOutputVar (vindex) == 0)
+ {
+ retval = IOSDF_Write2D (GH, vindex, alias);
+ }
+
+ return (retval);
+}
+
+
+ /*@@
+ @routine IOSDF_TimeFor2D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Decides if it is time to output a variable
+ using the IOSDF 2D output method
+ @enddesc
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ 1 if output should take place at this iteration, or<BR>
+ 0 if not
+ @endreturndesc
+@@*/
+int IOSDF_TimeFor2D (const cGH *GH, int vindex)
+{
+ int retval;
+ char *fullname;
+ ioSDFGH *myGH;
+
+
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ IOSDF_CheckSteerableParameters2D (myGH);
+
+ /* check if this variable should be output */
+ retval = myGH->out2D_every[vindex] > 0 &&
+ GH->cctk_iteration % myGH->out2D_every[vindex] == 0;
+ if (retval)
+ {
+ /* check if variable wasn't already output this iteration */
+ if (myGH->out2D_last[vindex] == GH->cctk_iteration)
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Already done IOSDF 2D output for '%s' in current "
+ "iteration (probably via triggers)", fullname);
+ free (fullname);
+ retval = 0;
+ }
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_TriggerOutput2D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Triggers the output of a variable
+ using the IOSDF 2D output method
+ @enddesc
+ @calls IOSDF_Write2D
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable to output
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine IOSDF_Write2D
+ @endreturndesc
+@@*/
+int IOSDF_TriggerOutput2D (const cGH *GH, int vindex)
+{
+ int retval;
+ ioSDFGH *myGH;
+
+
+ /* do the 2D output */
+ retval = IOSDF_Write2D (GH, vindex, CCTK_VarName (vindex));
+ if (retval == 0)
+ {
+ /* register variable as having 2D output this iteration */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ myGH->out2D_last[vindex] = GH->cctk_iteration;
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_CheckSteerableParameters2D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Check if steerable IOSDF 2D parameters have changed
+ @enddesc
+ @calls CCTK_TraverseString
+
+ @var myGH
+ @vdesc Pointer to IOSDF GH
+ @vtype ioSDFGH *
+ @vio inout
+ @endvar
+@@*/
+void IOSDF_CheckSteerableParameters2D (ioSDFGH *myGH)
+{
+ int i, num_vars;
+ char *fullname, *msg;
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* how often to output */
+ i = myGH->out2D_every_default;
+ myGH->out2D_every_default = out2D_every >= 0 ? out2D_every : out_every;
+
+ /* report if frequency changed */
+ if (myGH->out2D_every_default != i && ! CCTK_Equals (verbose, "none"))
+ {
+ if (myGH->out2D_every_default > 0)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING, "Periodic 2D output every %d "
+ "iterations", myGH->out2D_every_default);
+ }
+ else
+ {
+ CCTK_INFO ("Periodic 2D output turned off");
+ }
+ }
+
+ /* re-parse the 'out2D_vars' parameter if it was changed */
+ if (strcmp (out2D_vars, myGH->out2D_vars) || myGH->out2D_every_default != i)
+ {
+ num_vars = CCTK_NumVars ();
+ memset (myGH->out2D_every, 0, num_vars * sizeof (CCTK_INT));
+ if (CCTK_TraverseString (out2D_vars, SetOutputFlag, myGH,
+ CCTK_GROUP_OR_VAR) < 0)
+ {
+ CCTK_WARN (myGH->stop_on_parse_errors ? 0 : 1,
+ "error while parsing parameter 'IOSDF::out2D_vars'");
+ }
+
+ if (myGH->out2D_every_default == i || ! CCTK_Equals (verbose, "none"))
+ {
+ msg = NULL;
+ for (i = 0; i < num_vars; i++)
+ {
+ if (myGH->out2D_every[i])
+ {
+ fullname = CCTK_FullName (i);
+ if (! msg)
+ {
+ Util_asprintf (&msg, "Periodic 2D output requested for "
+ "'%s'", fullname);
+ }
+ else
+ {
+ Util_asprintf (&msg, "%s, '%s'", msg, fullname);
+ }
+ free (fullname);
+ }
+ }
+ if (msg)
+ {
+ CCTK_INFO (msg);
+ free (msg);
+ }
+ }
+
+ /* save the last setting of 'out2D_vars' parameter */
+ free (myGH->out2D_vars);
+ myGH->out2D_vars = strdup (out2D_vars);
+ }
+}
+
+
+/**************************** local functions ******************************/
+/* check if this variable can be output (static conditions) */
+static int CheckOutputVar (int vindex)
+{
+ int groupindex;
+ cGroup groupinfo;
+ char *fullname;
+ const char *errormsg;
+
+
+ /* get the variable group information */
+ groupindex = CCTK_GroupIndexFromVarI (vindex);
+ CCTK_GroupData (groupindex, &groupinfo);
+
+ errormsg = NULL;
+ if (groupinfo.dim < 2 || groupinfo.dim > 3)
+ {
+ errormsg = "dim != [2,3]";
+ }
+ else if (groupinfo.grouptype != CCTK_GF && groupinfo.grouptype != CCTK_ARRAY)
+ {
+ errormsg = "not a grid function or array";
+ }
+ else if (strncmp (CCTK_VarTypeName (groupinfo.vartype),
+ "CCTK_VARIABLE_REAL", 18) ||
+ CCTK_VarTypeSize (groupinfo.vartype) != sizeof (double))
+ {
+ errormsg = "not a double-precision floating-point grid function or array";
+ }
+
+ if (errormsg)
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "No IOSDF 2D output for '%s': %s", fullname, errormsg);
+ free (fullname);
+ }
+
+ return (errormsg != NULL);
+}
+
+
+/* callback for CCTK_TraverseString() to set the output flag
+ for the given variable */
+static void SetOutputFlag (int vindex, const char *optstring, void *arg)
+{
+ const ioSDFGH *myGH = arg;
+
+
+ if (CheckOutputVar (vindex) == 0)
+ {
+ myGH->out2D_every[vindex] = myGH->out2D_every_default;
+
+ if (optstring)
+ {
+ IOUtil_ParseOutputFrequency ("2D IOSDF", "IOSDF::out2D_vars",
+ myGH->stop_on_parse_errors,
+ vindex, optstring,
+ &myGH->out2D_every[vindex]);
+ }
+ }
+}
diff --git a/src/Output3D.c b/src/Output3D.c
new file mode 100644
index 0000000..16e01a5
--- /dev/null
+++ b/src/Output3D.c
@@ -0,0 +1,383 @@
+ /*@@
+ @file Output3D.c
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Functions to deal with 3D SDF output of variables
+ @enddesc
+ @version $Id$
+ @@*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "util_String.h"
+#include "CactusBase/IOUtil/src/ioutil_Utils.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Id$";
+CCTK_FILEVERSION(CactusIO_IOSDF_Output3D_c)
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static int CheckOutputVar (int vindex);
+static void SetOutputFlag (int vindex, const char *optstring, void *arg);
+
+
+/*@@
+ @routine IOSDF_Output3DGH
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Loops over all variables and outputs them if necessary
+ @enddesc
+ @calls IOSDF_TimeFor3D
+ IOSDF_Write3D
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ the number of variables which were output at this iteration
+ (or 0 if it wasn't time to output yet)
+ @endreturndesc
+@@*/
+int IOSDF_Output3DGH (const cGH *GH)
+{
+ int vindex, retval;
+ const ioSDFGH *myGH;
+
+
+ retval = 0;
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ /* loop over all variables */
+ for (vindex = CCTK_NumVars () - 1; vindex >= 0; vindex--)
+ {
+ if (IOSDF_TimeFor3D (GH, vindex) &&
+ IOSDF_Write3D (GH, vindex, CCTK_VarName (vindex)) == 0)
+ {
+ /* register variable as having 3D output this iteration */
+ myGH->out3D_last[vindex] = GH->cctk_iteration;
+ retval++;
+ }
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_Output3DVarAs
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Unconditional output of a variable
+ using the IOSDF 3D output method
+ @enddesc
+ @calls IOSDF_Write3D
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var fullname
+ @vdesc complete name of variable to output
+ @vtype const char *
+ @vio in
+ @endvar
+ @var alias
+ @vdesc alias name of variable to output
+ (used to generate output filename)
+ @vtype const char *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine IOSDF_Write3D, or<BR>
+ -1 if variable cannot be output by IOSDF_3D
+ @endreturndesc
+@@*/
+int IOSDF_Output3DVarAs (const cGH *GH, const char *fullname, const char *alias)
+{
+ int vindex, retval;
+
+
+ retval = -1;
+ vindex = CCTK_VarIndex (fullname);
+ if (vindex<0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "There is no such variable %s. Ignoring IOSDF 3D output.",
+ fullname);
+ } else if (CheckOutputVar (vindex) == 0)
+ {
+ retval = IOSDF_Write3D (GH, vindex, alias);
+ }
+
+ return (retval);
+}
+
+
+ /*@@
+ @routine IOSDF_TimeFor3D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Decides if it is time to output a variable
+ using the IOSDF 3D output method
+ @enddesc
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ 1 if output should take place at this iteration, or<BR>
+ 0 if not
+ @endreturndesc
+@@*/
+int IOSDF_TimeFor3D (const cGH *GH, int vindex)
+{
+ int retval;
+ char *fullname;
+ ioSDFGH *myGH;
+
+
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ IOSDF_CheckSteerableParameters3D (myGH);
+
+ /* check if this variable should be output */
+ retval = myGH->out3D_every[vindex] > 0 &&
+ GH->cctk_iteration % myGH->out3D_every[vindex] == 0;
+ if (retval)
+ {
+ /* check if variable wasn't already output this iteration */
+ if (myGH->out3D_last[vindex] == GH->cctk_iteration)
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Already done IOSDF 3D output for '%s' in current "
+ "iteration (probably via triggers)", fullname);
+ free (fullname);
+ retval = 0;
+ }
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_TriggerOutput3D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Triggers the output of a variable
+ using the IOSDF 3D output method
+ @enddesc
+ @calls IOSDF_Write3D
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable to output
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine IOSDF_Write3D
+ @endreturndesc
+@@*/
+int IOSDF_TriggerOutput3D (const cGH *GH, int vindex)
+{
+ int retval;
+ ioSDFGH *myGH;
+
+
+ /* do the 3D output */
+ retval = IOSDF_Write3D (GH, vindex, CCTK_VarName (vindex));
+ if (retval == 0)
+ {
+ /* register variables as having 3D output this iteration */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ myGH->out3D_last[vindex] = GH->cctk_iteration;
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_CheckSteerableParameters3D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Check if steerable IOSDF 3D parameters have changed
+ @enddesc
+ @calls CCTK_TraverseString
+
+ @var myGH
+ @vdesc Pointer to IOSDF GH
+ @vtype ioSDFGH *
+ @vio inout
+ @endvar
+@@*/
+void IOSDF_CheckSteerableParameters3D (ioSDFGH *myGH)
+{
+ int i, num_vars;
+ char *fullname, *msg;
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* how often to output */
+ i = myGH->out3D_every_default;
+ myGH->out3D_every_default = out3D_every >= 0 ? out3D_every : out_every;
+
+ /* report if frequency changed */
+ if (myGH->out3D_every_default != i && ! CCTK_Equals (verbose, "none"))
+ {
+ if (myGH->out3D_every_default > 0)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING, "Periodic 3D output every %d "
+ "iterations", myGH->out3D_every_default);
+ }
+ else
+ {
+ CCTK_INFO ("Periodic 3D output turned off");
+ }
+ }
+
+ /* re-parse the 'out3D_vars' parameter if it was changed */
+ if (strcmp (out3D_vars, myGH->out3D_vars) || myGH->out3D_every_default != i)
+ {
+ num_vars = CCTK_NumVars ();
+ memset (myGH->out3D_every, 0, num_vars * sizeof (CCTK_INT));
+ if (CCTK_TraverseString (out3D_vars, SetOutputFlag, myGH,
+ CCTK_GROUP_OR_VAR) < 0)
+ {
+ CCTK_WARN (myGH->stop_on_parse_errors ? 0 : 1,
+ "error while parsing parameter 'IOSDF::out3D_vars'");
+ }
+
+ if (myGH->out3D_every_default == i || ! CCTK_Equals (verbose, "none"))
+ {
+ msg = NULL;
+ for (i = 0; i < num_vars; i++)
+ {
+ if (myGH->out3D_every[i] > 0)
+ {
+ fullname = CCTK_FullName (i);
+ if (! msg)
+ {
+ Util_asprintf (&msg, "Periodic 3D output requested for "
+ "'%s'", fullname);
+ }
+ else
+ {
+ Util_asprintf (&msg, "%s, '%s'", msg, fullname);
+ }
+ free (fullname);
+ }
+ }
+ if (msg)
+ {
+ CCTK_INFO (msg);
+ free (msg);
+ }
+ }
+
+ /* save the last setting of 'out3D_vars' parameter */
+ free (myGH->out3D_vars);
+ myGH->out3D_vars = strdup (out3D_vars);
+ }
+}
+
+
+/**************************** local functions ******************************/
+/* check if this variable can be output (static conditions) */
+static int CheckOutputVar (int vindex)
+{
+ int groupindex;
+ cGroup groupinfo;
+ char *fullname;
+ const char *errormsg;
+
+
+ /* get the variable group information */
+ groupindex = CCTK_GroupIndexFromVarI (vindex);
+ CCTK_GroupData (groupindex, &groupinfo);
+
+ /* check if variable is grid array type with 3 dimensions */
+ errormsg = NULL;
+ if (groupinfo.dim != 3)
+ {
+ errormsg = "dim != 3";
+ }
+ else if (groupinfo.grouptype != CCTK_GF && groupinfo.grouptype != CCTK_ARRAY)
+ {
+ errormsg = "not a grid function or array";
+ }
+ else if (strncmp (CCTK_VarTypeName (groupinfo.vartype),
+ "CCTK_VARIABLE_REAL", 18) ||
+ CCTK_VarTypeSize (groupinfo.vartype) != sizeof (double))
+ {
+ errormsg = "not a double-precision floating-point grid function or array";
+ }
+
+ if (errormsg)
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "No IOSDF 3D output for '%s': %s", fullname, errormsg);
+ free (fullname);
+ }
+
+ return (errormsg != NULL);
+}
+
+
+/* callback for CCTK_TraverseString() to set the output flag
+ for the given variable */
+static void SetOutputFlag (int vindex, const char *optstring, void *arg)
+{
+ const ioSDFGH *myGH = arg;
+
+
+ if (CheckOutputVar (vindex) == 0)
+ {
+ myGH->out3D_every[vindex] = myGH->out3D_every_default;
+
+ if (optstring)
+ {
+ IOUtil_ParseOutputFrequency ("3D IOSDF", "IOSDF::out3D_vars",
+ myGH->stop_on_parse_errors,
+ vindex, optstring,
+ &myGH->out3D_every[vindex]);
+ }
+ }
+}
diff --git a/src/Startup.c b/src/Startup.c
new file mode 100644
index 0000000..fbb8b79
--- /dev/null
+++ b/src/Startup.c
@@ -0,0 +1,251 @@
+ /*@@
+ @file Startup.c
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Startup routines for IOSDF.
+ @enddesc
+ @version $Id$
+ @@*/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_IOMethods.h"
+#include "cctk_Parameters.h"
+#include "CactusBase/IOUtil/src/ioutil_Utils.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Id$";
+CCTK_FILEVERSION(CactusIO_IOSDF_Startup_c)
+
+
+/********************************************************************
+ ******************** Macro Definitions ************************
+ ********************************************************************/
+#define CREATE_OUTDIR(dim, dir) \
+ { \
+ const char *_dir = dir; \
+ \
+ \
+ /* check whether "dir" was set; if not default to "IO::out_dir" */ \
+ if (*_dir == 0) \
+ { \
+ _dir = out_dir; \
+ } \
+ \
+ /* omit the directory name if it's the current working dir */ \
+ if (strcmp (_dir, ".") == 0) \
+ { \
+ myGH->dir = strdup (""); \
+ } \
+ else \
+ { \
+ myGH->dir = malloc (strlen (_dir) + 2); \
+ sprintf (myGH->dir, "%s/", _dir); \
+ } \
+ \
+ /* create the directory */ \
+ i = IOUtil_CreateDirectory (GH, myGH->dir, 0, 0); \
+ if (i < 0) \
+ { \
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, \
+ "IOSDF_SetupGH: Problem creating directory '%s' " \
+ "for %dD output", myGH->dir, dim); \
+ } \
+ else if (i >= 0 && CCTK_Equals (verbose, "full")) \
+ { \
+ CCTK_VInfo (CCTK_THORNSTRING, "%dD output to directory '%s'", \
+ dim, myGH->dir); \
+ } \
+ }
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static void *IOSDF_SetupGH (tFleshConfig *config, int conv_level, cGH *GH);
+
+
+ /*@@
+ @routine IOSDF_Startup
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ The startup registration routine for IOSDF.
+ Registers the GH extensions needed for IOSDF
+ along with its setup routine.
+ @enddesc
+ @calls CCTK_RegisterGHExtension
+ CCTK_RegisterGHExtensionSetupGH
+@@*/
+void IOSDF_Startup (void)
+{
+ CCTK_RegisterGHExtensionSetupGH (CCTK_RegisterGHExtension ("IOSDF"),
+ IOSDF_SetupGH);
+}
+
+
+ /*@@
+ @routine IOSDF_Terminate
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ The termination routine for IOSDF.
+ Closes all open SDF output files.
+ @enddesc
+@@*/
+void IOSDF_Terminate (void)
+{
+ gft_close_all ();
+}
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+ /*@@
+ @routine IOSDF_SetupGH
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Allocates and sets up IOSDF's GH extension structure
+ @enddesc
+
+ @calls CCTK_RegisterIOMethod
+ CCTK_RegisterIOMethodOutputGH
+ CCTK_RegisterIOMethodOutputVarAs
+ CCTK_RegisterIOMethodTimeToOutput
+ CCTK_RegisterIOMethodTriggerOutput
+
+ @var config
+ @vdesc the CCTK configuration as provided by the flesh
+ @vtype tFleshConfig *
+ @vio unused
+ @endvar
+ @var conv_level
+ @vdesc the convergence level
+ @vtype int
+ @vio unused
+ @endvar
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype cGH *
+ @vio in
+ @endvar
+
+ @returntype void *
+ @returndesc
+ pointer to the allocated GH extension structure
+ @endreturndesc
+@@*/
+static void *IOSDF_SetupGH (tFleshConfig *config, int conv_level, cGH *GH)
+{
+ int i, maxdim, numvars;
+ ioSDFGH *myGH;
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* suppress compiler warnings about unused variables */
+ (void) (config + 0);
+ (void) (conv_level + 0);
+ (void) (GH + 0);
+
+ /* allocate the GH extension and its components */
+ myGH = malloc (sizeof (ioSDFGH));
+ if (! myGH)
+ {
+ CCTK_WARN (0, "IOSDF_SetupGH: Unable to allocate memory for GH");
+ }
+
+ /* register the IOSDF routines as output methods */
+ i = CCTK_RegisterIOMethod ("IOSDF_1D");
+ CCTK_RegisterIOMethodOutputGH (i, IOSDF_Output1DGH);
+ CCTK_RegisterIOMethodOutputVarAs (i, IOSDF_Output1DVarAs);
+ CCTK_RegisterIOMethodTimeToOutput (i, IOSDF_TimeFor1D);
+ CCTK_RegisterIOMethodTriggerOutput (i, IOSDF_TriggerOutput1D);
+
+ /* only register N-D IOSDF I/O methods
+ if at least N-dimensional grid variables are defined by thorns */
+ maxdim = CCTK_MaxDim ();
+ if (maxdim >= 2)
+ {
+ i = CCTK_RegisterIOMethod ("IOSDF_2D");
+ CCTK_RegisterIOMethodOutputGH (i, IOSDF_Output2DGH);
+ CCTK_RegisterIOMethodOutputVarAs (i, IOSDF_Output2DVarAs);
+ CCTK_RegisterIOMethodTimeToOutput (i, IOSDF_TimeFor2D);
+ CCTK_RegisterIOMethodTriggerOutput (i, IOSDF_TriggerOutput2D);
+ }
+
+ if (maxdim >= 3)
+ {
+ i = CCTK_RegisterIOMethod ("IOSDF_3D");
+ CCTK_RegisterIOMethodOutputGH (i, IOSDF_Output3DGH);
+ CCTK_RegisterIOMethodOutputVarAs (i, IOSDF_Output3DVarAs);
+ CCTK_RegisterIOMethodTimeToOutput (i, IOSDF_TimeFor3D);
+ CCTK_RegisterIOMethodTriggerOutput (i, IOSDF_TriggerOutput3D);
+ }
+
+ numvars = CCTK_NumVars ();
+ myGH->out1D_every = malloc (numvars * sizeof (CCTK_INT));
+ myGH->out2D_every = malloc (numvars * sizeof (CCTK_INT));
+ myGH->out3D_every = malloc (numvars * sizeof (CCTK_INT));
+ myGH->out1D_last = malloc (numvars * sizeof (int));
+ myGH->out2D_last = malloc (numvars * sizeof (int));
+ myGH->out3D_last = malloc (numvars * sizeof (int));
+
+ for (i = 0; i < numvars; i++)
+ {
+ myGH->out1D_last[i] = -1;
+ myGH->out2D_last[i] = -1;
+ myGH->out3D_last[i] = -1;
+ }
+
+ myGH->out1D_vars = strdup ("");
+ myGH->out2D_vars = strdup ("");
+ myGH->out3D_vars = strdup ("");
+ myGH->out1D_every_default = out1D_every - 1;
+ myGH->out2D_every_default = out2D_every - 1;
+ myGH->out3D_every_default = out3D_every - 1;
+
+ myGH->fileList_1D = NULL;
+ myGH->fileList_2D = NULL;
+ myGH->fileList_3D = NULL;
+
+ myGH->stop_on_parse_errors = strict_io_parameter_check;
+ if (! CCTK_Equals (verbose, "none"))
+ {
+ CCTK_INFO ("I/O Method 'IOSDF_1D' registered: output of 1D lines of grid "
+ "functions/arrays to SDF files");
+ }
+ IOSDF_CheckSteerableParameters1D (myGH);
+ if (maxdim >= 2)
+ {
+ if (! CCTK_Equals (verbose, "none"))
+ {
+ CCTK_INFO ("I/O Method 'IOSDF_2D' registered: output of 2D planes of "
+ "grid functions/arrays to SDF files");
+ }
+ IOSDF_CheckSteerableParameters2D (myGH);
+ }
+ if (maxdim >= 3)
+ {
+ if (! CCTK_Equals (verbose, "none"))
+ {
+ CCTK_INFO ("I/O Method 'IOSDF_3D' registered: output of 3D grid "
+ "functions/arrays to SDF files");
+ }
+ IOSDF_CheckSteerableParameters3D (myGH);
+ }
+ myGH->stop_on_parse_errors = 0;
+
+ /* make sure all output directories exist */
+ CREATE_OUTDIR (1, out1D_dir);
+ CREATE_OUTDIR (2, out2D_dir);
+ CREATE_OUTDIR (3, out3D_dir);
+
+ return (myGH);
+}
diff --git a/src/Write1D.c b/src/Write1D.c
new file mode 100644
index 0000000..debf166
--- /dev/null
+++ b/src/Write1D.c
@@ -0,0 +1,436 @@
+/*@@
+ @file Write1D.c
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Output one-dimensional lines in SDF file format.
+ @enddesc
+ @version $Id$
+@@*/
+
+#include <math.h> /* sqrt(3) */
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "util_Table.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "CactusBase/IOUtil/src/ioutil_AdvertisedFiles.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Header$";
+CCTK_FILEVERSION(CactusIO_IOSDF_Write1D_c)
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static char *OpenFile (const cGH *GH,
+ const char *fullname,
+ const char *alias,
+ const cGroup *gdata,
+ int dir);
+
+
+/*@@
+ @routine IOSDF_Write1D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ This routine does 1D line output along the orthogonals
+ and the diagonal (in case of a cubed grid).
+ <p>
+ It writes to SDF files suitable for gnuplot and xgraph.
+ A header telling the physical time prefixes the output data.
+ @enddesc
+ @calls Hyperslab_GlobalMappingByIndex
+ Hyperslab_FreeMapping
+ Hyperslab_GetList
+ OpenFile
+ WriteData
+
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc global index of variable to output
+ @vtype int
+ @vio in
+ @endvar
+ @var alias
+ @vdesc alias name (used for creating the output filename)
+ @vtype const char *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ 0 for success, or<BR>
+ -1 if variable has no storage assigned
+ @endreturndesc
+@@*/
+int IOSDF_Write1D (const cGH *GH, int vindex, const char *alias)
+{
+ ioSDFGH *myGH;
+ int do_dir[4], coord_index[3];
+ int i, dir, myproc, gindex, have_coords, mapping;
+ int num_requested_hslabs, num_returned_hslabs;
+ int *extent_int;
+ cGroup gdata;
+ char *fullname, *groupname, *filename;
+ CCTK_INT coord_system_handle, coord_handles[3];
+ double offset;
+ CCTK_REAL coord_lower[3];
+ CCTK_INT downsample[4];
+ CCTK_INT *origin, *direction;
+ CCTK_INT hsize, extent;
+ CCTK_INT vindices[2];
+ double *hdata[2];
+ const double dtime = GH->cctk_time;
+ const char *coordnames[] = {"x", "y", "z", "d"};
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* get the variable's group index and its full name */
+ gindex = CCTK_GroupIndexFromVarI (vindex);
+ fullname = CCTK_FullName (vindex);
+
+ /* check if variable has storage assigned */
+ if (! CCTK_QueryGroupStorageI (GH, gindex))
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write1D: No IOSDF_1D output for '%s' (no storage)",
+ fullname);
+ free (fullname);
+ return (-1);
+ }
+
+ /* get the handle for IOSDF extensions */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ /* get the variable's group information */
+ CCTK_GroupData (gindex, &gdata);
+
+ /* see what slices should be output */
+ do_dir[0] = out1D_x && gdata.dim >= 1;
+ do_dir[1] = out1D_y && gdata.dim >= 2;
+ do_dir[2] = out1D_z && gdata.dim >= 3;
+ /* diagonal slice is done only if variable is non-staggered and 3D */
+ do_dir[3] = out1D_d && gdata.dim == 3 && gdata.stagtype == 0;
+ if (out1D_d && ! do_dir[3] && myGH->out1D_last[vindex] < 0)
+ {
+ CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write1D: No IOSDF_1D diagonal output for '%s' "
+ "(only implemented for non-staggered 3D variables)",
+ fullname);
+ }
+
+ /* return if nothing to do */
+ if (! (do_dir[0] || do_dir[1] || do_dir[2] || do_dir[3]))
+ {
+ free (fullname);
+ return (0);
+ }
+
+ /* get the coordinate system associated with this grid variable */
+ groupname = CCTK_GroupName (gindex);
+ coord_system_handle = Coord_GroupSystem (GH, groupname);
+ free (groupname);
+
+ dir = gdata.dim < 3 ? gdata.dim : 3;
+
+ have_coords = coord_system_handle >= 0 &&
+ Util_TableGetIntArray (coord_system_handle, dir,
+ coord_handles, "COORDINATES") >= 0;
+ if (have_coords)
+ {
+ /* get the coordinate functions and coordinate physical minimum */
+ for (i = 0; i < dir; i++)
+ {
+ coord_index[i] = -1;
+ coord_lower[i] = 0;
+ Util_TableGetInt (coord_handles[i], &coord_index[i], "GAINDEX");
+ Util_TableGetReal (coord_handles[i], &coord_lower[i], "COMPMIN");
+ have_coords &= coord_index[i] >= 0;
+ }
+ }
+
+ myproc = CCTK_MyProc (GH);
+
+ origin = calloc (2*gdata.dim, sizeof (CCTK_INT));
+ direction = origin + gdata.dim;
+ extent_int = malloc ((gdata.dim + 1) * sizeof (int));
+
+ /* set downsampling vector from I/O parameters */
+ downsample[0] = out_downsample_x;
+ downsample[1] = out_downsample_y;
+ downsample[2] = out_downsample_z;
+ downsample[3] = 1;
+
+ /* get the variable's extents, compute the extent for 3D-diagonals as the
+ minimum of grid points in each direction */
+ CCTK_GroupgshVI (GH, gdata.dim, extent_int, vindex);
+ if (gdata.dim == 3)
+ {
+ extent_int[3] = extent_int[0] < extent_int[1] ?
+ extent_int[0] : extent_int[1];
+ if (extent_int[2] < extent_int[3])
+ {
+ extent_int[3] = extent_int[2];
+ }
+ }
+ /* get the total number of grid points to check for zero-sized variables */
+ for (dir = 0, hsize = 1; dir < gdata.dim; dir++)
+ {
+ hsize *= extent_int[dir];
+ }
+
+ /* now do the actual I/O looping over all directions */
+ for (dir = 0; dir < 4; dir++)
+ {
+ if (hsize <= 0)
+ {
+ continue;
+ }
+
+ /* skip empty slices */
+ if (! do_dir[dir])
+ {
+ continue;
+ }
+
+ /* processor 0 opens the files with the appropriate name */
+ filename = NULL;
+ if (myproc == 0)
+ {
+ filename = OpenFile (GH, fullname, alias, &gdata, dir);
+ }
+
+ /* get the number of hyperslabs to extract
+ (ie. whether to get a coordinate hyperslab too or not) */
+ num_requested_hslabs = have_coords && dir < 3 ? 2 : 1;
+
+ /* set the direction vector */
+ for (i = 0; i < gdata.dim; i++)
+ {
+ direction[i] = (dir == i || dir == 3) ? 1 : 0;
+ }
+
+ /* set the extent */
+ extent = extent_int[dir];
+
+ /* set the origin of the line */
+ if (gdata.grouptype == CCTK_GF && dir < 3)
+ {
+ for (i = 0; i < gdata.dim; i++)
+ {
+ origin[i] = myGH->spxyz[gdata.dim-1][dir][i];
+ }
+ extent -= origin[dir];
+
+ /* correct extent in the case of staggered grids */
+ if (CCTK_StaggerDirIndex(dir,gdata.stagtype)==1)
+ {
+ --extent;
+ }
+ }
+ else /* origin for CCTK_ARRAYS is always (0, 0, 0) */
+ {
+ memset (origin, 0, gdata.dim * sizeof (CCTK_INT));
+ }
+
+ mapping = Hyperslab_GlobalMappingByIndex (GH, vindex, 1,
+ direction, origin, &extent,
+ &downsample[dir],
+ -1, /* table handle */
+ NULL /* conversion fn */,
+ &hsize);
+ if (mapping < 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write1D: Failed to define hyperslab mapping for "
+ "variable '%s'", fullname);
+ continue;
+ }
+ if (hsize <= 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write1D: selected hyperslab has zero size for "
+ "variable '%s' direction %d", fullname, dir);
+ Hyperslab_FreeMapping (mapping);
+ continue;
+ }
+
+ /* allocate hyperslab buffers on I/O processor */
+ hdata[0] = hdata[1] = NULL;
+ if (myproc == 0)
+ {
+ hdata[0] = malloc (hsize * sizeof (double));
+ hdata[1] = have_coords ? malloc (hsize * sizeof (double)) : NULL;
+ }
+
+ /* get the hyperslabs */
+ vindices[0] = vindex;
+ vindices[1] = coord_index[dir];
+ num_returned_hslabs = Hyperslab_GetList (GH, mapping, num_requested_hslabs,
+ NULL, vindices, NULL, NULL,
+ (void **) hdata, NULL);
+
+ /* release the mapping structure */
+ Hyperslab_FreeMapping (mapping);
+
+ /* And dump the data to file */
+ if (num_returned_hslabs != num_requested_hslabs)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write1D: Failed to extract hyperslab for "
+ "variable '%s'", fullname);
+ }
+ else if (filename)
+ {
+ if (have_coords)
+ {
+ if (dir < 3)
+ {
+ /* get the staggering offset for the xyz coordinates */
+ offset = 0.5 * GH->cctk_delta_space[dir] *
+ CCTK_StaggerDirIndex (dir, gdata.stagtype);
+ for (i = 0; i < hsize; i++)
+ {
+ hdata[1][i] += offset;
+ }
+ }
+ else
+ {
+ /* calculate the diagonal coordinates */
+ offset = GH->cctk_delta_space[0] * sqrt (3);
+ for (i = 0; i < hsize; i++)
+ {
+ hdata[1][i] = coord_lower[0]*sqrt (3) + i*offset;
+ }
+ }
+ }
+
+ extent_int[0] = hsize;
+ i = have_coords ? gft_out_full (filename, dtime, extent_int,
+ coordnames[dir], 1, hdata[1], hdata[0]):
+ gft_out_brief (filename, dtime, extent_int,
+ 1, hdata[0]);
+ if (i <= 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Error writing to 1D IOSDF output file '%s'", filename);
+ }
+ }
+
+ /* clean up */
+ free (hdata[0]);
+ free (hdata[1]);
+ } /* end of loop through all directions */
+
+ /* free allocated resources */
+ free (origin);
+ free (fullname);
+ free (extent_int);
+
+ return (0);
+}
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+/*@@
+ @routine OpenFile
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Opens a set of SDF files for a given alias name.
+ If this is the first time through, it will advertise them
+ to IOUtil.
+ @enddesc
+ @@*/
+static char *OpenFile (const cGH *GH,
+ const char *fullname,
+ const char *alias,
+ const cGroup *gdata,
+ int dir)
+{
+ ioSDFGH *myGH;
+ int upper, lower;
+ char *filename, *nameddata;
+ char slicename[40];
+ ioAdvertisedFileDesc advertised_file;
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* get handle for and IOSDF GH extensions */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ nameddata = malloc (strlen (alias) + 3);
+ sprintf (nameddata, "%s_%d", alias, dir);
+ filename = GetNamedData (myGH->fileList_1D, nameddata);
+ if (filename)
+ {
+ free (nameddata);
+ return (filename);
+ }
+
+ /* get the indices into spxyz[] */
+ lower = (dir + 1) % 3;
+ upper = (dir + 2) % 3;
+ if (upper < lower)
+ {
+ upper = lower;
+ lower = 0;
+ }
+
+ if (dir < 3)
+ {
+ if (gdata->dim == 1)
+ {
+ strcpy (slicename, "1D");
+ }
+ else if (gdata->dim == 2)
+ {
+ /* give the slice origin as range [1 .. n] */
+ sprintf (slicename, "%c_%d", 'x' + dir,
+ gdata->grouptype == CCTK_GF ?
+ myGH->spxyz[gdata->dim-1][dir][lower] : 0);
+ }
+ else
+ {
+ /* give the slice origin as range [1 .. n] */
+ sprintf (slicename, "%c_%d_%d", 'x' + dir,
+ gdata->grouptype == CCTK_GF ?
+ myGH->spxyz[gdata->dim-1][dir][lower] : 0,
+ gdata->grouptype == CCTK_GF ?
+ myGH->spxyz[gdata->dim-1][dir][upper] : 0);
+ }
+ }
+ else
+ {
+ sprintf (slicename, "%dD_diagonal", gdata->dim);
+ }
+
+ filename = malloc (strlen (myGH->out1D_dir) + strlen (alias) +
+ sizeof (slicename) + 6);
+ sprintf (filename, "%s%s_%s.sdf", myGH->out1D_dir, alias, slicename);
+ StoreNamedData (&myGH->fileList_1D, nameddata, filename);
+ free (nameddata);
+
+ /* advertise the output file */
+ advertised_file.slice = slicename;
+ advertised_file.thorn = CCTK_THORNSTRING;
+ advertised_file.varname = fullname;
+ advertised_file.description = "One-dimensional line plots";
+ advertised_file.mimetype = "application/sdf";
+
+ IOUtil_AdvertiseFile (GH, filename, &advertised_file);
+
+ return (filename);
+}
diff --git a/src/Write2D.c b/src/Write2D.c
new file mode 100644
index 0000000..551e0c8
--- /dev/null
+++ b/src/Write2D.c
@@ -0,0 +1,371 @@
+/*@@
+ @file Write2D.c
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Output two-dimensional slices in SDF file format.
+ @enddesc
+ @version $Id$
+ @@*/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "util_Table.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "CactusBase/IOUtil/src/ioutil_AdvertisedFiles.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Id$";
+CCTK_FILEVERSION(CactusIO_IOSDF_Write2D_c)
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static char **OpenFile (const cGH *GH,
+ const char *fullname,
+ const char *alias,
+ int dim,
+ int maxdir);
+
+
+/*@@
+ @routine IOSDF_Write2D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Writes the 2D slices of a variable into separate SDF files.
+ @enddesc
+ @calls Hyperslab_GlobalMappingByIndex
+ Hyperslab_FreeMapping
+ Hyperslab_GetList
+ OpenFile
+ WriteData
+
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable to output
+ @vtype int
+ @vio in
+ @endvar
+ @var alias
+ @vdesc alias name of variable to output
+ @vtype const char *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ 0 for success, or<BR>
+ -1 if variable has no storage assigned<BR>
+ -2 if output file couldn't be opened<BR>
+ -3 if hyperslab for coordinates and/or variable couldn't be
+ extracted
+ @endreturndesc
+@@*/
+int IOSDF_Write2D (const cGH *GH, int vindex, const char *alias)
+{
+ ioSDFGH *myGH;
+ int i, total_hsize, num_requested_hslabs, num_returned_hslabs;
+ int dir, dir_i, dir_j, maxdir, myproc, gindex, have_coords;
+ int mapping;
+ cGroup gdata;
+ int coord_index[3];
+ CCTK_INT coord_system_handle, coord_handles[3];
+ char *fullname, *groupname;
+ int extent_int[3];
+ double offset[2];
+ CCTK_INT vindices[3], origin[3], extent[2], direction[6], downsample[2],
+ hsize[2];
+ double *hdata[3];
+ char **filenames;
+ const double dtime = GH->cctk_time;
+ const char *coordnames[] = {"x|y", "x|z", "y|z"};
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* get the variable name and group information */
+ fullname = CCTK_FullName (vindex);
+ gindex = CCTK_GroupIndexFromVarI (vindex);
+ CCTK_GroupData (gindex, &gdata);
+
+ /* check if variable has storage assigned */
+ if (! CCTK_QueryGroupStorageI (GH, gindex))
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "No IOSDF 2D output for '%s' (no storage)", fullname);
+ free (fullname);
+ return (-1);
+ }
+
+ /* get the handle for IOSDF extensions */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ /* get the number of slices to output */
+ /* in general: maxdir = gdata.dim * (gdata.dim - 1) / 2; */
+ maxdir = gdata.dim == 2 ? 1 : 3;
+
+ /* get the coordinate system associated with this grid variable */
+ groupname = CCTK_GroupName (gindex);
+ coord_system_handle = Coord_GroupSystem (GH, groupname);
+ free (groupname);
+
+ dir = gdata.dim < 3 ? gdata.dim : 3;
+
+ have_coords = coord_system_handle >= 0 &&
+ Util_TableGetIntArray (coord_system_handle, dir,
+ coord_handles, "COORDINATES") >= 0;
+ if (have_coords)
+ {
+ /* get the coordinate functions and coordinate physical minimum */
+ for (i = 0; i < dir; i++)
+ {
+ coord_index[i] = -1;
+ Util_TableGetInt (coord_handles[i], &coord_index[i], "GAINDEX");
+ have_coords &= coord_index[i] >= 0;
+ }
+ }
+ num_requested_hslabs = have_coords ? 3 : 1;
+
+ /* processor 0 opens the files on the first trip through */
+ filenames = NULL;
+ myproc = CCTK_MyProc (GH);
+ if (myproc == 0)
+ {
+ filenames = OpenFile (GH, fullname, alias, gdata.dim, maxdir);
+ }
+
+ /* get the extents of the variable */
+ CCTK_GroupgshVI (GH, gdata.dim, extent_int, vindex);
+
+ /* get the total number of grid points to check for zero-sized variables */
+ for (dir = 0, hsize[0] = 1; dir < gdata.dim; dir++)
+ {
+ hsize[0] *= extent_int[dir];
+ }
+
+ /* now do the actual I/O looping over all directions */
+ for (dir = 0; dir < maxdir; dir++)
+ {
+ if (hsize[0] <= 0)
+ {
+ continue;
+ }
+
+ /* get the directions to span the hyperslab */
+ if (dir == 0)
+ {
+ dir_i = 0; dir_j = 1; /* xy */
+ downsample[0] = out_downsample_x; downsample[1] = out_downsample_y;
+ }
+ else if (dir == 1)
+ {
+ dir_i = 0; dir_j = 2; /* xz */
+ downsample[0] = out_downsample_x; downsample[1] = out_downsample_z;
+ }
+ else
+ {
+ dir_i = 1; dir_j = 2; /* yz */
+ downsample[0] = out_downsample_y; downsample[1] = out_downsample_z;
+ }
+
+ /* set the extent vector */
+ extent[0] = extent_int[dir_i];
+ extent[1] = extent_int[dir_j];
+
+ /* set the origin using the slice center from IOUtil */
+ memset (origin, 0, sizeof (origin));
+ if (have_coords)
+ {
+ origin[maxdir-dir-1] = myGH->sp2xyz[gdata.dim-1][dir];
+ }
+
+ /* set the direction vector */
+ memset (direction, 0, sizeof (direction));
+ direction[dir_i] = direction[gdata.dim + dir_j] = 1;
+
+ mapping = Hyperslab_GlobalMappingByIndex (GH, vindex, 2,
+ direction, origin, extent,
+ downsample,
+ -1, /* table handle */
+ NULL /* conversion fn */,
+ hsize);
+ if (mapping < 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write2D: Failed to define hyperslab mapping for "
+ "variable '%s'", fullname);
+ continue;
+ }
+ total_hsize = hsize[0] * hsize[1];
+ if (total_hsize <= 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write2D: selected hyperslab has zero size for "
+ "variable '%s' direction %d", fullname, dir);
+ Hyperslab_FreeMapping (mapping);
+ continue;
+ }
+
+ hdata[0] = hdata[1] = hdata[2];
+ if (myproc == 0)
+ {
+ /* allocate hyperslab buffers */
+ hdata[0] = malloc (total_hsize * sizeof (double));
+ hdata[1] = have_coords ? malloc (2 * total_hsize * sizeof(double)) : NULL;
+ hdata[2] = hdata[1] + total_hsize;
+ }
+
+ /* get the hyperslabs */
+ vindices[0] = vindex;
+ vindices[1] = coord_index[dir_i];
+ vindices[2] = coord_index[dir_j];
+ num_returned_hslabs = Hyperslab_GetList (GH, mapping, num_requested_hslabs,
+ NULL, vindices, NULL, NULL,
+ (void **) hdata, NULL);
+
+ /* release the mapping structure */
+ Hyperslab_FreeMapping (mapping);
+
+ /* and dump the data to file */
+ if (filenames)
+ {
+ if (num_returned_hslabs == num_requested_hslabs)
+ {
+ if (have_coords)
+ {
+ /* get the staggering offset for the coordinates */
+ offset[0] = 0.5 * GH->cctk_delta_space[dir_i] *
+ CCTK_StaggerDirIndex (dir_i, gdata.stagtype);
+ offset[1] = 0.5 * GH->cctk_delta_space[dir_j] *
+ CCTK_StaggerDirIndex (dir_j, gdata.stagtype);
+ for (i = 0; i < total_hsize; i++)
+ {
+ hdata[1][i] += offset[0];
+ hdata[2][i] += offset[1];
+ }
+ }
+
+ extent[0] = hsize[0];
+ extent[1] = hsize[1];
+
+ i = have_coords ? gft_out_full (filenames[dir], dtime, extent_int,
+ coordnames[dir], 2, hdata[1], hdata[0]):
+ gft_out_brief (filenames[dir], dtime, extent_int,
+ 2, hdata[0]);
+ if (i <= 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Error writing to 2D IOSDF output file '%s'",
+ filenames[dir]);
+ }
+ }
+ else
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write2D: Failed to extract hyperslab for "
+ "variable '%s'", fullname);
+ }
+
+ /* clean up */
+ free (hdata[0]);
+ free (hdata[1]);
+
+ } /* end of outputting the data by processor 0 */
+
+ } /* end of looping through xyz directions */
+
+ free (fullname);
+
+ return (0);
+}
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+/*@@
+ @routine OpenFile
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Opens a set of SDF files for a given alias name.
+ If this is the first time through, it will advertise them
+ to IOUtil.
+ @enddesc
+
+ @returntype char **
+ @returndesc
+ the set of full filenames
+ @endreturndesc
+ @@*/
+static char **OpenFile (const cGH *GH,
+ const char *fullname,
+ const char *alias,
+ int dim,
+ int maxdir)
+{
+ int dir;
+ char **filenames;
+ ioSDFGH *myGH;
+ ioAdvertisedFileDesc advertised_file;
+ char slicename[30];
+ const char *extensions[] = {"xy", "xz", "yz"};
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* get handle for IOSDF GH extensions */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ /* see if we are the first time through */
+ filenames = GetNamedData (myGH->fileList_2D, alias);
+ if (filenames)
+ {
+ return (filenames);
+ }
+
+ filenames = malloc (maxdir * sizeof (char **));
+
+ /* open/create files for each slice */
+ for (dir = 0; dir < maxdir; dir++)
+ {
+ filenames[dir] = malloc (strlen (myGH->out2D_dir) + strlen (alias) +
+ sizeof (slicename) + 20);
+
+ if (dim == 2)
+ {
+ strcpy (slicename, "2D");
+ }
+ else
+ {
+ /* give the slice origin as range [1 .. n] */
+ sprintf (slicename, "%s_%d", extensions[dir],
+ myGH->sp2xyz[dim-1][dir]);
+ }
+
+ sprintf (filenames[dir], "%s%s_%s.sdf", myGH->out2D_dir, alias, slicename);
+
+ /* advertise the file for downloading and write file info */
+ advertised_file.slice = slicename;
+ advertised_file.thorn = CCTK_THORNSTRING;
+ advertised_file.varname = fullname;
+ advertised_file.description = "Two-dimensional slice plots";
+ advertised_file.mimetype = "application/sdf";
+
+ IOUtil_AdvertiseFile (GH, filenames[dir], &advertised_file);
+ }
+
+ /* store file desriptors in database */
+ StoreNamedData (&myGH->fileList_2D, alias, filenames);
+
+ return (filenames);
+}
diff --git a/src/Write3D.c b/src/Write3D.c
new file mode 100644
index 0000000..f07ef55
--- /dev/null
+++ b/src/Write3D.c
@@ -0,0 +1,292 @@
+/*@@
+ @file Write3D.c
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Three-dimensional output of variables in SDF file format.
+ @enddesc
+ @version $Id$
+ @@*/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "util_Table.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "CactusBase/IOUtil/src/ioutil_AdvertisedFiles.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Header$";
+CCTK_FILEVERSION(CactusIO_IOSDF_Write3D_c)
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static char *OpenFile (const cGH *GH, const char *fullname, const char *alias);
+
+/*@@
+ @routine IOSDF_Write3D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Writes the 3D volume of a variable into a gnuplot SDF file.
+ @enddesc
+ @calls Hyperslab_GlobalMappingByIndex
+ Hyperslab_FreeMapping
+ Hyperslab_GetList
+ OpenFile
+
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable to output
+ @vtype int
+ @vio in
+ @endvar
+ @var alias
+ @vdesc alias name of variable to output
+ @vtype const char *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ 0 for success, or<BR>
+ -1 if variable has no storage assigned<BR>
+ -2 if output file couldn't be opened<BR>
+ -3 if hyperslab for coordinates and/or variable couldn't be
+ extracted
+ @endreturndesc
+@@*/
+int IOSDF_Write3D (const cGH *GH, int vindex, const char *alias)
+{
+ int i, total_hsize;
+ int myproc, gindex, have_coords;
+ int num_requested_hslabs, num_returned_hslabs;
+ cGroup gdata;
+ CCTK_INT coord_system_handle, coord_handles[3];
+ char *fullname, *groupname, *filename;
+ double *hdata[4];
+ int extent_int[3];
+ double offset[3];
+ int mapping;
+ CCTK_INT vindices[4], extent[3], downsample[3], hsize[3];
+ const double dtime = GH->cctk_time;
+ const CCTK_INT origin[] = {0, 0, 0},
+ direction[] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* get the variable group information */
+ fullname = CCTK_FullName (vindex);
+ gindex = CCTK_GroupIndexFromVarI (vindex);
+ CCTK_GroupData (gindex, &gdata);
+
+ /* check if variable has storage assigned */
+ if (! CCTK_QueryGroupStorageI (GH, gindex))
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "No IOSDF 3D output for '%s' (no storage)", fullname);
+ free (fullname);
+ return (-1);
+ }
+
+ /* get the coordinate system associated with this grid variable */
+ vindices[0] = vindex;
+ groupname = CCTK_GroupName (gindex);
+ coord_system_handle = Coord_GroupSystem (GH, groupname);
+ free (groupname);
+
+ have_coords = coord_system_handle >= 0 &&
+ Util_TableGetIntArray (coord_system_handle, 3,
+ coord_handles, "COORDINATES") >= 0;
+ if (have_coords)
+ {
+ /* get the coordinate functions and coordinate physical minimum */
+ for (i = 1; i <= 3; i++)
+ {
+ vindices[i] = -1;
+ Util_TableGetInt (coord_handles[i-1], &vindices[i], "GAINDEX");
+ have_coords &= vindices[i] >= 0;
+ }
+ }
+ num_requested_hslabs = have_coords ? 4 : 1;
+
+ /* What processor are we on? */
+ myproc = CCTK_MyProc (GH);
+
+ /* Open the file on processor 0 */
+ filename = myproc == 0 ? OpenFile (GH, fullname, alias) : NULL;
+
+ /* get the total number of grid points to check for zero-sized variables */
+ /* set the extent vector (copy from 'int' to 'CCTK_INT') */
+ CCTK_GroupgshVI (GH, 3, extent_int, vindex);
+ for (i = 0, total_hsize = 1; i < 3; i++)
+ {
+ total_hsize *= extent_int[i];
+ extent[i] = extent_int[i];
+ }
+ if (total_hsize <= 0)
+ {
+ free (fullname);
+ return (0);
+ }
+
+ downsample[0] = out_downsample_x;
+ downsample[1] = out_downsample_y;
+ downsample[2] = out_downsample_z;
+
+ /* get the hyperslab mapping */
+ mapping = Hyperslab_GlobalMappingByIndex (GH, vindex, 3,
+ direction, origin, extent,
+ downsample,
+ -1, /* table handle */
+ NULL /* conversion fn */,
+ hsize);
+ if (mapping < 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write3D: Failed to define hyperslab mapping for "
+ "variable '%s'", fullname);
+ free (fullname);
+ return (-1);
+ }
+ for (i = 0, total_hsize = 1; i < 3; i++)
+ {
+ extent_int[i] = hsize[i];
+ total_hsize *= hsize[i];
+ }
+ if (total_hsize <= 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write3D: selected hyperslab has zero size for "
+ "variable '%s'", fullname);
+ Hyperslab_FreeMapping (mapping);
+ free (fullname);
+ return (-1);
+ }
+
+ hdata[0] = hdata[1] = hdata[2] = hdata[3];
+ if (myproc == 0)
+ {
+ /* allocate hyperslab buffers */
+ hdata[0] = malloc (total_hsize * sizeof (double));
+ hdata[1] = have_coords ? malloc (3 * total_hsize * sizeof (double)) : NULL;
+ hdata[2] = hdata[1] + 1*total_hsize;
+ hdata[3] = hdata[1] + 2*total_hsize;
+ }
+
+ /* get the hyperslabs */
+ num_returned_hslabs = Hyperslab_GetList (GH, mapping, num_requested_hslabs,
+ NULL, vindices, NULL, NULL,
+ (void **) hdata, NULL);
+
+ /* And dump the data to file */
+ if (myproc == 0)
+ {
+ if (num_returned_hslabs == num_requested_hslabs)
+ {
+ if (have_coords)
+ {
+ /* get the staggering offset for the coordinates */
+ for (i = 0; i < 3; i++)
+ {
+ offset[i] = 0.5 * GH->cctk_delta_space[i] *
+ CCTK_StaggerDirIndex (i, gdata.stagtype);
+ }
+ for (i = 0; i < total_hsize; i++)
+ {
+ hdata[1][i] += offset[0];
+ hdata[2][i] += offset[1];
+ hdata[3][i] += offset[2];
+ }
+ }
+
+ i = have_coords ? gft_out_full (filename, dtime, extent_int, "x|y|z", 3,
+ hdata[1], hdata[0]) :
+ gft_out_brief (filename, dtime, extent_int, 3,hdata[0]);
+ if (i <= 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Error writing to 3D IOSDF output file '%s'", filename);
+ }
+ }
+ else
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write3D: Failed to extract hyperslab for "
+ "variable '%s'", fullname);
+ }
+
+ /* clean up */
+ free (hdata[0]);
+ free (hdata[1]);
+ } /* end of outputting the data by processor 0 */
+
+ free (fullname);
+
+ return (0);
+}
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+/*@@
+ @routine OpenFile
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Opens an SDF file for a given alias name.
+ If this is the first time through, it will advertise it
+ to IOUtil.
+ @enddesc
+
+ @returntype char *
+ @returndesc
+ the full filename of the SDF output file
+ @endreturndesc
+ @@*/
+static char *OpenFile (const cGH *GH, const char *fullname, const char *alias)
+{
+ char *filename;
+ ioSDFGH *myGH;
+ ioAdvertisedFileDesc advertised_file;
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* get handle for IOSDF GH extensions */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ /* see if we are the first time through */
+ filename = GetNamedData (myGH->fileList_3D, alias);
+ if (! filename)
+ {
+ filename = malloc (strlen (myGH->out3D_dir) + strlen (alias) + 9);
+
+ /* open/create the file */
+ sprintf (filename, "%s%s_3D.sdf", myGH->out3D_dir, alias);
+
+ /* advertise the file for downloading and write file info */
+ advertised_file.slice = "";
+ advertised_file.thorn = CCTK_THORNSTRING;
+ advertised_file.varname = fullname;
+ advertised_file.description = "Full-dimensional variable contents";
+ advertised_file.mimetype = "application/sdf";
+
+ IOUtil_AdvertiseFile (GH, filename, &advertised_file);
+
+ /* store filename in database */
+ StoreNamedData (&myGH->fileList_3D, alias, filename);
+ }
+
+ return (filename);
+}
diff --git a/src/ioSDFGH.h b/src/ioSDFGH.h
new file mode 100644
index 0000000..e31867b
--- /dev/null
+++ b/src/ioSDFGH.h
@@ -0,0 +1,87 @@
+ /*@@
+ @header ioSDFGH.h
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ The extensions to the GH structure from IOSDF.
+ @version $Header$
+ @@*/
+
+#ifndef _IOSDF_IOSDFGH_H_
+#define _IOSDF_IOSDFGH_H_ 1
+
+#include "StoreNamedData.h"
+#include "bbhutil.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct IOSDFGH
+{
+ /* default number of times to output */
+ int out1D_every_default, out2D_every_default, out3D_every_default;
+
+ /* number of times to output every variable */
+ CCTK_INT *out1D_every, *out2D_every, *out3D_every;
+
+ /* lists of variables to output */
+ char *out1D_vars, *out2D_vars, *out3D_vars;
+
+ /* directories in which to output */
+ char *out1D_dir, *out2D_dir, *out3D_dir;
+
+ /* the last iteration output for var [i] */
+ int *out1D_last, *out2D_last, *out3D_last;
+
+ /* database for names of output files that were already created */
+ pNamedData *fileList_1D, *fileList_2D, *fileList_3D;
+
+ /* for 1D lines, we define the index where to start the line:
+ spxyz[maxdim][XYZdirection][xyzstart_index] */
+ int ***spxyz;
+
+ /* for 2D planes, we define the index where to locate the plane
+ sp2xyz[maxdim][perpendicular direction] */
+ int **sp2xyz;
+
+ /* stop on I/O parameter parsing errors ? */
+ int stop_on_parse_errors;
+
+} ioSDFGH;
+
+
+/* prototypes of functions to be registered as I/O methods */
+int IOSDF_Output1DGH (const cGH *GH);
+int IOSDF_TriggerOutput1D (const cGH *GH, int);
+int IOSDF_TimeFor1D (const cGH *GH, int);
+int IOSDF_Output1DVarAs (const cGH *GH, const char *var, const char *alias);
+int IOSDF_Output2DGH (const cGH *GH);
+int IOSDF_TriggerOutput2D (const cGH *GH, int);
+int IOSDF_TimeFor2D (const cGH *GH, int);
+int IOSDF_Output2DVarAs (const cGH *GH, const char *var, const char *alias);
+int IOSDF_Output3DGH (const cGH *GH);
+int IOSDF_TriggerOutput3D (const cGH *GH, int);
+int IOSDF_TimeFor3D (const cGH *GH, int);
+int IOSDF_Output3DVarAs (const cGH *GH, const char *var, const char *alias);
+
+/* other function prototypes */
+void IOSDF_Startup (void);
+
+int IOSDF_Write1D (const cGH *GH, int vindex, const char *alias);
+int IOSDF_Write2D (const cGH *GH, int vindex, const char *alias);
+int IOSDF_Write3D (const cGH *GH, int vindex, const char *alias);
+
+void IOSDF_Choose1D (const cGH *GH);
+void IOSDF_Choose2D (const cGH *GH);
+
+void IOSDF_CheckSteerableParameters1D (ioSDFGH *myGH);
+void IOSDF_CheckSteerableParameters2D (ioSDFGH *myGH);
+void IOSDF_CheckSteerableParameters3D (ioSDFGH *myGH);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* _IOSDF_IOSDFGH_H_ */
diff --git a/src/make.code.defn b/src/make.code.defn
new file mode 100644
index 0000000..8bf6eb1
--- /dev/null
+++ b/src/make.code.defn
@@ -0,0 +1,6 @@
+# Main make.code.defn file for thorn IOSDF
+# $Header$
+
+# Source files in this directory
+SRCS = Startup.c ChooseOutput.c Output1D.c Write1D.c Output2D.c Write2D.c \
+ Output3D.c Write3D.c