SpECTRE Documentation Coverage Report
Current view: top level - __w/spectre/spectre/docs/DevGuide - OptionParsing.md Hit Total Coverage
Commit: b7cf72820a3faaa6fb97f8d6135c1ee188e37de8 Lines: 0 1 0.0 %
Date: 2024-04-23 18:44:12
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : \cond NEVER
       2             : Distributed under the MIT License.
       3             : See LICENSE.txt for details.
       4             : \endcond
       5             : # Option Parsing {#dev_guide_option_parsing}
       6             : 
       7             : \tableofcontents
       8             : 
       9             : SpECTRE can read YAML configuration files at runtime to set parameters
      10             : and choose between classes implementing an interface.  %Options are
      11             : parsed during code initialization and can be used to construct objects
      12             : placed in the Parallel::GlobalCache and options passed to the
      13             : parallel components.  The types necessary to mark objects for parsing
      14             : are declared in `Options/Options.hpp`.
      15             : 
      16             : ## Metadata and options
      17             : 
      18             : YAML input files begin with a metadata section, terminated by `---`, and
      19             : followed by the executable options:
      20             : 
      21             : ```yaml
      22             : # Metadata here
      23             : Description: |
      24             :   Briefly describe the configuration and link to papers for details.
      25             : ---
      26             : # Options start here
      27             : ```
      28             : 
      29             : The metadata section may also be empty:
      30             : 
      31             : ```yaml
      32             : ---
      33             : ---
      34             : # Options start here
      35             : ```
      36             : 
      37             : You only need the leading `---` marker if the metadata section is empty. This is
      38             : YAML's "document start marker" (see the [YAML spec](https://yaml.org/spec/1.2)).
      39             : Any metadata fields at the beginning of the file also imply the start of a
      40             : document, so you don't need the first `---` marker.
      41             : 
      42             : Metadata provide information for tools, whereas options provide information to
      43             : the executable. See tools like `CheckOutputFiles` for details on the metadata
      44             : fields that they use. Metadata can also provide information on how to run the
      45             : input file, such as the name and version of the executable, and a description
      46             : that may refer to published papers for details on the configuration.
      47             : Options are defined by the executable and detailed below.
      48             : 
      49             : ## General option format
      50             : 
      51             : An option is defined by an "option tag", represented by a `struct`.  At minimum,
      52             : the struct must declare the type of the object to be parsed and provide a brief
      53             : description of the meaning.  The name of the option in the input file
      54             : defaults to the name of the struct (excluding any template parameters
      55             : and scope information), but can be overridden by providing a static
      56             : `name()` function.  Several other pieces of information, such as
      57             : suggestions, limits and grouping, may be provided if desired.  This
      58             : information is all included in the generated help output.
      59             : 
      60             : If an option has a suggested value, the value is specified in the
      61             : input file as usual, but a warning will be issued if the specified
      62             : value does not match the suggestion.
      63             : 
      64             : Examples:
      65             : \snippet Test_Options.cpp options_example_scalar_struct
      66             : \snippet Test_Options.cpp options_example_vector_struct
      67             : 
      68             : The option type can be any type understood natively by yaml-cpp
      69             : (fundamentals, `std::string`, and `std::map`, `std::vector`,
      70             : `std::list`, `std::array`, and `std::pair` of parsable types) and
      71             : types SpECTRE adds support for.  SpECTRE adds `std::unordered_map`
      72             : (but only with ordered keys), `std::variant` (with alternatives tested
      73             : in order), and various classes marked as constructible in their
      74             : declarations.
      75             : 
      76             : An option tag can be placed in a group by adding a `group` type alias to the
      77             : struct. The alias should refer to a type that, like option tags, defines a help
      78             : string and may override a static `name()` function.
      79             : 
      80             : Example:
      81             : \snippet Test_Options.cpp options_example_group
      82             : 
      83             : ## Constructible classes
      84             : 
      85             : A class that defines `static constexpr Options::String help` and a
      86             : typelist of option structs `options` can be created by the option
      87             : parser.  When the class is requested, the option parser will parse
      88             : each of the options in the `options` list, and then supply them to the
      89             : constructor of the class.  A class can use Options::Alternatives to
      90             : support more than one possible set of options for its creation.  (See
      91             : [Custom parsing](#custom-parsing) below for more general creation
      92             : mechanisms.)
      93             : 
      94             : Unlike option descriptions, which should be brief, the class help
      95             : string has no length limits and should give a description of the class
      96             : and any necessary discussion of its options beyond what can be
      97             : described in their individual help strings.
      98             : 
      99             : Creatable classes must be default constructible and move assignable.
     100             : 
     101             : The `Options::Context` is an optional argument to the constructor that should be
     102             : used when the constructor checks for validity of the input. If the input is
     103             : invalid, `PARSE_ERROR` is used to propagate the error message back through the
     104             : options ensuring that the error message will have a full backtrace so it is easy
     105             : for the user to diagnose.
     106             : 
     107             : Example:
     108             : \snippet Test_CustomTypeConstruction.cpp class_creation_example
     109             : 
     110             : Classes may use the Metavariables struct, which is effectively the compile time
     111             : input file, in their parsing by templating the `options` type alias or by taking
     112             : the Metavariables as a final argument to the constructor (after the
     113             : `Options::Context`).
     114             : 
     115             : Example:
     116             : \snippet Test_CustomTypeConstruction.cpp class_creation_example_with_metavariables
     117             : 
     118             : ## Factory
     119             : 
     120             : The factory interface creates an object of type
     121             : `std::unique_ptr<Base>` containing a pointer to some class derived
     122             : from `Base`.  The list of creatable derived classes is specified in
     123             : the `factory_creation` struct in the metavariables, which must contain
     124             : a `factory_classes` type alias that is a `tmpl::map` from base classes
     125             : to lists of derived classes:
     126             : \snippet Test_Factory.cpp factory_creation
     127             : 
     128             : When a `std::unique_ptr<Base>` is requested, the factory will expect a
     129             : single YAML argument specifying the name of the class (as given by a
     130             : static `name()` function or, lacking that, the actual class name).  If
     131             : the derived class takes no arguments, the name can be given as a YAML
     132             : string, otherwise it must be given as a single key-value pair, with
     133             : the key the name of the class.  The value portion of this pair is then
     134             : used to create the requested derived class in the same way as an
     135             : explicitly constructible class.  Examples:
     136             : \snippet Test_Factory.cpp factory_without_arguments
     137             : \snippet Test_Factory.cpp factory_with_arguments
     138             : 
     139             : \anchor custom-parsing
     140             : ## Custom parsing
     141             : 
     142             : Occasionally, the requirements imposed by the default creation
     143             : mechanism are too stringent.  In these cases, the construction
     144             : algorithm can be overridden by providing a specialization of the
     145             : struct
     146             : \code{cpp}
     147             : template <typename T>
     148             : struct Options::create_from_yaml {
     149             :   template <typename Metavariables>
     150             :   static T create(const Options::Option& options);
     151             : };
     152             : \endcode
     153             : The create function can perform any operations required to construct
     154             : the object.
     155             : 
     156             : Example of using a specialization to parse an enum:
     157             : \snippet Test_CustomTypeConstruction.cpp enum_creation_example
     158             : 
     159             : Note that in the case where the `create` function does *not* need to use the
     160             : `Metavariables` it is recommended that a general implementation forward to an
     161             : explicit instantiation with `void` as the `Metavariables` type. The reason for
     162             : using `void` specialization is to reduce compile time. Since we only need one
     163             : full implementation of the function independent of what type `Metavariables` is,
     164             : we should only parse and compile it once. By having a specialization on `void`
     165             : (or some other non-metavariables type like `NoSuchType`) we can handle the
     166             : metavariables-independent case efficiently. As a concrete example, the general
     167             : definition and forward declaration of the `void` specialization in the header
     168             : file would be:
     169             : 
     170             : \snippet Test_CustomTypeConstruction.cpp enum_void_creation_header_example
     171             : 
     172             : while in the `cpp` file the definition of the `void` specialization is:
     173             : 
     174             : \snippet Test_CustomTypeConstruction.cpp enum_void_creation_cpp_example

Generated by: LCOV version 1.14