Serac  0.1
Serac is an implicit thermal strucural mechanics simulation code.
cli.cpp
1 // Copyright (c) 2019-2024, Lawrence Livermore National Security, LLC and
2 // other Serac Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
8 
9 #include "axom/CLI11.hpp"
10 
14 
15 namespace serac::cli {
16 
17 //------- Command Line Interface -------
18 
19 std::unordered_map<std::string, std::string> defineAndParse(int argc, char* argv[], std::string app_description)
20 {
21  // NOTE: When adding/removing command line options remember to update the following places as well:
22  // src/docs/sphinx/user_guide/command_line_options.rst
23  // serac::cli::printGiven() (in this file)
24 
25  // specify all input arguments
26  axom::CLI::App app{app_description};
27  std::string input_file_path;
28  app.add_option("-i, --input-file", input_file_path, "Input file to use")->check(axom::CLI::ExistingFile);
29  int restart_cycle;
30  auto restart_opt =
31  app.add_option("-c, --restart-cycle", restart_cycle, "Cycle to restart from")->check(axom::CLI::PositiveNumber);
32  bool create_input_file_docs{false};
33  app.add_flag("-d, --create-input-file-docs", create_input_file_docs,
34  "Writes Sphinx documentation for input file, then exits");
35  std::string output_directory;
36  app.add_option("-o, --output-directory", output_directory, "Directory to put outputted files");
37  bool enable_paraview{false};
38  app.add_flag("-p, --paraview", enable_paraview, "Enable ParaView output");
39  bool print_unused{false};
40  app.add_flag("-u, --print-unused", print_unused, "Prints unused entries in input file, then exits");
41  bool version{false};
42  app.add_flag("-v, --version", version, "Print version and provenance information, then exits");
43 
44  // Parse the arguments and check if they are good
45  try {
46  app.parse(argc, argv);
47  } catch (const axom::CLI::ParseError& e) {
48  serac::logger::flush();
49  if (e.get_name() == "CallForHelp") {
50  auto msg = app.help();
51  SLIC_INFO_ROOT(msg);
53  } else {
54  auto err_msg = axom::CLI::FailureMessage::simple(&app, e);
55  SLIC_ERROR_ROOT(err_msg);
56  }
57  }
58 
59  // Store found values and set defaults if not set above
60  std::unordered_map<std::string, std::string> cli_opts;
61  if (version) {
62  // If version is on the command line ignore all others and do not require anything
63  cli_opts.insert({"version", {}});
64  } else {
65  if (input_file_path.empty()) {
66  SLIC_ERROR_ROOT("No input file given. Use '--help' for command line options.");
67  }
68 
69  cli_opts.insert({std::string("input-file"), input_file_path});
70  // If a restart cycle was specified
71  if (restart_opt->count() > 0) {
72  cli_opts["restart-cycle"] = std::to_string(restart_cycle);
73  }
74  if (create_input_file_docs) {
75  cli_opts.insert({"create-input-file-docs", {}});
76  }
77  if (print_unused) {
78  cli_opts.insert({"print-unused", {}});
79  }
80  if (output_directory == "") {
81  // if given by user use that otherwise use input file's basename minus extension
82  output_directory = serac::input::getInputFileName(input_file_path);
83  }
84  cli_opts.insert({"output-directory", output_directory});
85  if (enable_paraview) {
86  cli_opts.insert({"paraview", {}});
87  cli_opts.insert({"paraview-directory", output_directory + "_paraview"});
88  }
89  }
90 
91  return cli_opts;
92 }
93 
94 namespace detail {
95 
96 std::string cliValueToString(std::string value) { return value; }
97 
98 std::string cliValueToString(bool value) { return value ? "true" : "false"; }
99 
100 std::string cliValueToString(int value) { return std::to_string(value); }
101 
102 } // namespace detail
103 
104 void printGiven(std::unordered_map<std::string, std::string>& cli_opts)
105 {
106  // Add header
107  std::string optsMsg = axom::fmt::format("\n{:*^80}\n", "Command Line Options");
108 
109  // Create options map
110  // clang-format off
111  std::vector<std::pair<std::string, std::string>> opts_output_map{
112  {"create-input-file-docs", "Create Input File Docs"},
113  {"input-file", "Input File"},
114  {"output-directory", "Output Directory"},
115  {"paraview", "Enable ParaView output"},
116  {"restart-cycle", "Restart Cycle"},
117  {"version", "Print version"}};
118  // clang-format on
119 
120  // Add options to string
121  for (auto output_pair : opts_output_map) {
122  auto search = cli_opts.find(output_pair.first);
123  if (search != cli_opts.end()) {
124  optsMsg += axom::fmt::format("{0}: {1}\n", output_pair.second, detail::cliValueToString(search->second));
125  }
126  }
127 
128  // Add footer
129  optsMsg += axom::fmt::format("{:*^80}\n", "*");
130 
131  SLIC_INFO_ROOT(optsMsg);
132  serac::logger::flush();
133 }
134 
135 } // namespace serac::cli
This file contains the all the necessary functions and macros required for interacting with the comma...
This file contains the all the necessary functions for reading input files.
This file contains the all the necessary functions and macros required for logging as well as a helpe...
Command line functionality.
Definition: cli.cpp:15
std::unordered_map< std::string, std::string > defineAndParse(int argc, char *argv[], std::string app_description)
Defines command line options and parses the found values.
Definition: cli.cpp:19
void printGiven(std::unordered_map< std::string, std::string > &cli_opts)
Prints all given command line options to the screen.
Definition: cli.cpp:104
std::string getInputFileName(const std::string &file_path)
Returns the name of the input file (base name with file extension removed).
Definition: input.cpp:80
std::string version(bool add_SHA)
Returns a string for the version of Serac.
Definition: about.cpp:211
void exitGracefully(bool error)
Exits the program gracefully after cleaning up necessary tasks.
Definition: terminator.cpp:44
Helper functions for exiting Serac cleanly.