Skip to content

Commit

Permalink
Prefix all namelist group and option names for MPAS dycore
Browse files Browse the repository at this point in the history
When MPAS is used as a dynamical core, the following transformations are
performed for each namelist group and option name:

1. Leading `config_` is removed recursively from the name. Case-insensitive.
2. Leading `mpas_` is removed recursively from the name. Case-insensitive.
3. Prepend `mpas_` to the name.

As a result, it is now easier to distinguish MPAS namelist groups and options
from CAM-SIMA ones. Additionally, the possibility of name collisions with
CAM-SIMA ones is also resolved once and for all.

Note that only namelist I/O is affected. Internally, MPAS still refers to its
namelist options by their original names due to compatibility reasons.
  • Loading branch information
kuanchihwang committed Jan 29, 2025
1 parent 37aa961 commit 183fed2
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
87 changes: 87 additions & 0 deletions src/tools/registry/gen_inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
#include "fortprintf.h"
#include "utility.h"

#ifdef MPAS_CAM_DYCORE
#include <ctype.h>
#endif

void process_core_macro(const char *macro, const char *val, va_list ap);
void process_domain_macro(const char *macro, const char *val, va_list ap);

Expand Down Expand Up @@ -699,6 +703,14 @@ int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/
const char *nmlrecname, *nmlrecindef, *nmlrecinsub;
const char *nmloptname, *nmlopttype, *nmloptval, *nmloptunits, *nmloptdesc, *nmloptposvals, *nmloptindef;

#ifdef MPAS_CAM_DYCORE
// Fortran variable names have a length limit of 63 characters. + 1 for the terminating null character.
char new_nmlrecname[64];
char new_nmloptname[64];
const char *old_nmlrecname;
const char *old_nmloptname;
#endif

char pool_name[1024];
char core_string[1024];

Expand Down Expand Up @@ -743,7 +755,14 @@ int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/

// Parse Namelist Records
for (nmlrecs_xml = ezxml_child(registry, "nml_record"); nmlrecs_xml; nmlrecs_xml = nmlrecs_xml->next){
#ifdef MPAS_CAM_DYCORE
old_nmlrecname = ezxml_attr(nmlrecs_xml, "name");
transform_name(new_nmlrecname, sizeof(new_nmlrecname), old_nmlrecname);

nmlrecname = new_nmlrecname;
#else
nmlrecname = ezxml_attr(nmlrecs_xml, "name");
#endif
nmlrecindef = ezxml_attr(nmlrecs_xml, "in_defaults");
nmlrecinsub = ezxml_attr(nmlrecs_xml, "in_subpool");

Expand Down Expand Up @@ -777,7 +796,14 @@ int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/

// Define variable definitions prior to reading the namelist in.
for (nmlopt_xml = ezxml_child(nmlrecs_xml, "nml_option"); nmlopt_xml; nmlopt_xml = nmlopt_xml->next){
#ifdef MPAS_CAM_DYCORE
old_nmloptname = ezxml_attr(nmlopt_xml, "name");
transform_name(new_nmloptname, sizeof(new_nmloptname), old_nmloptname);

nmloptname = new_nmloptname;
#else
nmloptname = ezxml_attr(nmlopt_xml, "name");
#endif
nmlopttype = ezxml_attr(nmlopt_xml, "type");
nmloptval = ezxml_attr(nmlopt_xml, "default_value");
nmloptunits = ezxml_attr(nmlopt_xml, "units");
Expand Down Expand Up @@ -809,7 +835,14 @@ int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/
// Define the namelist block, to read the namelist record in.
fortprintf(fd, " namelist /%s/ &\n", nmlrecname);
for (nmlopt_xml = ezxml_child(nmlrecs_xml, "nml_option"); nmlopt_xml; nmlopt_xml = nmlopt_xml->next){
#ifdef MPAS_CAM_DYCORE
old_nmloptname = ezxml_attr(nmlopt_xml, "name");
transform_name(new_nmloptname, sizeof(new_nmloptname), old_nmloptname);

nmloptname = new_nmloptname;
#else
nmloptname = ezxml_attr(nmlopt_xml, "name");
#endif
if(nmlopt_xml->next){
fortprintf(fd, " %s, &\n", nmloptname);
} else {
Expand Down Expand Up @@ -840,7 +873,14 @@ int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/
// Define broadcast calls for namelist values.
fortprintf(fd, " if (ierr <= 0) then\n");
for (nmlopt_xml = ezxml_child(nmlrecs_xml, "nml_option"); nmlopt_xml; nmlopt_xml = nmlopt_xml->next){
#ifdef MPAS_CAM_DYCORE
old_nmloptname = ezxml_attr(nmlopt_xml, "name");
transform_name(new_nmloptname, sizeof(new_nmloptname), old_nmloptname);

nmloptname = new_nmloptname;
#else
nmloptname = ezxml_attr(nmlopt_xml, "name");
#endif
nmlopttype = ezxml_attr(nmlopt_xml, "type");

if(strncmp(nmlopttype, "real", 1024) == 0){
Expand All @@ -858,7 +898,14 @@ int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/
fortprintf(fd, " call mpas_log_write(' The following values will be used for variables in this record:')\n");
fortprintf(fd, " call mpas_log_write(' ')\n");
for (nmlopt_xml = ezxml_child(nmlrecs_xml, "nml_option"); nmlopt_xml; nmlopt_xml = nmlopt_xml->next){
#ifdef MPAS_CAM_DYCORE
old_nmloptname = ezxml_attr(nmlopt_xml, "name");
transform_name(new_nmloptname, sizeof(new_nmloptname), old_nmloptname);

nmloptname = new_nmloptname;
#else
nmloptname = ezxml_attr(nmlopt_xml, "name");
#endif
nmlopttype = ezxml_attr(nmlopt_xml, "type");

if (strncmp(nmlopttype, "character", 1024) == 0) {
Expand All @@ -885,10 +932,21 @@ int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/
fortprintf(fd, "\n");

for (nmlopt_xml = ezxml_child(nmlrecs_xml, "nml_option"); nmlopt_xml; nmlopt_xml = nmlopt_xml->next){
#ifdef MPAS_CAM_DYCORE
old_nmloptname = ezxml_attr(nmlopt_xml, "name");
transform_name(new_nmloptname, sizeof(new_nmloptname), old_nmloptname);

nmloptname = new_nmloptname;

// Keep namelist options to their original names in MPAS pools for compatibility reasons.
fortprintf(fd, " call mpas_pool_add_config(%s, '%s', %s)\n", pool_name, old_nmloptname, nmloptname);
fortprintf(fcg, " call mpas_pool_get_config(configPool, '%s', %s)\n", old_nmloptname, nmloptname);
#else
nmloptname = ezxml_attr(nmlopt_xml, "name");

fortprintf(fd, " call mpas_pool_add_config(%s, '%s', %s)\n", pool_name, nmloptname, nmloptname);
fortprintf(fcg, " call mpas_pool_get_config(configPool, '%s', %s)\n", nmloptname, nmloptname);
#endif
}
fortprintf(fd, "\n");
fortprintf(fcg, "\n");
Expand Down Expand Up @@ -2532,3 +2590,32 @@ int parse_structs_from_registry(ezxml_t registry)/*{{{*/

return 0;
}/*}}}*/


#ifdef MPAS_CAM_DYCORE
// Perform transformations for namelist group and option names.
void transform_name(char *new_name, const size_t new_name_size, const char *old_name) {
const char *const new_prefix = "mpas_";
const char *const old_prefix = "config_";
size_t size = 0;

if (!new_name || !old_name || new_name_size == 0) return;

// Remove all leading whitespaces by moving pointer forward.
while (*old_name != '\0' && isspace((unsigned char) *old_name)) old_name++;

// Remove all leading `config_` by moving pointer forward.
while (strncasecmp(old_name, old_prefix, strlen(old_prefix)) == 0) old_name += strlen(old_prefix);

// Remove all leading `mpas_` by moving pointer forward.
while (strncasecmp(old_name, new_prefix, strlen(new_prefix)) == 0) old_name += strlen(new_prefix);

*new_name = '\0';
size = snprintf(NULL, 0, "%s%s", new_prefix, old_name) + 1;
snprintf(new_name, size > new_name_size ? new_name_size : size, "%s%s", new_prefix, old_name);

// Remove all trailing whitespaces by zeroing (nulling) out.
new_name += strlen(new_name) - 1;
while (*new_name != '\0' && isspace((unsigned char) *new_name)) *new_name-- = '\0';
}
#endif
4 changes: 4 additions & 0 deletions src/tools/registry/gen_inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,7 @@ int push_attributes(ezxml_t currentPosition);
int merge_structs_and_var_arrays(ezxml_t currentPosition);
int merge_streams(ezxml_t registry);
int parse_structs_from_registry(ezxml_t registry);

#ifdef MPAS_CAM_DYCORE
void transform_name(char *new_name, const size_t new_name_size, const char *old_name);
#endif

0 comments on commit 183fed2

Please sign in to comment.