Skip to content

Commit

Permalink
Change ReduceCceWorldtube to use options
Browse files Browse the repository at this point in the history
  • Loading branch information
knelli2 committed Sep 12, 2024
1 parent b245c4f commit a0a4ecd
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 34 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/DeployStaticExecutables.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ jobs:
cp ./tests/InputFiles/Cce/CharacteristicExtract.yaml
./CceExecutables/CharacteristicExtract.yaml
cp ./tests/InputFiles/ReduceCceWorldtube/ReduceCceWorldtube.yaml
./CceExecutables/ReduceCceWorldtube.yaml
for i in CharacteristicExtract ReduceCceWorldtube; do
docker cp static-execs:/work/spectre/build/bin/$i ./CceExecutables;
done
Expand Down
18 changes: 11 additions & 7 deletions docs/Tutorials/CCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ release). Inside this tarball is
[Input worldtube data formats](#input_worldtube_data_formats) section)
- an example YAML input file
- example output from CCE
- a `ReduceCceWorldtube` executable for converting between
- a `ReduceCceWorldtube` executable and YAML file for converting between
[worldtube data formats](#input_worldtube_data_formats)

\note The tarball is `.xz` so use `tar -xf TarName.tar.xz` to extract. The `-z`
Expand Down Expand Up @@ -198,18 +198,22 @@ SpECTRE provides a separate executable for converting from the
The `ReduceCceWorldtube` executable should be run on a
[cartesian_metric](#cartesian_metric_and_derivatives) worldtube file, and will
produce a corresponding 'reduced' Bondi-Sachs worldtube file.
The basic command-line arguments for the executable are:
This executable works similarly to our other executables by accepting a YAML
input file:

```
ReduceCceWorldtube --input-file CceR0050.h5 --output-file BondiCceR0050.h5\
--lmax_factor 3
ReduceCceWorldtube --input-file ReduceCceWorldtube.yaml
```

The argument `--lmax_factor` determines the factor by which the resolution of
with a YAML file

\snippet ReduceCceWorldtube.yaml reduce_cce_worldtube_yaml_doxygen_example

The option `LMaxFactor` determines the factor by which the resolution of
the boundary computation that is run will exceed the resolution of the
input and output files.
Empirically, we have found that `lmax_factor` of 3 is sufficient to achieve
roundoff precision in all boundary data we have attempted, and an `lmax_factor`
Empirically, we have found that `LMaxFactor` of 3 is sufficient to achieve
roundoff precision in all boundary data we have attempted, and an `LMaxFactor`
of 2 is usually sufficient to vastly exceed the precision of the simulation that
provided the boundary dataset.

Expand Down
2 changes: 2 additions & 0 deletions src/Executables/ReduceCceWorldtube/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ target_link_libraries(
Cce
GeneralRelativity
Informer
Options
Parallel
Printf
Spectral
SpinWeightedSphericalHarmonics
Expand Down
178 changes: 151 additions & 27 deletions src/Executables/ReduceCceWorldtube/ReduceCceWorldtube.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@

#include <boost/program_options.hpp>
#include <cstddef>
#include <exception>
#include <string>

#include "DataStructures/ComplexModalVector.hpp"
#include "DataStructures/DataBox/DataBox.hpp"
#include "DataStructures/DataBox/Tag.hpp"
#include "DataStructures/DataVector.hpp"
#include "DataStructures/SpinWeighted.hpp"
#include "DataStructures/Variables.hpp"
Expand All @@ -18,9 +20,14 @@
#include "Evolution/Systems/Cce/WorldtubeBufferUpdater.hpp"
#include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshCoefficients.hpp"
#include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshCollocation.hpp"
#include "Options/Auto.hpp"
#include "Options/ParseOptions.hpp"
#include "Options/String.hpp"
#include "Parallel/CreateFromOptions.hpp"
#include "Parallel/Printf/Printf.hpp"
#include "Utilities/Gsl.hpp"
#include "Utilities/TMPL.hpp"
#include "Utilities/TaggedTuple.hpp"

// Charm looks for this function but since we build without a main function or
// main module we just have it be empty
Expand Down Expand Up @@ -275,6 +282,107 @@ void perform_cce_worldtube_reduction(
}
Parallel::printf("\n");
}

namespace OptionTags {
struct InputSpecH5File {
using type = std::string;
static constexpr Options::String help =
"Name of SpEC H5 worldtube file. A '.h5' extension will be added if "
"needed.";
};

struct OutputH5File {
using type = std::string;
static constexpr Options::String help =
"Name of output H5 file. A '.h5' extension will be added if needed.";
};

struct FixSpecNormalization {
using type = bool;
static constexpr Options::String help =
"Apply corrections associated with documented SpEC worldtube file "
"errors. If you are using worldtube data from SpECTRE or from another NR "
"code but in the SpECTRE format, then this option should be 'False'";
};

struct BufferDepth {
using type = Options::Auto<size_t>;
static constexpr Options::String help =
"Number of time steps to load during each call to the file-accessing "
"routines. Higher values mean fewer, larger loads from file into RAM. "
"Default 2000.";
};

struct LMaxFactor {
using type = Options::Auto<size_t>;
static constexpr Options::String help =
"The boundary computations will be performed at a resolution that is "
"'LMaxFactor' times the input file LMax to avoid aliasing. Default 2.";
};
} // namespace OptionTags

using option_tags =
tmpl::list<OptionTags::InputSpecH5File, OptionTags::OutputH5File,
OptionTags::FixSpecNormalization, OptionTags::BufferDepth,
OptionTags::LMaxFactor>;
using OptionTuple = tuples::tagged_tuple_from_typelist<option_tags>;

namespace ReduceCceTags {
struct InputSpecH5File : db::SimpleTag {
using type = std::string;
using option_tags = tmpl::list<OptionTags::InputSpecH5File>;
static constexpr bool pass_metavariables = false;
static type create_from_options(std::string option) {
if (not option.ends_with(".h5")) {
option += ".h5";
}
return option;
}
};

struct OutputH5File : db::SimpleTag {
using type = std::string;
using option_tags = tmpl::list<OptionTags::OutputH5File>;
static constexpr bool pass_metavariables = false;
static type create_from_options(std::string option) {
if (not option.ends_with(".h5")) {
option += ".h5";
}
return option;
}
};

struct FixSpecNormalization : db::SimpleTag {
using type = bool;
using option_tags = tmpl::list<OptionTags::FixSpecNormalization>;
static constexpr bool pass_metavariables = false;
static type create_from_options(const bool option) { return option; }
};

struct BufferDepth : db::SimpleTag {
using type = size_t;
using option_tags = tmpl::list<OptionTags::BufferDepth>;
static constexpr bool pass_metavariables = false;
static type create_from_options(const std::optional<size_t>& option) {
return option.value_or(2000);
}
};

struct LMaxFactor : db::SimpleTag {
using type = size_t;
using option_tags = tmpl::list<OptionTags::BufferDepth>;
static constexpr bool pass_metavariables = false;
static type create_from_options(const std::optional<size_t>& option) {
return option.value_or(2);
}
};
} // namespace ReduceCceTags

using tags =
tmpl::list<ReduceCceTags::InputSpecH5File, ReduceCceTags::OutputH5File,
ReduceCceTags::FixSpecNormalization, ReduceCceTags::BufferDepth,
ReduceCceTags::LMaxFactor>;
using TagsTuple = tuples::tagged_tuple_from_typelist<tags>;
} // namespace

/*
Expand All @@ -283,44 +391,60 @@ void perform_cce_worldtube_reduction(
* storing the worldtube scalars that are required as input for CCE.
*/
int main(int argc, char** argv) {
boost::program_options::positional_options_description pos_desc;
pos_desc.add("old_spec_cce_file", 1).add("output_file", 1);

// Boost options for the input yaml and --help flag
boost::program_options::options_description desc("Options");
desc.add_options()("help,h,", "show this help message")(
"input_file", boost::program_options::value<std::string>()->required(),
"name of old CCE data file")(
"output_file", boost::program_options::value<std::string>()->required(),
"output filename")(
"fix_spec_normalization",
"Apply corrections associated with documented SpEC "
"worldtube file errors")(
"buffer_depth",
boost::program_options::value<size_t>()->default_value(2000),
"number of time steps to load during each call to the file-accessing "
"routines. Higher values mean fewer, larger loads from file into RAM.")(
"lmax_factor", boost::program_options::value<size_t>()->default_value(2),
"the boundary computations will be performed at a resolution that is "
"lmax_factor times the input file lmax to avoid aliasing");
"input-file", boost::program_options::value<std::string>()->required(),
"Name of YAML file to parse.");

boost::program_options::variables_map vars;

boost::program_options::store(
boost::program_options::command_line_parser(argc, argv)
.positional(pos_desc)
.options(desc)
.run(),
vars);

if (vars.count("help") != 0u or vars.count("input_file") == 0u or
vars.count("output_file") == 0u) {
Parallel::printf("%s\n", desc);
// Option parser for all the actual options
Options::Parser<option_tags> parser{
"This executable is used for converting the unnecessarily large SpEC "
"worldtube data format into a far smaller representation (roughly a "
"factor of 4) just storing the worldtube scalars that are required as "
"input for CCE."};

// Help is a successful return
if (vars.contains("help")) {
Parallel::printf("%s\n%s", desc, parser.help());
return 0;
}

perform_cce_worldtube_reduction(vars["input_file"].as<std::string>(),
vars["output_file"].as<std::string>(),
vars["buffer_depth"].as<size_t>(),
vars["lmax_factor"].as<size_t>(),
vars.count("fix_spec_normalization") != 0u);
// Not specifying an input file is an error
if (not vars.contains("input-file")) {
Parallel::printf("Missing input file. Pass '--input-file'");
return 1;
}

// Wrap in try-catch to print nice errors and terminate gracefully
try {
const std::string input_yaml = vars["input-file"].as<std::string>();

// Actually parse the yaml. This does a check if it exists.
parser.parse_file(input_yaml);

// First create option tags, and then actual tags.
const OptionTuple options = parser.template apply<option_tags>(
[](auto... args) { return OptionTuple(std::move(args)...); });
const TagsTuple inputs =
Parallel::create_from_options<void>(options, tags{});

// Do the reduction
perform_cce_worldtube_reduction(
tuples::get<ReduceCceTags::InputSpecH5File>(inputs),
tuples::get<ReduceCceTags::OutputH5File>(inputs),
tuples::get<ReduceCceTags::BufferDepth>(inputs),
tuples::get<ReduceCceTags::BufferDepth>(inputs),
tuples::get<ReduceCceTags::FixSpecNormalization>(inputs));
} catch (const std::exception& exception) {
Parallel::printf("%s\n", exception.what());
return 1;
}
}
12 changes: 12 additions & 0 deletions tests/InputFiles/ReduceCceWorldtube/ReduceCceWorldtube.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Distributed under the MIT License.
# See LICENSE.txt for details.

# [reduce_cce_worldtube_yaml_doxygen_example]

InputSpecH5File: SpecFilenameR0292.h5
OutputH5File: ReducedWorldtubeR0292.h5
FixSpecNormalization: False
BufferDepth: Auto
LMaxFactor: 3

# [reduce_cce_worldtube_yaml_doxygen_example]

0 comments on commit a0a4ecd

Please sign in to comment.