lower_bounds, upper_bounds and initial_point. Ambiguities are resolved by attaching a keyword to the most recently seen context in which it could appear, if such exists, or to the first relevant context that subsequently comes along in the input file. With the earlier IDR parser, non-exclusive specifications (those not in mutually exclusive blocks) were required to be unique. That is why there are such aliases for initial_point as cdv_initial_point and ddv_initial_point.cd Dakota/packages/nidr make
These steps regenerate NIDR_keywds.H and dakota.input.txt in the Dakota/src directory. As described in more detail in the next section, you must manually update NIDRProblemDescDB.C in Dakota/src to accord with changes to dakota.input.nspec. If you commit changes to a source repository, be sure to commit the updated Dakota/src/NIDR_keywds.H, Dakota/src/dakota.input.nspec, Dakota/src/dakota.input.txt, and your manually updated Dakota/src/NIDRProblemDescDB.C.
{ startfcn, startdata, stopfcn, stopdata }
i.e., a brace-enclosed list of one to four functions and data pointers, with trailing entities taken to be zero if not present; zero for a function means no function will be called. The startfcn must deal with any associated data. Otherwise, the distinction between startfcn and stopfcn is relevant only to keywords that begin a group of keywords (enclosed in parentheses or square brackets). The startfcn is called before other entities in the group are processed, and the stop function is called after they are processed. Top-level keywords often have both startfcn and stopfcn; stopfcn is uncommon but possible for lower-level keywords. The startdata and (if needed) stopdata values are usually pointers to little structures that provide keyword-specific details to generic functions for startfcn and stopfcn. Some keywords that begin groups (such as "approx_problem" within the top-level "strategy" keyword) have no need of either a startfcn or a stopfcn; this is indicated by "{0}".
Most of the things within braces in dakota.input.nspec are invocations of macros defined in NIDRProblemDescDB.C. The macros simplify writing dakota.input.nspec and make it more readable. Most macro invocations refer to little structures defined in NIDRProblemDescDB.C, usually with the help of other macros, some of which have different definitions in different parts of NIDRProblemDescDB.C. When adding a keyword to dakota.input.nspec, you may need to add a structure definition or even introduce a new data type. NIDRProblemDescDB.C has sections corresponding to each top-level keyword. The top-level keywords are in alphabetical order, and most entites in the section for a top-level keyword are also in alphabetical order. While not required, it is probably good practice to maintain this structure, as it makes things easier to find.
Any integer, real, or string data associated with a keyword are provided to the keyword's startfcn, whose second argument is a pointer to a Values structure, defined in header file nidr.h.
Example 1: if you added the specification:
[method_setting REAL {method_setting_start, &method_setting_details} ]
void NIDRProblemDescDB:: method_setting_start(const char *keyname, Values *val, void **g, void *v) { ... }
&method_setting_details would be passed as v, val->n (the number of values) would be 1 and *val->r would be the REAL value given for the method_setting keyword. The method_setting_start function would suitably store this value with the help of method_setting_details.
For some top-level keywords, g (the third argument to the startfcn and stopfcn) provides access to a relevant context. For example, method_start (the startfcn for the top-level method keyword) executes
DataMethod *dm = new DataMethod; *g = (void*)dm;
dm). The start functions for lower-level keywords within the method keyword get access to dm through their g arguments. Here is an example: void NIDRProblemDescDB:: method_str(const char *keyname, Values *val, void **g, void *v) { (*(DataMethod**)g)->**(String DataMethod::**)v = *val->s; }
v is a pointer-to-member, and an assignment is made to one of the components of the DataMethod object pointed to by *g. The corresponding stopfcn for the top-level method keyword is void NIDRProblemDescDB:: method_stop(const char *keyname, Values *val, void **g, void *v) { DataMethod *p = *(DataMethod**)g; pDDBInstance->dataMethodList.insert(*p); delete p; }
Example 2: if you added the specification
[method_setting REALLIST {{N_mdm(RealL,methodCoeffs)}
RealL into NIDRProblemDescDB::method_RealL. This function is used to process lists of REAL values for several keywords. By looking at the source, you can see that the list values are val->r[i] for 0 <= i < val->n.const RealVector& get_drv(const String& entry_name);
if (entry_name == "variables.continuous_design.initial_point") return dbRep->dataVariablesIter->continuousDesignVars;
continuousDesignVars attribute from a DataVariables object. Since there may be multiple variables specifications, the dataVariablesIter list iterator identifies which node in the list of DataVariables objects is used. In particular, dataVariablesList contains a list of all of the data_variables objects, one for each time variables_kwhandler() has been called by the parser. The particular variables object used for the data retrieval is managed by dataVariablesIter, which is set in a set_db_list_nodes() operation that will not be described here.There may be multiple DataMethod, DataModel, DataVariables, DataInterface, and/or DataResponses objects. However, only one strategy specification is currently allowed so a list of DataStrategy objects is not needed. Rather, ProblemDescDB::strategySpec is the lone DataStrategy object.
To augment the get_<data_type>() functions, add else blocks with new identifier strings which retrieve the appropriate data attributes from the Data class object. The style for the identifier strings is a top-down hierarchical description, with specification levels separated by periods and words separated with underscores, e.g. "keyword.group_specification.individual_specification". Use the dbRep->listIter->attribute syntax for variables, interface, responses, and method specifications. For example, the method_setting example attribute would be added to get_drv() as:
else if (entry_name == "method.method_name.method_setting") return dbRep->dataMethodIter->methodSetting;
A strategy specification addition would not use a list iterator, and would instead look like:
else if (entry_name == "strategy.strategy_name.strategy_setting") return dbRep->strategySpec.strategySetting;
const String& interface_type = problem_db.get_string("interface.type");
"interface.type" identifier string to the ProblemDescDB::get_string() retrieval function, which returns the desired attribute from the active DataInterface object.
dataMethodIter, dataModelIter, dataVariablesIter, dataInterfaceIter, and dataResponsesIter) guaranteed to be set correctly. Outside of the constructors, the database list nodes will correspond to the last set operation, and may not return data from the desired list node.
1.5.1