Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
YamlParameterList.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Teuchos: Common Tools Package
4 //
5 // Copyright 2004 NTESS and the Teuchos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
11 #include <Teuchos_ScalarTraits.hpp>
16 #include <Teuchos_RCP.hpp>
17 #include <Teuchos_Exceptions.hpp>
18 #include <Teuchos_TwoDArray.hpp>
19 
20 #include <Teuchos_Parser.hpp>
21 
23 using Teuchos::RCP;
24 
25 namespace TeuchosTests
26 {
27  TEUCHOS_UNIT_TEST(YAML, XmlEquivalence)
28  {
29  using std::string;
30  using std::vector;
31  vector<string> matchStems;
32  matchStems.push_back("Match1");
33  matchStems.push_back("Match2");
34  matchStems.push_back("Match3");
35  matchStems.push_back("Match4");
36  for(size_t i = 0; i < matchStems.size(); i++)
37  {
38  string yamlFile = matchStems[i] + ".yaml";
40  string xmlFile = matchStems[i] + ".xml";
41  RCP<ParameterList> xmlList = Teuchos::getParametersFromXmlFile(xmlFile);
42  TEST_EQUALITY(Teuchos::haveSameValues(*xmlList, *yamlList, true), true);
43  }
44  }
45  TEUCHOS_UNIT_TEST(YAML, IntVsDouble)
46  {
47  //YAML2 has a double param that has the same name/value as an int param in XML2
48  //YAML reader should recognize the double and the param lists should not be equivalent
49  RCP<ParameterList> xmlList = Teuchos::getParametersFromXmlFile("IntVsDouble.xml");
50  RCP<ParameterList> yamlList = Teuchos::getParametersFromYamlFile("IntVsDouble.yaml");
51  TEST_EQUALITY(Teuchos::haveSameValues(*xmlList, *yamlList), false);
52  }
53  TEUCHOS_UNIT_TEST(YAML, IllegalKeyString)
54  {
55  TEST_THROW(Teuchos::getParametersFromYamlFile("IllegalKeyString.yaml");, Teuchos::ParserFail);
56  }
57 
58  TEUCHOS_UNIT_TEST(YAML, Issue1801)
59  {
61  "My Awesome Problem:\n"
62  " Particle Periodic:\n"
63  " X: \"-1.0, 1.0\"\n"
64  " emotions: happy_sad, indifferent\n"
65  "...\n"
66  );
67  }
68 
69  TEUCHOS_UNIT_TEST(YAML, PR1805) // "\t" has been removed since yaml does not support tabs
70  {
72  "My Awesome Problem:\n"
73  " Mesh:\n"
74  " Inline:\n"
75  " Type: Quad\n"
76  " Elements: [ 10, 10 ]\n"
77  "...\n"
78  );
79  }
80 
81  TEUCHOS_UNIT_TEST(YAML, IntAndDoubleArray)
82  {
83  int correctInts[5] = {2, 3, 5, 7, 11};
84  //the last number with 10 dec digits of precision should test correct double conversion
85  double correctDoubles[5] = {2.718, 3.14159, 1.618, 1.23456789, 42.1337};
87  //Retrieve arrays from a specific sublist (tests the mixed nesting of sequence/map)
88  ParameterList& sublist = params->get<ParameterList>("smoother: params");
89  Teuchos::Array<int>& intArr = sublist.get<Teuchos::Array<int> >("intArray");
90  Teuchos::Array<double>& doubleArr = sublist.get<Teuchos::Array<double> >("doubleArray");
91  TEST_EQUALITY(intArr.size(), 5);
92  TEST_EQUALITY(doubleArr.size(), 5);
93  for(int i = 0; i < 5; i++)
94  {
95  TEST_EQUALITY(correctInts[i], intArr[i]);
96  TEST_EQUALITY(correctDoubles[i], doubleArr[i]);
97  }
98  }
99  TEUCHOS_UNIT_TEST(YAML, InconsistentArrayType)
100  {
101  std::string correctStrings[5] = {"2", "3", "5", "7", "imastring"};
102  double correctDoubles[5] = {2, 3, 1.618, 1.23456789, 42.1337};
103  RCP<ParameterList> plist = Teuchos::getParametersFromYamlFile("InconsistentArray.yaml");
104  //verify that stringArray and doubleArray have the correct types and the correct values
105  const Teuchos::Array<std::string>& stringArr = plist->get<Teuchos::Array<std::string> >("stringArray");
106  const Teuchos::Array<double>& doubleArr = plist->get<Teuchos::Array<double> >("doubleArray");
107  for(int i = 0; i < 5; i++)
108  {
109  if(stringArr[i] != correctStrings[i])
110  {
111  throw std::runtime_error(std::string("stringArray value is incorrect."));
112  }
113  if(doubleArr[i] != correctDoubles[i])
114  {
115  throw std::runtime_error(std::string("doubleArray value is incorrect."));
116  }
117  }
118  }
119  TEUCHOS_UNIT_TEST(YAML, TwoDArrayConvert)
120  {
121  std::string xmlString =
122  " <ParameterList>\n"
123  " <ParameterList name=\"Problem\">\n"
124  " <ParameterList name=\"Neumann BCs\">\n"
125  " <ParameterList name=\"Time Dependent NBC on SS cyl_outside for DOF all set P\">\n"
126  " <Parameter name=\"BC Values\" type=\"TwoDArray(double)\" value=\"3x1:{ 0.0, 10.0, 20.0}\"/>\n"
127  " </ParameterList>\n"
128  " </ParameterList>\n"
129  " </ParameterList>\n"
130  " <ParameterList name=\"Discretization\">\n"
131  " <Parameter name=\"Node Set Associations\" type=\"TwoDArray(string)\" value=\"2x2:{1, 2, top, bottom}\"/>\n"
132  " <Parameter name=\"Bool-looking String\" type=\"string\" value=\"TRUE\" docString=\"my docString\"/>\n"
133  " </ParameterList>\n"
134  " </ParameterList>\n";
135  RCP<ParameterList> xmlParams = Teuchos::getParametersFromXmlString(xmlString);
136  std::stringstream yamlOutStream;
137  yamlOutStream << std::showpoint << std::fixed << std::setprecision(1);
138  Teuchos::YAMLParameterList::writeYamlStream(yamlOutStream, *xmlParams);
139  std::string yamlString = yamlOutStream.str();
140  std::string expectedYamlString =
141  "%YAML 1.1\n"
142  "---\n"
143  "ANONYMOUS:\n"
144  " Problem: \n"
145  " Neumann BCs: \n"
146  " Time Dependent NBC on SS cyl_outside for DOF all set P: \n"
147  " BC Values: [[0.0], [10.0], [20.0]]\n"
148  " Discretization: \n"
149  " Node Set Associations: [['1', '2'], [top, bottom]]\n"
150  " Bool-looking String: 'TRUE'\n"
151  "...\n";
152  TEST_EQUALITY(yamlString, expectedYamlString);
153  std::stringstream yamlInStream(yamlString);
154  RCP<ParameterList> yamlParams;
155  yamlParams = Teuchos::YAMLParameterList::parseYamlStream(yamlInStream);
156  std::stringstream yamlOutStream2;
157  yamlOutStream2 << std::showpoint << std::fixed << std::setprecision(1);
158  Teuchos::YAMLParameterList::writeYamlStream(yamlOutStream2, *yamlParams);
159  std::string yamlString2 = yamlOutStream2.str();
160  TEST_EQUALITY(yamlString2, expectedYamlString);
161  }
162 
163  TEUCHOS_UNIT_TEST(YAML, Issue1815)
164  {
166  "Header:\n"
167  " Output:\n"
168  " File Name: electrostatic.exo\n"
169  " Cell Average Quantities:\n"
170  " eblock-0_0: ES_POTENTIAL, E0\n"
171  " \n"
172  " Particle Dump:\n"
173  " File Name: beam_emit2.h5part\n");
174  }
175 
176  TEUCHOS_UNIT_TEST(YAML, Issue1807part2)
177  {
179  "Header:\n"
180  " Particle Dump:\n"
181  " File Name: beam_emit2.h5part\n"
182  "# Stride Time: 5.0e-12\n");
183  }
184 
185  TEUCHOS_UNIT_TEST(YAML, Issue2090)
186  {
188  "Parameter List:\n"
189  " Boundary Conditions:\n"
190  " Bottom:\n"
191  " Dirichlet:\n"
192  " Sideset: bottom\n"
193  " Field: ES_POTENTIAL\n"
194  " Value: |\n"
195  " double r_sq = xin*xin+yin*yin;\n"
196  " double factor = 0.5*1.e8*1.60217662e-19/(2*3.14159265358979323846*8.854187817e-12);\n"
197  " ES_POTENTIAL= factor*log(r_sq) +3*xin-3*yin;\n"
198  " # end Boundary Conditions\n");
200  Teuchos::getParameter<std::string>(
201  params->sublist("Boundary Conditions", true)
202  .sublist("Bottom", true)
203  .sublist("Dirichlet", true)
204  ,"Value"),
205  "double r_sq = xin*xin+yin*yin;\n"
206  "double factor = 0.5*1.e8*1.60217662e-19/(2*3.14159265358979323846*8.854187817e-12);\n"
207  "ES_POTENTIAL= factor*log(r_sq) +3*xin-3*yin;\n");
208  }
209 
210  TEUCHOS_UNIT_TEST(YAML, Issue2306)
211  {
212  // ensure that duplicate names throw an exception
214  "Foo:\n"
215  " Bar:\n"
216  " Value: 1\n"
217  " Bar:\n"
218  " Value: 2\n"),
219  Teuchos::ParserFail);
220  }
221 
222  TEUCHOS_UNIT_TEST(YAML, keep_top_name)
223  {
225  char const * const cstr =
226  "%YAML 1.1\n"
227  "---\n"
228  "Albany:\n"
229  " some param: 5\n"
230  "...\n";
231  Teuchos::updateParametersFromYamlCString(cstr, Teuchos::ptr(&pl), true);
232  std::stringstream ss;
233  ss << std::showpoint;
235  auto s = ss.str();
236  TEST_EQUALITY(s, cstr);
237  }
238 
239  TEUCHOS_UNIT_TEST(YAML, long_long_param)
240  {
242  "List:\n"
243  " small number: 54\n"
244  " small double: 3.0\n"
245  " scientific: 3.123e02\n"
246  " big number: 72057594037927936\n"
247  );
248  TEST_EQUALITY(pl->isType<int>("small number"), true);
249  TEST_EQUALITY(pl->isType<double>("small double"), true);
250  TEST_EQUALITY(pl->isType<double>("scientific"), true);
251  TEST_EQUALITY(pl->isType<long long>("big number"), true);
252  TEST_EQUALITY(pl->get<long long>("big number"), 72057594037927936ll);
253  }
254 
255  TEUCHOS_UNIT_TEST(YAML, bools)
256  {
258  "List:\n"
259  " input_true: true\n"
260  " input_false: false\n"
261  " input_TRUE: TRUE\n"
262  " input_FALSE: FALSE\n"
263  " input_True: True\n"
264  " input_False: False\n"
265  " input_yes: yes\n"
266  " input_no: no\n"
267  );
268  TEST_EQUALITY(pl->isType<bool>("input_true"), true);
269  TEST_EQUALITY(pl->isType<bool>("input_false"), true);
270  TEST_EQUALITY(pl->isType<bool>("input_yes"), true);
271  TEST_EQUALITY(pl->isType<bool>("input_no"), true);
272  TEST_EQUALITY(pl->isType<bool>("input_TRUE"), true);
273  TEST_EQUALITY(pl->isType<bool>("input_True"), true);
274  TEST_EQUALITY(pl->isType<bool>("input_FALSE"), true);
275  TEST_EQUALITY(pl->isType<bool>("input_False"), true);
276  TEST_EQUALITY(pl->get<bool>("input_true"), true);
277  TEST_EQUALITY(pl->get<bool>("input_false"), false);
278  TEST_EQUALITY(pl->get<bool>("input_yes"), true);
279  TEST_EQUALITY(pl->get<bool>("input_no"), false);
280  TEST_EQUALITY(pl->get<bool>("input_TRUE"), true);
281  TEST_EQUALITY(pl->get<bool>("input_True"), true);
282  TEST_EQUALITY(pl->get<bool>("input_FALSE"), false);
283  TEST_EQUALITY(pl->get<bool>("input_False"), false);
284  }
285 
286  TEUCHOS_UNIT_TEST(YAML, flow_map)
287  {
289  "List:\n"
290  " Fields: {rho: 0.125, px: 0., py: 0., pz: 0., rho_E: 0.25}\n");
291  auto& field_pl = pl->sublist("Fields");
292  TEST_EQUALITY(field_pl.get<double>("rho"), 0.125);
293  }
294 
295  TEUCHOS_UNIT_TEST(YAML, root_name)
296  {
299  "mycode:\n"
300  " sublist:\n"
301  " param1: foo\n",
302  Teuchos::ptr(&pl),
303  true,
304  "root_name test"
305  );
306  auto& sublist = pl.sublist("sublist");
307  TEST_EQUALITY(sublist.name(), "mycode->sublist");
308  }
309 
310  TEUCHOS_UNIT_TEST(YAML, null_node)
311  {
313  "mycode:\n"
314  " empty_node:\n"
315  );
316  TEST_EQUALITY(pl->isSublist("empty_node"), true);
317  }
318 
319 #ifdef HAVE_TEUCHOSPARAMETERLIST_YAMLCPP
320  TEUCHOS_UNIT_TEST(YAML, yamlcpp_parser)
321  {
323  "mycode:\n"
324  " list_of_2d_arrays:\n"
325  " - [[1,2,3], [4,5,6]]\n"
326  " - [[7,8,9], [10,11,12]]\n"
327  " ragged_array:\n"
328  " - [1,2,3]\n"
329  " - [1,2,3,4]\n"
330  " line_continuation: [\n"
331  " 1,2,3,\n"
332  " 4,5,6\n"
333  " ]\n"
334  " # allow unicode comments: ±\n"
335  );
336 
338  threeDarr_t& list_of_arrs = pl->get<threeDarr_t>("list_of_2d_arrays");
339  threeDarr_t correct_list_of_arrs = {
340  {{1, 2, 3}, {4, 5, 6}},
341  {{7, 8, 9}, {10, 11, 12}}
342  };
343  for (int i=0; i<list_of_arrs.size(); i++) {
344  for (int j=0; j<list_of_arrs[i].size(); j++) {
345  for (int k=0; k<list_of_arrs[i][j].size(); k++) {
346  TEST_EQUALITY(correct_list_of_arrs[i][j][k], list_of_arrs[i][j][k]);
347  }
348  }
349  }
350 
351  using twoDarr_t = Teuchos::Array<Teuchos::Array<int>>;
352  twoDarr_t ragged_arr = pl->get<twoDarr_t>("ragged_array");
353  twoDarr_t correct_ragged_arr = {
354  {1, 2, 3},
355  {1, 2, 3, 4}
356  };
357  for (int i=0; i<ragged_arr.size(); i++) {
358  for (int j=0; j<ragged_arr[i].size(); j++) {
359  TEST_EQUALITY(correct_ragged_arr[i][j], ragged_arr[i][j]);
360  }
361  }
362 
363  using arr_t = Teuchos::Array<int>;
364  arr_t arr = pl->get<arr_t>("line_continuation");
365  arr_t correct_arr = {1, 2, 3, 4, 5, 6};
366  for (int i=0; i<arr.size(); i++) {
367  TEST_EQUALITY(correct_arr[i], arr[i]);
368  }
369  }
370 
371  TEUCHOS_UNIT_TEST(YAML, yaml_throws)
372  {
374  "Foo:\n"
375  " [60,2,3]: 1\n"),
376  Teuchos::YamlKeyError)
378  "Foo:\n"
379  " Array:\n"
380  " - 1.3e0.2\n"
381  " - [1,2,3]"),
382  Teuchos::YamlSequenceError)
384  "Foo: 1\n"),
385  Teuchos::YamlStructureError)
386  }
387  // It is not clear how to test Teuchos::YamlUndefinedNode, but the throw
388  // is left in the source code to protect against any unforeseen cases.
389 
390 #endif // HAVE_TEUCHOSPARAMETERLIST_YAMLCPP
391 
392 } //namespace TeuchosTests
A thin wrapper around the Teuchos Array class that allows for 2 dimensional arrays.
Teuchos::RCP< Teuchos::ParameterList > parseYamlStream(std::istream &yaml)
Functions to convert between ParameterList and YAML.
TEUCHOSPARAMETERLIST_LIB_DLL_EXPORT void updateParametersFromYamlCString(const char *const data, const Teuchos::Ptr< Teuchos::ParameterList > &paramList, bool overwrite)
void writeParameterListToYamlOStream(const ParameterList &paramList, std::ostream &yamlOut)
T & get(const std::string &name, T def_value)
Return the parameter&#39;s value, or the default value if it is not there.
#define TEST_EQUALITY(v1, v2)
Assert the equality of v1 and v2.
#define TEST_THROW(code, ExceptType)
Assert that the statement &#39;code&#39; throws the exception &#39;ExceptType&#39; (otherwise the test fails)...
Teuchos::RCP< Teuchos::ParameterList > getParametersFromYamlString(const std::string &yamlStr)
Simple helper functions that make it easy to read and write XML to and from a parameterlist.
Templated Parameter List class.
bool isSublist(const std::string &name) const
Whether the given sublist exists in this list.
Unit testing support.
A list of parameters of arbitrary type.
void updateParametersFromYamlString(const std::string &yamlData, const Teuchos::Ptr< Teuchos::ParameterList > &paramList, bool overwrite, const std::string &name)
TEUCHOS_UNIT_TEST(YAML, XmlEquivalence)
size_type size() const
Defines basic traits for the scalar field type.
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
Creates an empty sublist and returns a reference to the sublist name. If the list already exists...
Smart reference counting pointer class for automatic garbage collection.
Teuchos::RCP< Teuchos::ParameterList > getParametersFromYamlFile(const std::string &yamlFileName)
void writeYamlStream(std::ostream &yaml, const Teuchos::ParameterList &pl)
Simple helper functions that make it easy to read and write Yaml to and from a parameterlist.
Reference-counted pointer class and non-member templated function implementations.