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 // ***********************************************************************
4 //
5 // Teuchos
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 
47 
49 #include <Teuchos_ScalarTraits.hpp>
54 #include <Teuchos_RCP.hpp>
55 #include <Teuchos_Exceptions.hpp>
56 #include <Teuchos_TwoDArray.hpp>
57 
58 #include <Teuchos_Parser.hpp>
59 
61 using Teuchos::RCP;
62 
63 namespace TeuchosTests
64 {
65  TEUCHOS_UNIT_TEST(YAML, XmlEquivalence)
66  {
67  using std::string;
68  using std::vector;
69  vector<string> matchStems;
70  matchStems.push_back("Match1");
71  matchStems.push_back("Match2");
72  matchStems.push_back("Match3");
73  matchStems.push_back("Match4");
74  for(size_t i = 0; i < matchStems.size(); i++)
75  {
76  string yamlFile = matchStems[i] + ".yaml";
78  string xmlFile = matchStems[i] + ".xml";
79  RCP<ParameterList> xmlList = Teuchos::getParametersFromXmlFile(xmlFile);
80  TEST_EQUALITY(Teuchos::haveSameValues(*xmlList, *yamlList, true), true);
81  }
82  }
83  TEUCHOS_UNIT_TEST(YAML, IntVsDouble)
84  {
85  //YAML2 has a double param that has the same name/value as an int param in XML2
86  //YAML reader should recognize the double and the param lists should not be equivalent
87  RCP<ParameterList> xmlList = Teuchos::getParametersFromXmlFile("IntVsDouble.xml");
88  RCP<ParameterList> yamlList = Teuchos::getParametersFromYamlFile("IntVsDouble.yaml");
89  TEST_EQUALITY(Teuchos::haveSameValues(*xmlList, *yamlList), false);
90  }
91  TEUCHOS_UNIT_TEST(YAML, IllegalKeyString)
92  {
93  TEST_THROW(Teuchos::getParametersFromYamlFile("IllegalKeyString.yaml");, Teuchos::ParserFail);
94  }
95 
96  TEUCHOS_UNIT_TEST(YAML, Issue1801)
97  {
99  "My Awesome Problem:\n"
100  " Particle Periodic:\n"
101  " X: \"-1.0, 1.0\"\n"
102  " emotions: happy_sad, indifferent\n"
103  "...\n"
104  );
105  }
106 
107  TEUCHOS_UNIT_TEST(YAML, PR1805) // "\t" has been removed since yaml does not support tabs
108  {
110  "My Awesome Problem:\n"
111  " Mesh:\n"
112  " Inline:\n"
113  " Type: Quad\n"
114  " Elements: [ 10, 10 ]\n"
115  "...\n"
116  );
117  }
118 
119  TEUCHOS_UNIT_TEST(YAML, IntAndDoubleArray)
120  {
121  int correctInts[5] = {2, 3, 5, 7, 11};
122  //the last number with 10 dec digits of precision should test correct double conversion
123  double correctDoubles[5] = {2.718, 3.14159, 1.618, 1.23456789, 42.1337};
125  //Retrieve arrays from a specific sublist (tests the mixed nesting of sequence/map)
126  ParameterList& sublist = params->get<ParameterList>("smoother: params");
127  Teuchos::Array<int>& intArr = sublist.get<Teuchos::Array<int> >("intArray");
128  Teuchos::Array<double>& doubleArr = sublist.get<Teuchos::Array<double> >("doubleArray");
129  TEST_EQUALITY(intArr.size(), 5);
130  TEST_EQUALITY(doubleArr.size(), 5);
131  for(int i = 0; i < 5; i++)
132  {
133  TEST_EQUALITY(correctInts[i], intArr[i]);
134  TEST_EQUALITY(correctDoubles[i], doubleArr[i]);
135  }
136  }
137  TEUCHOS_UNIT_TEST(YAML, InconsistentArrayType)
138  {
139  std::string correctStrings[5] = {"2", "3", "5", "7", "imastring"};
140  double correctDoubles[5] = {2, 3, 1.618, 1.23456789, 42.1337};
141  RCP<ParameterList> plist = Teuchos::getParametersFromYamlFile("InconsistentArray.yaml");
142  //verify that stringArray and doubleArray have the correct types and the correct values
143  const Teuchos::Array<std::string>& stringArr = plist->get<Teuchos::Array<std::string> >("stringArray");
144  const Teuchos::Array<double>& doubleArr = plist->get<Teuchos::Array<double> >("doubleArray");
145  for(int i = 0; i < 5; i++)
146  {
147  if(stringArr[i] != correctStrings[i])
148  {
149  throw std::runtime_error(std::string("stringArray value is incorrect."));
150  }
151  if(doubleArr[i] != correctDoubles[i])
152  {
153  throw std::runtime_error(std::string("doubleArray value is incorrect."));
154  }
155  }
156  }
157  TEUCHOS_UNIT_TEST(YAML, TwoDArrayConvert)
158  {
159  std::string xmlString =
160  " <ParameterList>\n"
161  " <ParameterList name=\"Problem\">\n"
162  " <ParameterList name=\"Neumann BCs\">\n"
163  " <ParameterList name=\"Time Dependent NBC on SS cyl_outside for DOF all set P\">\n"
164  " <Parameter name=\"BC Values\" type=\"TwoDArray(double)\" value=\"3x1:{ 0.0, 10.0, 20.0}\"/>\n"
165  " </ParameterList>\n"
166  " </ParameterList>\n"
167  " </ParameterList>\n"
168  " <ParameterList name=\"Discretization\">\n"
169  " <Parameter name=\"Node Set Associations\" type=\"TwoDArray(string)\" value=\"2x2:{1, 2, top, bottom}\"/>\n"
170  " <Parameter name=\"Bool-looking String\" type=\"string\" value=\"TRUE\" docString=\"my docString\"/>\n"
171  " </ParameterList>\n"
172  " </ParameterList>\n";
173  RCP<ParameterList> xmlParams = Teuchos::getParametersFromXmlString(xmlString);
174  std::stringstream yamlOutStream;
175  yamlOutStream << std::showpoint << std::fixed << std::setprecision(1);
176  Teuchos::YAMLParameterList::writeYamlStream(yamlOutStream, *xmlParams);
177  std::string yamlString = yamlOutStream.str();
178  std::string expectedYamlString =
179  "%YAML 1.1\n"
180  "---\n"
181  "ANONYMOUS:\n"
182  " Problem: \n"
183  " Neumann BCs: \n"
184  " Time Dependent NBC on SS cyl_outside for DOF all set P: \n"
185  " BC Values: [[0.0], [10.0], [20.0]]\n"
186  " Discretization: \n"
187  " Node Set Associations: [['1', '2'], [top, bottom]]\n"
188  " Bool-looking String: 'TRUE'\n"
189  "...\n";
190  TEST_EQUALITY(yamlString, expectedYamlString);
191  std::stringstream yamlInStream(yamlString);
192  RCP<ParameterList> yamlParams;
193  yamlParams = Teuchos::YAMLParameterList::parseYamlStream(yamlInStream);
194  std::stringstream yamlOutStream2;
195  yamlOutStream2 << std::showpoint << std::fixed << std::setprecision(1);
196  Teuchos::YAMLParameterList::writeYamlStream(yamlOutStream2, *yamlParams);
197  std::string yamlString2 = yamlOutStream2.str();
198  TEST_EQUALITY(yamlString2, expectedYamlString);
199  }
200 
201  TEUCHOS_UNIT_TEST(YAML, Issue1815)
202  {
204  "Header:\n"
205  " Output:\n"
206  " File Name: electrostatic.exo\n"
207  " Cell Average Quantities:\n"
208  " eblock-0_0: ES_POTENTIAL, E0\n"
209  " \n"
210  " Particle Dump:\n"
211  " File Name: beam_emit2.h5part\n");
212  }
213 
214  TEUCHOS_UNIT_TEST(YAML, Issue1807part2)
215  {
217  "Header:\n"
218  " Particle Dump:\n"
219  " File Name: beam_emit2.h5part\n"
220  "# Stride Time: 5.0e-12\n");
221  }
222 
223  TEUCHOS_UNIT_TEST(YAML, Issue2090)
224  {
226  "Parameter List:\n"
227  " Boundary Conditions:\n"
228  " Bottom:\n"
229  " Dirichlet:\n"
230  " Sideset: bottom\n"
231  " Field: ES_POTENTIAL\n"
232  " Value: |\n"
233  " double r_sq = xin*xin+yin*yin;\n"
234  " double factor = 0.5*1.e8*1.60217662e-19/(2*3.14159265358979323846*8.854187817e-12);\n"
235  " ES_POTENTIAL= factor*log(r_sq) +3*xin-3*yin;\n"
236  " # end Boundary Conditions\n");
238  Teuchos::getParameter<std::string>(
239  params->sublist("Boundary Conditions", true)
240  .sublist("Bottom", true)
241  .sublist("Dirichlet", true)
242  ,"Value"),
243  "double r_sq = xin*xin+yin*yin;\n"
244  "double factor = 0.5*1.e8*1.60217662e-19/(2*3.14159265358979323846*8.854187817e-12);\n"
245  "ES_POTENTIAL= factor*log(r_sq) +3*xin-3*yin;\n");
246  }
247 
248  TEUCHOS_UNIT_TEST(YAML, Issue2306)
249  {
250  // ensure that duplicate names throw an exception
252  "Foo:\n"
253  " Bar:\n"
254  " Value: 1\n"
255  " Bar:\n"
256  " Value: 2\n"),
257  Teuchos::ParserFail);
258  }
259 
260  TEUCHOS_UNIT_TEST(YAML, keep_top_name)
261  {
263  char const * const cstr =
264  "%YAML 1.1\n"
265  "---\n"
266  "Albany:\n"
267  " some param: 5\n"
268  "...\n";
269  Teuchos::updateParametersFromYamlCString(cstr, Teuchos::ptr(&pl), true);
270  std::stringstream ss;
271  ss << std::showpoint;
273  auto s = ss.str();
274  TEST_EQUALITY(s, cstr);
275  }
276 
277  TEUCHOS_UNIT_TEST(YAML, long_long_param)
278  {
280  "List:\n"
281  " small number: 54\n"
282  " small double: 3.0\n"
283  " scientific: 3.123e02\n"
284  " big number: 72057594037927936\n"
285  );
286  TEST_EQUALITY(pl->isType<int>("small number"), true);
287  TEST_EQUALITY(pl->isType<double>("small double"), true);
288  TEST_EQUALITY(pl->isType<double>("scientific"), true);
289  TEST_EQUALITY(pl->isType<long long>("big number"), true);
290  TEST_EQUALITY(pl->get<long long>("big number"), 72057594037927936ll);
291  }
292 
293  TEUCHOS_UNIT_TEST(YAML, bools)
294  {
296  "List:\n"
297  " input_true: true\n"
298  " input_false: false\n"
299  " input_TRUE: TRUE\n"
300  " input_FALSE: FALSE\n"
301  " input_True: True\n"
302  " input_False: False\n"
303  " input_yes: yes\n"
304  " input_no: no\n"
305  );
306  TEST_EQUALITY(pl->isType<bool>("input_true"), true);
307  TEST_EQUALITY(pl->isType<bool>("input_false"), true);
308  TEST_EQUALITY(pl->isType<bool>("input_yes"), true);
309  TEST_EQUALITY(pl->isType<bool>("input_no"), true);
310  TEST_EQUALITY(pl->isType<bool>("input_TRUE"), true);
311  TEST_EQUALITY(pl->isType<bool>("input_True"), true);
312  TEST_EQUALITY(pl->isType<bool>("input_FALSE"), true);
313  TEST_EQUALITY(pl->isType<bool>("input_False"), true);
314  TEST_EQUALITY(pl->get<bool>("input_true"), true);
315  TEST_EQUALITY(pl->get<bool>("input_false"), false);
316  TEST_EQUALITY(pl->get<bool>("input_yes"), true);
317  TEST_EQUALITY(pl->get<bool>("input_no"), false);
318  TEST_EQUALITY(pl->get<bool>("input_TRUE"), true);
319  TEST_EQUALITY(pl->get<bool>("input_True"), true);
320  TEST_EQUALITY(pl->get<bool>("input_FALSE"), false);
321  TEST_EQUALITY(pl->get<bool>("input_False"), false);
322  }
323 
324  TEUCHOS_UNIT_TEST(YAML, flow_map)
325  {
327  "List:\n"
328  " Fields: {rho: 0.125, px: 0., py: 0., pz: 0., rho_E: 0.25}\n");
329  auto& field_pl = pl->sublist("Fields");
330  TEST_EQUALITY(field_pl.get<double>("rho"), 0.125);
331  }
332 
333  TEUCHOS_UNIT_TEST(YAML, root_name)
334  {
337  "mycode:\n"
338  " sublist:\n"
339  " param1: foo\n",
340  Teuchos::ptr(&pl),
341  true,
342  "root_name test"
343  );
344  auto& sublist = pl.sublist("sublist");
345  TEST_EQUALITY(sublist.name(), "mycode->sublist");
346  }
347 
348  TEUCHOS_UNIT_TEST(YAML, null_node)
349  {
351  "mycode:\n"
352  " empty_node:\n"
353  );
354  TEST_EQUALITY(pl->isSublist("empty_node"), true);
355  }
356 
357 #ifdef HAVE_TEUCHOSPARAMETERLIST_YAMLCPP
358  TEUCHOS_UNIT_TEST(YAML, yamlcpp_parser)
359  {
361  "mycode:\n"
362  " list_of_2d_arrays:\n"
363  " - [[1,2,3], [4,5,6]]\n"
364  " - [[7,8,9], [10,11,12]]\n"
365  " ragged_array:\n"
366  " - [1,2,3]\n"
367  " - [1,2,3,4]\n"
368  " line_continuation: [\n"
369  " 1,2,3,\n"
370  " 4,5,6\n"
371  " ]\n"
372  " # allow unicode comments: ±\n"
373  );
374 
376  threeDarr_t& list_of_arrs = pl->get<threeDarr_t>("list_of_2d_arrays");
377  threeDarr_t correct_list_of_arrs = {
378  {{1, 2, 3}, {4, 5, 6}},
379  {{7, 8, 9}, {10, 11, 12}}
380  };
381  for (int i=0; i<list_of_arrs.size(); i++) {
382  for (int j=0; j<list_of_arrs[i].size(); j++) {
383  for (int k=0; k<list_of_arrs[i][j].size(); k++) {
384  TEST_EQUALITY(correct_list_of_arrs[i][j][k], list_of_arrs[i][j][k]);
385  }
386  }
387  }
388 
389  using twoDarr_t = Teuchos::Array<Teuchos::Array<int>>;
390  twoDarr_t ragged_arr = pl->get<twoDarr_t>("ragged_array");
391  twoDarr_t correct_ragged_arr = {
392  {1, 2, 3},
393  {1, 2, 3, 4}
394  };
395  for (int i=0; i<ragged_arr.size(); i++) {
396  for (int j=0; j<ragged_arr[i].size(); j++) {
397  TEST_EQUALITY(correct_ragged_arr[i][j], ragged_arr[i][j]);
398  }
399  }
400 
401  using arr_t = Teuchos::Array<int>;
402  arr_t arr = pl->get<arr_t>("line_continuation");
403  arr_t correct_arr = {1, 2, 3, 4, 5, 6};
404  for (int i=0; i<arr.size(); i++) {
405  TEST_EQUALITY(correct_arr[i], arr[i]);
406  }
407  }
408 
409  TEUCHOS_UNIT_TEST(YAML, yaml_throws)
410  {
412  "Foo:\n"
413  " [60,2,3]: 1\n"),
414  Teuchos::YamlKeyError)
416  "Foo:\n"
417  " Array:\n"
418  " - 1.3e0.2\n"
419  " - [1,2,3]"),
420  Teuchos::YamlSequenceError)
422  "Foo: 1\n"),
423  Teuchos::YamlStructureError)
424  }
425  // It is not clear how to test Teuchos::YamlUndefinedNode, but the throw
426  // is left in the source code to protect against any unforeseen cases.
427 
428 #endif // HAVE_TEUCHOSPARAMETERLIST_YAMLCPP
429 
430 } //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.