parametersystem.hh
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*
4  Copyright (C) 2011-2013 by Andreas Lauser
5 
6  This file is part of the Open Porous Media project (OPM).
7 
8  OPM is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 2 of the License, or
11  (at your option) any later version.
12 
13  OPM is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with OPM. If not, see <http://www.gnu.org/licenses/>.
20 */
30 #ifndef EWOMS_PARAMETERS_HH
31 #define EWOMS_PARAMETERS_HH
32 
34 #include <opm/common/ErrorMacros.hpp>
35 #include <opm/common/Exceptions.hpp>
36 #include <opm/material/common/ClassName.hpp>
37 
38 #include <dune/common/parametertree.hh>
39 
40 #include <map>
41 #include <list>
42 #include <sstream>
43 #include <string>
44 #include <iostream>
45 #include <unordered_map>
46 
64 #define EWOMS_REGISTER_PARAM(TypeTag, ParamType, ParamName, Description) \
65  ::Ewoms::Parameters::registerParam<TypeTag, ParamType, PTAG(ParamName)>( \
66  #ParamName, #ParamName, Description)
67 
77 #define EWOMS_END_PARAM_REGISTRATION(TypeTag) \
78  ::Ewoms::Parameters::endParamRegistration<TypeTag>()
79 
95 #define EWOMS_GET_PARAM(TypeTag, ParamType, ParamName) \
96  (::Ewoms::Parameters::get<TypeTag, ParamType, PTAG(ParamName)>(#ParamName, \
97  #ParamName))
98 
100 #define EWOMS_GET_PARAM_(TypeTag, ParamType, ParamName) \
101  (::Ewoms::Parameters::get<TypeTag, ParamType, PTAG(ParamName)>( \
102  #ParamName, #ParamName, \
103  /*errorIfNotRegistered=*/false))
104 
105 namespace Ewoms {
106 namespace Parameters {
107 
108 struct ParamInfo
109 {
110  std::string paramName;
111  std::string paramTypeName;
112  std::string typeTagName;
113  std::string propertyName;
114  std::string usageString;
115  std::string compileTimeValue;
116 
117  bool operator==(const ParamInfo &other) const
118  {
119  return other.paramName == paramName
120  && other.paramTypeName == paramTypeName
121  && other.typeTagName == typeTagName
122  && other.propertyName == propertyName
123  && other.usageString == usageString
124  && other.compileTimeValue == compileTimeValue;
125  }
126 };
127 
128 // forward declaration
129 template <class TypeTag, class ParamType, class PropTag>
130 const ParamType &get(const char *propTagName, const char *paramName,
131  bool errorIfNotRegistered = true);
132 
133 class ParamRegFinalizerBase_
134 {
135 public:
136  virtual ~ParamRegFinalizerBase_()
137  {}
138  virtual void retrieve() = 0;
139 };
140 
141 template <class TypeTag, class ParamType, class PropTag>
142 class ParamRegFinalizer_ : public ParamRegFinalizerBase_
143 {
144 public:
145  ParamRegFinalizer_(const std::string &paramName) : paramName_(paramName)
146  {}
147 
148  void retrieve()
149  {
150  // retrieve the parameter once to make sure that its value does
151  // not contain a syntax error.
152  ParamType __attribute__((unused)) dummy =
153  get<TypeTag, ParamType, PropTag>(/*propTagName=*/paramName_.data(),
154  paramName_.data(),
155  /*errorIfNotRegistered=*/true);
156  }
157 
158 private:
159  std::string paramName_;
160 };
161 } // namespace Parameters
162 
163 namespace Properties {
164 // type tag which is supposed to spliced in or inherited from if the
165 // parameter system is to be used
166 NEW_TYPE_TAG(ParameterSystem);
167 
168 NEW_PROP_TAG(ParameterMetaData);
169 NEW_PROP_TAG(ParameterGroupPrefix);
170 NEW_PROP_TAG(Description);
171 
172 
174 SET_PROP(ParameterSystem, ParameterMetaData)
175 {
176  typedef Dune::ParameterTree type;
177 
178  static Dune::ParameterTree &tree()
179  { return storage_().tree; }
180 
181  static std::map<std::string, ::Ewoms::Parameters::ParamInfo> &mutableRegistry()
182  { return storage_().registry; }
183 
184  static const std::map<std::string, ::Ewoms::Parameters::ParamInfo> &registry()
185  { return storage_().registry; }
186 
187  static std::list< ::Ewoms::Parameters::ParamRegFinalizerBase_ *> &
188  registrationFinalizers()
189  { return storage_().finalizers; }
190 
191  static bool &registrationOpen()
192  { return storage_().registrationOpen; }
193 
194 private:
195  // this is not pretty, but handling these attributes as static variables inside
196  // member functions of the ParameterMetaData property class triggers a bug in clang
197  // 3.5's address sanitizer which causes these variables to be initialized multiple
198  // times...
199  struct Storage_ {
200  Storage_()
201  { registrationOpen = true; }
202 
203  Dune::ParameterTree tree;
204  std::map<std::string, ::Ewoms::Parameters::ParamInfo> registry;
205  std::list< ::Ewoms::Parameters::ParamRegFinalizerBase_ *> finalizers;
206  bool registrationOpen;
207  };
208  static Storage_& storage_() {
209  static Storage_ obj;
210  return obj;
211  };
212 };
213 
214 SET_STRING_PROP(ParameterSystem, ParameterGroupPrefix, "");
215 SET_STRING_PROP(ParameterSystem, Description, "");
216 
217 } // namespace Properties
218 
219 namespace Parameters {
220 // function prototype declarations
221 void printParamUsage_(std::ostream &os, const ParamInfo &paramInfo);
222 void getFlattenedKeyList_(std::list<std::string> &dest,
223  const Dune::ParameterTree &tree,
224  const std::string &prefix = "");
225 
226 
227 void printParamUsage_(std::ostream &os, const ParamInfo &paramInfo)
228 {
229  std::string paramMessage, paramType, paramDescription;
230 
231  // convert the CamelCase name to a command line --parameter-name.
232  std::string cmdLineName = "-";
233  const std::string camelCaseName = paramInfo.paramName;
234  for (unsigned i = 0; i < camelCaseName.size(); ++i) {
235  if (isupper(camelCaseName[i]))
236  cmdLineName += "-";
237  cmdLineName += static_cast<char>(std::tolower(camelCaseName[i]));
238  }
239 
240  // assemble the printed output
241  paramMessage = " ";
242  paramMessage += cmdLineName;
243 
244  // add the =VALUE_TYPE part
245  if (paramInfo.paramTypeName == "std::string"
246  || paramInfo.paramTypeName == "const char *")
247  paramMessage += "=STRING";
248  else if (paramInfo.paramTypeName == "float"
249  || paramInfo.paramTypeName == "double"
250  || paramInfo.paramTypeName == "long double"
251  || paramInfo.paramTypeName == "quad")
252  paramMessage += "=SCALAR";
253  else if (paramInfo.paramTypeName == "int"
254  || paramInfo.paramTypeName == "unsigned int"
255  || paramInfo.paramTypeName == "short"
256  || paramInfo.paramTypeName == "unsigned short")
257  paramMessage += "=INTEGER";
258  else if (paramInfo.paramTypeName == "bool")
259  paramMessage += "=BOOLEAN";
260  else if (paramInfo.paramTypeName.empty()) {
261  // the parameter is a flag. Do nothing!
262  }
263  else {
264  // unknown type
265  paramMessage += "=VALUE";
266  }
267 
268  // fill up the up help string to the 50th character
269  paramMessage += " ";
270  while (paramMessage.size() < 50)
271  paramMessage += " ";
272 
273  // append the parameter usage string.
274  paramMessage += paramInfo.usageString;
275  paramMessage += "\n";
276 
277  // print everything
278  os << paramMessage;
279 }
280 
281 void getFlattenedKeyList_(std::list<std::string> &dest,
282  const Dune::ParameterTree &tree,
283  const std::string &prefix)
284 {
285  // add the keys of the current sub-structure
286  auto keyIt = tree.getValueKeys().begin();
287  const auto &keyEndIt = tree.getValueKeys().end();
288  for (; keyIt != keyEndIt; ++keyIt) {
289  std::string newKey(prefix);
290  newKey += *keyIt;
291  dest.push_back(newKey);
292  }
293 
294  // recursively add all substructure keys
295  auto subStructIt = tree.getSubKeys().begin();
296  const auto &subStructEndIt = tree.getSubKeys().end();
297  for (; subStructIt != subStructEndIt; ++subStructIt) {
298  std::string newPrefix(prefix);
299  newPrefix += *subStructIt;
300  newPrefix += ".";
301 
302  getFlattenedKeyList_(dest, tree.sub(*subStructIt), newPrefix);
303  }
304 }
305 
306 // print the values of a list of parameters
307 template <class TypeTag>
308 void printParamList_(std::ostream &os, const std::list<std::string> &keyList)
309 {
310  typedef typename GET_PROP(TypeTag, ParameterMetaData) ParamsMeta;
311 
312  const Dune::ParameterTree &tree = ParamsMeta::tree();
313 
314  auto keyIt = keyList.begin();
315  const auto &keyEndIt = keyList.end();
316  for (; keyIt != keyEndIt; ++keyIt) {
317  std::string value = ParamsMeta::registry().at(*keyIt).compileTimeValue;
318  if (tree.hasKey(*keyIt))
319  value = tree.get(*keyIt, "");
320  os << *keyIt << "=\"" << value << "\"\n";
321  }
322 }
323 
324 // print the values of a list of parameters
325 template <class TypeTag>
326 void printCompileTimeParamList_(std::ostream &os,
327  const std::list<std::string> &keyList)
328 {
329  typedef typename GET_PROP(TypeTag, ParameterMetaData) ParamsMeta;
330 
331  auto keyIt = keyList.begin();
332  const auto &keyEndIt = keyList.end();
333  for (; keyIt != keyEndIt; ++keyIt) {
334  const auto &paramInfo = ParamsMeta::registry().at(*keyIt);
335  os << *keyIt << "=\"" << paramInfo.compileTimeValue
336  << "\" # property: " << paramInfo.propertyName << "\n";
337  }
338 }
339 
341 
349 template <class TypeTag>
350 void printUsage(const std::string &progName, const std::string &errorMsg = "",
351  bool handleHelp = true, std::ostream &os = std::cerr)
352 {
353  typedef typename GET_PROP(TypeTag, ParameterMetaData) ParamsMeta;
354  std::string desc = GET_PROP_VALUE(TypeTag, Description);
355 
356  if (errorMsg != "") {
357  os << errorMsg << "\n"
358  << "\n";
359  }
360 
361  os << "Usage: " << progName << " [OPTIONS]\n";
362  if (desc != "")
363  os << desc << "\n";
364  os << "\n";
365  os << "Recognized options:\n";
366 
367  if (handleHelp) {
368  ParamInfo pInfo;
369  pInfo.paramName = "h,--help";
370  pInfo.usageString = "Print this help message and exit";
371  printParamUsage_(os, pInfo);
372  }
373 
374  auto paramIt = ParamsMeta::registry().begin();
375  const auto &paramEndIt = ParamsMeta::registry().end();
376  for (; paramIt != paramEndIt; ++paramIt) {
377  printParamUsage_(os, paramIt->second);
378  }
379 }
380 
396 template <class TypeTag>
397 std::string parseCommandLineOptions(int argc, char **argv, bool handleHelp = true)
398 {
399  Dune::ParameterTree &paramTree = GET_PROP(TypeTag, ParameterMetaData)::tree();
400 
401  if (handleHelp) {
402  for (int i = 1; i < argc; ++i) {
403  if (std::string("-h") == argv[i]
404  || std::string("--help") == argv[i]) {
405  printUsage<TypeTag>(argv[0], "", handleHelp, std::cout);
406  return "Help called";
407  }
408  }
409  }
410 
411  // All command line options need to start with '-'
412  for (int i = 1; i < argc; ++i) {
413  if (argv[i][0] != '-') {
414  std::ostringstream oss;
415  oss << "Command line argument " << i
416  << " (='" << argv[i] << "') is invalid.";
417 
418  if (handleHelp)
419  printUsage<TypeTag>(argv[0], oss.str(), handleHelp, std::cerr);
420 
421  return oss.str();
422  }
423 
424  std::string paramName, paramValue;
425 
426  // read a --my-opt=abc option. This gets transformed
427  // into the parameter "MyOpt" with the value being
428  // "abc"
429  if (argv[i][1] == '-') {
430  // There is nothing after the '-'
431  if (argv[i][2] == 0 || !std::isalpha(argv[i][2])) {
432  std::ostringstream oss;
433  oss << "Parameter name of argument " << i
434  << " ('" << argv[i] << "') "
435  << "is invalid because it does not start with a letter.";
436 
437  if (handleHelp)
438  printUsage<TypeTag>(argv[0], oss.str(), handleHelp,
439  std::cerr);
440 
441  return oss.str();
442  }
443 
444  // copy everything after the "--" into a separate string
445  std::string s(argv[i] + 2);
446 
447  // parse argument
448  unsigned j = 0;
449  while (true) {
450  if (j >= s.size()) {
451  // encountered the end of the string, i.e. we
452  // have a parameter where the argument is empty
453  paramName = s;
454  paramValue = "";
455  break;
456  }
457  else if (s[j] == '=') {
458  // we encountered a '=' character. everything
459  // before is the name of the parameter,
460  // everything after is the value.
461  paramName = s.substr(0, j);
462  paramValue = s.substr(j + 1);
463  break;
464  }
465  else if (s[j] == '-') {
466  // remove all "-" characters and capitalize the
467  // character after them
468  s.erase(j, 1);
469  if (s.size() == j) {
470  std::ostringstream oss;
471  oss << "Parameter name of argument " << i
472  << " ('" << argv[i] << "')"
473  << " is invalid (ends with a '-' character).";
474 
475  if (handleHelp)
476  printUsage<TypeTag>(argv[0], oss.str(), handleHelp,
477  std::cerr);
478  return oss.str();
479  }
480  else if (s[j] == '-') {
481  std::ostringstream oss;
482  oss << "Malformed parameter name in argument " << i
483  << " ('" << argv[i] << "'): "
484  << "'--' in parameter name.";
485 
486  if (handleHelp)
487  printUsage<TypeTag>(argv[0], oss.str(), handleHelp,
488  std::cerr);
489  return oss.str();
490  }
491  s[j] = static_cast<char>(std::toupper(s[j]));
492  }
493  else if (!std::isalnum(s[j])) {
494  std::ostringstream oss;
495  oss << "Parameter name of argument " << i
496  << " ('" << argv[i] << "')"
497  << " is invalid (character '" << s[j]
498  << "' is not a letter or digit).";
499 
500  if (handleHelp)
501  printUsage<TypeTag>(argv[0], oss.str(), handleHelp,
502  std::cerr);
503  return oss.str();
504  }
505 
506  ++j;
507  }
508  }
509  else {
510  // read a -myOpt abc option for the parameter "MyOpt" with
511  // a value of "abc"
512  paramName = argv[i] + 1;
513 
514  if (argc == i + 1 || argv[i + 1][0] == '-') {
515  std::ostringstream oss;
516  oss << "No argument given for parameter '" << argv[i] << "'!";
517  if (handleHelp)
518  printUsage<TypeTag>(argv[0], oss.str(), handleHelp,
519  std::cerr);
520  return oss.str();
521  }
522 
523  paramValue = argv[i + 1];
524  ++i; // In the case of '-myOpt abc' each pair counts as two arguments
525  }
526 
527  // capitalize first letter of parameter name
528  paramName[0] = static_cast<char>(std::toupper(paramName[0]));
529 
530  // Put the key=value pair into the parameter tree
531  paramTree[paramName] = paramValue;
532  }
533  return "";
534 }
535 
542 template <class TypeTag>
543 void printValues(std::ostream &os = std::cout)
544 {
545  typedef typename GET_PROP(TypeTag, ParameterMetaData) ParamsMeta;
546 
547  const Dune::ParameterTree &tree = ParamsMeta::tree();
548 
549  std::list<std::string> runTimeAllKeyList;
550  std::list<std::string> runTimeKeyList;
551  std::list<std::string> unknownKeyList;
552 
553  getFlattenedKeyList_(runTimeAllKeyList, tree);
554  auto keyIt = runTimeAllKeyList.begin();
555  const auto &keyEndIt = runTimeAllKeyList.end();
556  for (; keyIt != keyEndIt; ++keyIt) {
557  if (ParamsMeta::registry().find(*keyIt) == ParamsMeta::registry().end()) {
558  // key was not registered by the program!
559  unknownKeyList.push_back(*keyIt);
560  }
561  else {
562  // the key was specified at run-time
563  runTimeKeyList.push_back(*keyIt);
564  }
565  }
566 
567  // loop over all registered parameters
568  std::list<std::string> compileTimeKeyList;
569  auto paramInfoIt = ParamsMeta::registry().begin();
570  const auto &paramInfoEndIt = ParamsMeta::registry().end();
571  for (; paramInfoIt != paramInfoEndIt; ++paramInfoIt) {
572  // check whether the key was specified at run-time
573  const auto &keyName = paramInfoIt->first;
574  if (tree.hasKey(keyName))
575  continue;
576  else
577  compileTimeKeyList.push_back(keyName);
578  }
579 
580  // report the values of all registered (and unregistered)
581  // parameters
582  if (runTimeKeyList.size() > 0) {
583  os << "# [known parameters which were specified at run-time]\n";
584  printParamList_<TypeTag>(os, runTimeKeyList);
585  }
586 
587  if (compileTimeKeyList.size() > 0) {
588  os << "# [parameters which were specified at compile-time]\n";
589  printCompileTimeParamList_<TypeTag>(os, compileTimeKeyList);
590  }
591 
592  if (unknownKeyList.size() > 0) {
593  os << "# [unused run-time specified parameters]\n";
594  auto unusedKeyIt = unknownKeyList.begin();
595  const auto &unusedKeyEndIt = unknownKeyList.end();
596  for (; unusedKeyIt != unusedKeyEndIt; ++unusedKeyIt) {
597  os << *unusedKeyIt << "=\"" << tree.get(*unusedKeyIt, "") << "\"\n" << std::flush;
598  }
599  }
600 }
601 
610 template <class TypeTag>
611 bool printUnused(std::ostream &os = std::cout)
612 {
613  typedef typename GET_PROP(TypeTag, ParameterMetaData) ParamsMeta;
614 
615  const Dune::ParameterTree &tree = ParamsMeta::tree();
616  std::list<std::string> runTimeAllKeyList;
617  std::list<std::string> unknownKeyList;
618 
619  getFlattenedKeyList_(runTimeAllKeyList, tree);
620  auto keyIt = runTimeAllKeyList.begin();
621  const auto &keyEndIt = runTimeAllKeyList.end();
622  for (; keyIt != keyEndIt; ++keyIt) {
623  if (ParamsMeta::registry().find(*keyIt) == ParamsMeta::registry().end()) {
624  // key was not registered by the program!
625  unknownKeyList.push_back(*keyIt);
626  }
627  }
628 
629  if (unknownKeyList.size() > 0) {
630  os << "# [unused run-time specified parameters]\n";
631  auto unusedKeyIt = unknownKeyList.begin();
632  const auto &unusedKeyEndIt = unknownKeyList.end();
633  for (; unusedKeyIt != unusedKeyEndIt; ++unusedKeyIt) {
634  os << *unusedKeyIt << "=\"" << tree.get(*unusedKeyIt, "") << "\"\n" << std::flush;
635  }
636  return true;
637  }
638  return false;
639 }
640 
642 template <class TypeTag>
643 class Param
644 {
645  typedef typename GET_PROP(TypeTag, ParameterMetaData) ParamsMeta;
646 
647 public:
648  template <class ParamType, class PropTag>
649  static const ParamType &get(const char *propTagName, const char *paramName,
650  bool errorIfNotRegistered = true)
651  {
652  static const ParamType &value =
653  retrieve_<ParamType, PropTag>(propTagName,
654  paramName,
655  errorIfNotRegistered);
656  return value;
657  }
658 
659 private:
660  struct Blubb
661  {
662  std::string propertyName;
663  std::string paramTypeName;
664  std::string groupName;
665 
666  Blubb &operator=(const Blubb &b)
667  {
668  propertyName = b.propertyName;
669  paramTypeName = b.paramTypeName;
670  groupName = b.groupName;
671  return *this;
672  }
673  };
674 
675  static void check_(const std::string &paramTypeName,
676  const std::string &propertyName, const char *paramName)
677  {
678  typedef std::unordered_map<std::string, Blubb> StaticData;
679  static StaticData staticData;
680 
681  typename StaticData::iterator it = staticData.find(paramName);
682  Blubb *b;
683  if (it == staticData.end()) {
684  Blubb a;
685  a.propertyName = propertyName;
686  a.paramTypeName = paramTypeName;
687  staticData[paramName] = a;
688  b = &staticData[paramName];
689  }
690  else
691  b = &(it->second);
692 
693  if (b->propertyName != propertyName) {
694  OPM_THROW(std::logic_error,
695  "GET_*_PARAM for parameter '" << paramName
696  << "' called for at least two different properties ('"
697  << b->propertyName << "' and '" << propertyName << "')");
698  }
699 
700  if (b->paramTypeName != paramTypeName) {
701  OPM_THROW(std::logic_error,
702  "GET_*_PARAM for parameter '" << paramName
703  << "' called with at least two different types ("
704  << b->paramTypeName << " and " << paramTypeName << ")");
705  }
706  }
707 
708  template <class ParamType, class PropTag>
709  static const ParamType &retrieve_(const char *propTagName,
710  const char *paramName,
711  bool errorIfNotRegistered = true)
712  {
713 #ifndef NDEBUG
714  // make sure that the parameter is used consistently. since
715  // this is potentially quite expensive, it is only done if
716  // debugging code is not explicitly turned off.
717  check_(Opm::className<ParamType>(), propTagName, paramName);
718 #endif
719 
720  typedef typename GET_PROP(TypeTag, ParameterMetaData) ParamsMeta;
721  if (errorIfNotRegistered) {
722  if (ParamsMeta::registrationOpen())
723  OPM_THROW(std::runtime_error, "Parameters can only retieved "
724  "after _all_ of them have been "
725  "registered.");
726 
727  if (ParamsMeta::registry().find(paramName) == ParamsMeta::registry().end())
728  OPM_THROW(std::runtime_error,
729  "Accessing parameter " << paramName
730  << " without prior registration is not allowed.");
731  }
732 
733  // prefix the parameter name by the model's GroupName. E.g. If
734  // the model specifies its group name to be 'Stokes', in an
735  // INI file this would result in something like:
736  //
737  // [Stokes]
738  // NewtonWriteConvergence = true
739  std::string canonicalName(paramName);
740 
741  std::string modelParamGroup(GET_PROP_VALUE(TypeTag,
742  ParameterGroupPrefix));
743  if (modelParamGroup.size()) {
744  canonicalName.insert(0, ".");
745  canonicalName.insert(0, modelParamGroup);
746  }
747 
748  // retrieve actual parameter from the parameter tree
749  const ParamType defaultValue = GET_PROP_VALUE_(TypeTag, PropTag);
750  static ParamType value =
751  ParamsMeta::tree().template get<ParamType>(canonicalName, defaultValue);
752 
753  return value;
754  }
755 };
756 
757 template <class TypeTag, class ParamType, class PropTag>
758 const ParamType &get(const char *propTagName, const char *paramName,
759  bool errorIfNotRegistered)
760 {
761  return Param<TypeTag>::template get<ParamType, PropTag>(propTagName,
762  paramName,
763  errorIfNotRegistered);
764 }
765 
766 template <class TypeTag, class ParamType, class PropTag>
767 void registerParam(const char *paramName, const char *propertyName, const char *usageString)
768 {
769  typedef typename GET_PROP(TypeTag, ParameterMetaData) ParamsMeta;
770  if (!ParamsMeta::registrationOpen())
771  OPM_THROW(std::logic_error,
772  "Parameter registration was already closed before "
773  "the parameter '" << paramName << "' was registered.");
774 
775  ParamsMeta::registrationFinalizers().push_back(
776  new ParamRegFinalizer_<TypeTag, ParamType, PropTag>(paramName));
777 
778  ParamInfo paramInfo;
779  paramInfo.paramName = paramName;
780  paramInfo.paramTypeName = Opm::className<ParamType>();
781  std::string tmp = Opm::className<TypeTag>();
782  tmp.replace(0, strlen("Opm::Properties::TTag::"), "");
783  paramInfo.propertyName = propertyName;
784  paramInfo.usageString = usageString;
785  std::ostringstream oss;
786  oss << GET_PROP_VALUE_(TypeTag, PropTag);
787  paramInfo.compileTimeValue = oss.str();
788  if (ParamsMeta::registry().find(paramName) != ParamsMeta::registry().end()) {
789  // allow to register a parameter twice, but only if the
790  // parameter name, type and usage string are exactly the same.
791  if (ParamsMeta::registry().at(paramName) == paramInfo)
792  return;
793  OPM_THROW(std::logic_error,
794  "Parameter " << paramName
795  << " registered twice with non-matching characteristics.");
796  }
797 
798  ParamsMeta::mutableRegistry()[paramName] = paramInfo;
799 }
800 
801 template <class TypeTag>
802 void endParamRegistration()
803 {
804  typedef typename GET_PROP(TypeTag, ParameterMetaData) ParamsMeta;
805  if (!ParamsMeta::registrationOpen())
806  OPM_THROW(std::logic_error,
807  "Parameter registration was already "
808  "closed. It is only possible to close it "
809  "once.");
810 
811  ParamsMeta::registrationOpen() = false;
812 
813  // loop over all parameters and retrieve their values to make sure
814  // that there is no syntax error
815  auto pIt = ParamsMeta::registrationFinalizers().begin();
816  const auto &pEndIt = ParamsMeta::registrationFinalizers().end();
817  for (; pIt != pEndIt; ++pIt) {
818  (*pIt)->retrieve();
819  delete *pIt;
820  }
821 }
823 
824 } // namespace Parameters
825 } // namespace Ewoms
826 
827 #endif
std::string parseCommandLineOptions(int argc, char **argv, bool handleHelp=true)
Parse the parameters provided on the command line.
Definition: parametersystem.hh:397
#define GET_PROP(TypeTag, PropTagName)
Retrieve a property for a type tag.
Definition: propertysystem.hh:453
#define GET_PROP_VALUE(TypeTag, PropTagName)
Access the value attribute of a property for a type tag.
Definition: propertysystem.hh:468
void printUsage(const std::string &progName, const std::string &errorMsg="", bool handleHelp=true, std::ostream &os=std::cerr)
Print a usage message for all run-time parameters.
Definition: parametersystem.hh:350
void printValues(std::ostream &os=std::cout)
Print values of the run-time parameters.
Definition: parametersystem.hh:543
SET_PROP(NumericModel, ParameterTree)
Set the ParameterTree property.
Definition: basicproperties.hh:117
NEW_PROP_TAG(Grid)
The type of the DUNE grid.
STL namespace.
Definition: baseauxiliarymodule.hh:35
bool printUnused(std::ostream &os=std::cout)
Print the list of unused run-time parameters.
Definition: parametersystem.hh:611
NEW_TYPE_TAG(AuxModule)
Provides the magic behind the eWoms property system.
SET_STRING_PROP(NumericModel, ModelParameterGroup,"")
use the global group as default for the model's parameter group