diff --git a/components/eamxx/docs/user/model_input.md b/components/eamxx/docs/user/model_input.md index 38486c77a21..b9ba4358d05 100644 --- a/components/eamxx/docs/user/model_input.md +++ b/components/eamxx/docs/user/model_input.md @@ -1,8 +1,230 @@ -Model input +Model inputs ===================================== -TODO: explain how defaults XML, atmchange/atmquery, buildml, and input.yaml work. +This section explains how input parameters are passed to EAMxx, and how the user can +change their value. The full list of the currently configuraable runtime parameters for +EAMxx can be found [here](../common/eamxx_params.md). -[Here](../common/eamxx_params.md) is a list of the currently configurable runtime parameters for EAMxx. +In the following, we assume that the reader has a familiarity with [CIME case +control](https://esmci.github.io/cime/versions/master/html/users_guide/index.html). +The main files/scripts involved in the EAMxx runtime configuration are the following: +1. `buildnml`: this script, located in `components/eamxx/cime_config`, is called by CIME's case management + scripts (`case.setup`, `case.build, `case.submit`), and is responsible for creating EAMxx input files, + including handling of user-specific modifications for the runtime parameters. Users should not have to + modify this script, nor should they have to manually call it. +2. `scream_input.yaml`: EAMxx will parse this [YAML](https://yaml.org/spec/1.2.2) file at runtime, + to detect all of its configuration parameters. It is generated automatically by `buildnml` inside the + RUNDIR/data folder, where `RUNDIR` is the run directory generated by CIME. Since this file is automatically + generated when `buildnml` runs, users should not manually modify it. Any manual modification will be + lost the next time `buildnml` runs (e.g., at `case.submit` time). +3. 'namelist_scream.xml`: this XML file is generated by `buildnml`, and contains all the runtime parameters that EAMxx + will read in at runtime. `buildnml` uses this XML file as an intermediate file during the generation of + `scream_input.yaml`. In particular, `buildnml` generates this file using case information to select the + proper configuration from the file `namelist_defaults_scream.xml`, located in `components/eamxx/cime_config`. + As it was the case for `scream_input.yaml`, since this XML file is automatically generated by `buildnml`, + the user should not manually modify this file. Any manual modification will be lost the next time `buildnml` + runs (e.g., at `case.submit` time). + Since the main product of `buildnml` is `scream_input.yaml`, one may wonder why we keep + this XML file around at all. The main reason is to make it easier for the `atmquery` script (see below) to + retrieve settings. +4. `namelist.nl`: EAMxx will parse this [namelist](https://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vnad/index.html) + file at runtime, to retrieve all the parameters specific to the [Homme](some_homme_ref) dycore. + It is generated automatically by `buildnml` inside the RUNDIR/data folder, where `RUNDIR` is the run + directory generated by CIME. Since this file is automatically generated when `buildnml` runs, + users should not manually modify it. Any manual modification will be lost the next time `buildnml` runs + (e.g., at `case.submit` time). +5. `atmchange` and `atmquery`: these script, located in `components/eamxx/scripts` and linked in the case folder, + can be used to query and change any of the runtime configuration parameters of EAMxx. + +Among the files listed above, `atmquery` and `atmchange` are the only ones that the user should interact with, +and therefore we give here a brief overview of how they can be used, and how their output can be interpreted. +For both these scripts, a short help can also be obtained using the `-h` flag, highlighting their use cases and options. + +# Querying parameters with `atmquery` + +This script is the simplest way for the user to check the value and properties of EAMxx input parameters. +A basic usage of the script is + +```bash +$ ./atmquery my_param +``` +which will retrieve the value of the parameter called `my_param`, by locating the XML node "my_param" in the +file `namelist_scream.xml` in the RUNDIR folder. Obviously, an XML file can have multiple nodes with the same tag, +and the script is implemented to error out if multiple matches are found. In such a scenario, the user needs +to provide also the parents nodes names, using enough parents to uniquely identify the node (in most cases, +one parent is enough). To specify a parent, the user can prepend the parent name and `::` to the node name: + +```bash +$ ./atmquery foo::my_param +``` + +The output will contain the fully scoped parameter name, along with the value. E.g., +```bash +$ ./atmquery foo::my_param + namelist_defaults::node1::node2::foo::my_param: 10 +``` + +It is sometimes desirable to query _all_ the nodes that have a particular name, or that contain a particular +string. We can do that by using the `--grep` flag: +```blah +$ ./atmquery --grep sub + iop_options::iop_dosubsidence: false + ctl_nl::hypervis_subcycle: 1 + ctl_nl::hypervis_subcycle_tom: 1 + ctl_nl::hypervis_subcycle_q: 6 + atmosphere_processes::number_of_subcycles: 1 + sc_import::number_of_subcycles: 1 + homme::number_of_subcycles: 1 + physics::number_of_subcycles: 1 +``` +TODO: This difference between basica and `--grep` is not really intuitive (see [this +issue](https://github.com/E3SM-Project/scream/issues/2413)). +Using the `--grep` option has another effect: if the match is not a leaf of the XML tree, all its subelements +are printed: +```bash +$ ./atmquery --grep homme + homme + Moisture: moist + BfbHash: 18 + number_of_subcycles: 1 + enable_precondition_checks: true + enable_postcondition_checks: true + repair_log_level: trace + internal_diagnostics_level: 0 + compute_tendencies: None +``` + +Similarly to the CIME utility `xmlchange`, the options `--value`, `--type`, `--valid-values`, and `--full` can be +used to respectively retrieve just the parameter value (useful for bash scripting), the parameter's type, +a list of valid values for parameter (when applicable), or all of the above: +```bash +$ ./atmquery atm_log_level --value + info +$ ./atmquery atm_log_level --type + namelist_defaults::driver_options::atm_log_level: string +$ ./atmquery atm_log_level --valid-values + namelist_defaults::driver_options::atm_log_level: ['trace', 'debug', 'info', 'warn', 'error'] +$ ./atmquery atm_log_level --full + namelist_defaults::driver_options::atm_log_level + value: info + type: string + valid values: ['trace', 'debug', 'info', 'warn', 'error'] +``` + +Finally, the option `--listall` can be used to list the whole content of the XML file, which will be displayed +with each node indented in its parent scope: +```bash +$ ./atmquery --listall + namelist_defaults + grids_manager + Type: Homme + physics_grid_type: PG2 + physics_grid_rebalance: None + dynamics_namelist_file_name: ./data/namelist.nl + vertical_coordinate_filename: /some/path/to/coords/file.nc + initial_conditions + Filename: /some/path/to/ic/file.nc + topography_filename: /some/path/to/topo/file.nc + ... +``` + +# Changing model inputs via `atmchange` + +When `buildnml` runs, the model inputs are deduced from the case configuration settings (e.g., the grid, +the compset, etc.) and the `namelist_scream_defaults.xml` file, located in the eamxx source tree. +The user can change any of these parameters using the `atmchange` script. +A basic usage of the script is + +```bash +$ ./atmchange my_param=10 +``` +As for `atmquery`, if there are multiple matches for a given parameter name, the user must specify a unique +scoped name, which allows `atmchange` to uniquely identify the XML node to modify: +```bash +$ ./atmquery homme::number_of_subcycles + namelist_defaults::atmosphere_processes::homme::number_of_subcycles: 1 +$ ./atmchange number_of_subcycles=10 +ERROR: number_of_subcycles is ambiguous (use --all to change all matches), matches: + namelist_defaults::atmosphere_processes::number_of_subcycles + namelist_defaults::atmosphere_processes::sc_import::number_of_subcycles + namelist_defaults::atmosphere_processes::homme::number_of_subcycles + namelist_defaults::atmosphere_processes::physics::number_of_subcycles + namelist_defaults::atmosphere_processes::physics::mac_aero_mic::number_of_subcycles + namelist_defaults::atmosphere_processes::physics::mac_aero_mic::tms::number_of_subcycles + namelist_defaults::atmosphere_processes::physics::mac_aero_mic::shoc::number_of_subcycles + namelist_defaults::atmosphere_processes::physics::mac_aero_mic::cldFraction::number_of_subcycles + namelist_defaults::atmosphere_processes::physics::mac_aero_mic::p3::number_of_subcycles + namelist_defaults::atmosphere_processes::physics::rrtmgp::number_of_subcycles + namelist_defaults::atmosphere_processes::sc_export::number_of_subcycles +$ ./atmchange homme::number_of_subcycles=10 +Regenerating /path/to/namelist_scream.xml. Manual edits will be lost. +$ ./atmquery homme::number_of_subcycles + namelist_defaults::atmosphere_processes::homme::number_of_subcycles: 10 +``` +In some cases, the user may be interested in changing _all_ nodes with a given name. In that case, +the `--all` flag can be used: +```bash +$ ./atmquery --grep number_of_subcycles + atmosphere_processes::number_of_subcycles: 1 + sc_import::number_of_subcycles: 1 + homme::number_of_subcycles: 1 + physics::number_of_subcycles: 1 + mac_aero_mic::number_of_subcycles: 24 + tms::number_of_subcycles: 1 + shoc::number_of_subcycles: 1 + cldFraction::number_of_subcycles: 1 + spa::number_of_subcycles: 1 + p3::number_of_subcycles: 1 + rrtmgp::number_of_subcycles: 1 + sc_export::number_of_subcycles: 1 +$ ./atmchange --all number_of_subcycles=3 +Regenerating /path/to/namelist_scream.xml. Manual edits will be lost. +$ ./atmquery --grep number_of_subcycles + atmosphere_processes::number_of_subcycles: 3 + sc_import::number_of_subcycles: 3 + homme::number_of_subcycles: 3 + physics::number_of_subcycles: 3 + mac_aero_mic::number_of_subcycles: 3 + tms::number_of_subcycles: 3 + shoc::number_of_subcycles: 3 + cldFraction::number_of_subcycles: 3 + spa::number_of_subcycles: 3 + p3::number_of_subcycles: 3 + rrtmgp::number_of_subcycles: 3 + sc_export::number_of_subcycles: 3 +``` +Since the XML file stores constraints on the parameter value (like its type or valid values), attempting to use the +wrong type will cause an error: +```bash +$ ./atmquery --type se_ne + namelist_defaults::ctl_nl::se_ne: integer +$ ./atmchange se_ne=hello +ERROR: Could not refine 'hello' as type 'integer': +``` +There are three main types supported: integer, float, string, logical. When passing a string to `atmchange`, +the script will try to interpret it acoording to the parameter type, and throw an error if that's not possible: +for "string", anything works; for "integer", only digits are allowed, possibly with a negative sign in front; +for "float", only digits are allowed, possibly with a negative sign in front and a decimal point; for "logical", +only the strings "true" and "false" are allowed (case insensitive). There are two additional types supported: +"file" and "array(T)", where "T" is any of the other supported types (but not another array): + - "file" is used to inform CIME of the input files that have to be download from E3SM data servers, like initial conditions files, +or certain lookup tables. + - "array(T)" allows to specify a list of items (of the same type), which will be parsed inside EAMxx as + a `std::vector`. + +For type "string" and "array(T)", it is also possible to _append_ to the currently stored value +```bash +$ ./atmquery homme::compute_tendencies + namelist_defaults::atmosphere_processes::homme::compute_tendencies: + value: a, b + type: array(string) + valid values: [] +$ ./atmchange homme::compute_tendencies+=c +$ ./atmquery homme::compute_tendencies --full + namelist_defaults::atmosphere_processes::homme::compute_tendencies + value: a, b, c + type: array(string) + valid values: [] +```