Simpatico  v1.10
ParamComposite.cpp
1 /*
2 * Util Package - C++ Utilities for Scientific Computation
3 *
4 * Copyright 2010 - 2017, The Regents of the University of Minnesota
5 * Distributed under the terms of the GNU General Public License.
6 */
7 
8 #include "ParamComposite.h" // class header
9 #include "Begin.h"
10 #include "End.h"
11 #include "Blank.h"
12 #include <util/global.h>
13 
14 #include <cstdio>
15 #include <cstring>
16 
17 namespace Util
18 {
19 
20  /*
21  * Default Constructor.
22  */
24  : ParamComponent(),
25  list_(),
26  isLeaf_(),
27  size_(0),
28  className_("ParamComposite"),
29  isRequired_(true),
30  isActive_(true)
31  {}
32 
33  /*
34  * Constructor.
35  */
37  : ParamComponent(),
38  list_(),
39  isLeaf_(),
40  size_(0),
41  className_("ParamComposite"),
42  isRequired_(true),
43  isActive_(true)
44  {
45  if (capacity <= 0 ) {
46  UTIL_THROW("Attempt to reserve capacity <= 0");
47  }
48  list_.reserve(capacity);
49  isLeaf_.reserve(capacity);
50  }
51 
52  /*
53  * Copy constructor.
54  */
56  : ParamComponent(other),
57  list_(),
58  isLeaf_(),
59  size_(0),
60  className_(other.className_),
61  isRequired_(true),
62  isActive_(true)
63  {}
64 
65  /*
66  * Destructor.
67  */
69  {
70  if (size_ > 0) {
71  for (int i=0; i < size_; ++i) {
72  if (isLeaf_[i]) {
73  delete list_[i];
74  }
75  /* Only delete Parameter, Begin, End & Blank leaf objects.
76  * Do NOT delete node objects here. These are instances of
77  * of subclasses of ParamComposite that are never created
78  * by this object, and so should not be destroyed by this
79  * object.
80  */
81  }
82  }
83  }
84 
85  /*
86  * Read required parameter block, including begin and end.
87  */
88  void ParamComposite::readParam(std::istream &in)
89  {
90  assert(className_.size() > 0);
91  isRequired_ = true;
92  isActive_ = true;
93  readBegin(in, className_.c_str());
94  readParameters(in);
95  readEnd(in);
96  }
97 
98  /*
99  * Read optional parameter block, including begin and end.
100  */
101  void ParamComposite::readParamOptional(std::istream &in)
102  {
103  assert(className_.size() > 0);
104  isRequired_ = false;
105  isActive_ = false;
106  Begin* beginPtr = &readBegin(in, className_.c_str(), isRequired_);
107  if (beginPtr->isActive()) {
108  readParameters(in);
109  readEnd(in);
110  isActive_ = true;
111  } else {
112  delete beginPtr;
113  }
114  }
115 
116  /*
117  * Default writeParam implementation.
118  */
119  void ParamComposite::writeParam(std::ostream &out)
120  {
121  if (isActive_) {
122  for (int i=0; i < size_; ++i) {
123  list_[i]->writeParam(out);
124  }
125  }
126  }
127 
128  /*
129  * Default load implementation, adds begin and end.
130  */
132  {
133  assert(className_.size() > 0);
134  Begin* beginPtr = &addBegin(className_.c_str());
135  if (ParamComponent::echo()) {
136  if (isIoProcessor()) {
137  beginPtr->writeParam(Log::file());
138  }
139  }
140  loadParameters(ar);
141  End* endPtr = &addEnd();
142  if (ParamComponent::echo()) {
143  if (isIoProcessor()) {
144  endPtr->writeParam(Log::file());
145  }
146  }
147  }
148 
149  /*
150  * Optionally load this object.
151  */
153  {
154  // Load and broadcast isActive_ flag
155  if (isIoProcessor()) {
156  ar & isActive_;
157  if (!isActive_) {
158  if (ParamComponent::echo()) {
159  Log::file() << indent()
160  << className() << "{ [absent] }"
161  << std::endl;
162  }
163  }
164  } else {
165  #ifdef UTIL_MPI
166  if (!hasIoCommunicator()) {
167  UTIL_THROW("Error: not isIoProcessor and not hasIoCommunicator");
168  }
169  #else
170  UTIL_THROW("Error: not isIoProcessor and no MPI");
171  #endif
172  }
173  #ifdef UTIL_MPI
174  if (hasIoCommunicator()) {
175  bcast<bool>(ioCommunicator(), isActive_, 0);
176  }
177  #endif
178 
179  // Load object data iff isActive_
180  if (isActive_) {
181  load(ar);
182  }
183  }
184 
185  /*
186  * Default save implementation.
187  */
189  {
190  for (int i=0; i < size_; ++i) {
191  list_[i]->save(ar);
192  }
193  }
194 
195  /*
196  * Save this optional ParamComposite.
197  */
199  {
200  ar & isActive_;
201  if (isActive_) {
202  save(ar);
203  }
204  }
205 
206  /*
207  * Reset list to empty state.
208  */
210  {
211  for (int i=0; i < size_; ++i) {
212  if (isLeaf_[i]) {
213  delete list_[i];
214  } else {
215  list_[i]->resetParam();
216  }
217  }
218  size_ = 0;
219  }
220 
221  /*
222  * Set this to be the parent of a child component.
223  */
225  {
226  param.setIndent(*this, next);
227  #ifdef UTIL_MPI
228  if (hasIoCommunicator()) {
230  }
231  #endif
232  }
233 
234  /*
235  * Add a leaf ParamComponent to the format array.
236  */
238  {
239  list_.push_back(&param);
240  isLeaf_.push_back(isLeaf);
241  ++size_;
242  }
243 
244  // ParamComposite object
245 
246  /*
247  * Add a required ParamComposite node.
248  */
250  {
251  bool isLeaf = false;
252  setParent(child, next);
253  addComponent(child, isLeaf);
254  }
255 
256  /*
257  * Add a required ParamComposite node, and call its readParam() method.
258  */
259  void
261  bool next)
262  {
263  addParamComposite(child, next);
264  child.readParam(in);
265  }
266 
267  /*
268  * Add an optional ParamComposite, and call its readParamOptional method.
269  */
270  void
272  ParamComposite &child, bool next)
273  {
274  addParamComposite(child, next);
275  child.readParamOptional(in);
276  }
277 
278  /*
279  * Add a required ParamComposite node and load its data from archive ar.
280  */
281  void
283  ParamComposite &child, bool next)
284  {
285  addParamComposite(child, next);
286  child.load(ar);
287  }
288 
289  /*
290  * Add an optional ParamComposite node, and load data if isActive.
291  */
292  void
294  ParamComposite &child, bool next)
295  {
296  addParamComposite(child, next);
297  child.loadOptional(ar);
298  }
299 
300  // Begin
301 
302  /*
303  * Create and add a new Begin object.
304  */
305  Begin& ParamComposite::addBegin(const char *label)
306  {
307  Begin* ptr = new Begin(label);
308  setParent(*ptr, false);
309  addComponent(*ptr);
310  return *ptr;
311  }
312 
313  /*
314  * Read the opening line of a ParamComposite.
315  */
316  Begin& ParamComposite::readBegin(std::istream &in, const char *label,
317  bool isRequired)
318  {
319  Begin* ptr = new Begin(label, isRequired);
320  setParent(*ptr, false);
321  ptr->readParam(in);
322  if (ptr->isActive()) {
323  addComponent(*ptr);
324  }
325  return *ptr;
326  }
327 
328  // End
329 
330  /*
331  * Create and add a new End object.
332  */
334  {
335  End* ptr = new End();
336  setParent(*ptr, false);
337  addComponent(*ptr);
338  return *ptr;
339  }
340 
341  /*
342  * Read the closing bracket of a ParamComposite.
343  */
344  End& ParamComposite::readEnd(std::istream &in)
345  {
346  End* ptr = &addEnd();
347  ptr->readParam(in);
348  return *ptr;
349  }
350 
351  // Blank
352 
353  /*
354  * Create and add a new Blank object (a blank line).
355  */
357  {
358  Blank* ptr = new Blank();
359  setParent(*ptr);
360  addComponent(*ptr);
361  return *ptr;
362  }
363 
364  /*
365  * Read a blank line.
366  */
367  Blank& ParamComposite::readBlank(std::istream &in)
368  {
369  Blank* ptr = &addBlank();
370  ptr->readParam(in);
371  return *ptr;
372  }
373 
374  /*
375  * Set the class name string.
376  */
378  { className_ = className; }
379 
380  /*
381  * Set or unset the isActive flag.
382  */
384  {
385  isRequired_ = isRequired;
386  if (isRequired_) {
387  isActive_ = true;
388  }
389  }
390 
391  /*
392  * Set or unset the isActive flag.
393  */
395  {
396  if (isRequired_ && !isActive) {
397  UTIL_THROW("Error: cannot be required but not active");
398  }
399  isActive_ = isActive;
400  }
401 
402 }
virtual void loadOptional(Serializable::IArchive &ar)
Load an optional ParamComposite.
End bracket of a ParamComposite parameter block.
Definition: End.h:24
ParamComposite()
Constructor.
An empty line within a parameter file.
Definition: Blank.h:24
bool isRequired() const
Is this ParamComposite required in the input file?
void setIoCommunicator(MPI::Intracomm &communicator)
Set the communicator.
Definition: MpiFileIo.cpp:36
void resetParam()
Resets ParamComposite to its empty state.
virtual void readParamOptional(std::istream &in)
Read optional parameter file block.
virtual void readParam(std::istream &in)
Read a blank line.
Definition: Blank.cpp:27
void setParent(ParamComponent &param, bool next=true)
Set this to the parent of a child component.
void loadParamComposite(Serializable::IArchive &ar, ParamComposite &child, bool next=true)
Add and load a required child ParamComposite.
End & readEnd(std::istream &in)
Add and read the closing bracket.
void saveOptional(Serializable::OArchive &ar)
Saves isActive flag, and then calls save() iff isActive is true.
File containing preprocessor macros for error handling.
void setIsActive(bool isActive)
Set or unset the isActive flag.
Blank & readBlank(std::istream &in)
Add and read a new Blank object, representing a blank line.
void bcast< bool >(MPI::Intracomm &comm, bool &data, int root)
Explicit specialization of bcast for bool data.
Definition: MpiSendRecv.cpp:34
End & addEnd()
Add a closing bracket.
bool isActive() const
Is this parameter active?
Saving / output archive for binary ostream.
void addComponent(ParamComponent &param, bool isLeaf=true)
Add a new ParamComponent object to the format array.
void loadParamCompositeOptional(Serializable::IArchive &ar, ParamComposite &child, bool next=true)
Add and load an optional child ParamComposite if isActive.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
std::string className() const
Get class name string.
MPI::Intracomm & ioCommunicator() const
Get the MPI communicator by reference.
Definition: MpiFileIo.h:105
virtual void writeParam(std::ostream &out)
Write all parameters to an output stream.
virtual void save(Serializable::OArchive &ar)
Saves all parameters to an archive.
virtual ~ParamComposite()
Virtual destructor.
Utility classes for scientific computation.
Definition: accumulators.mod:1
static bool echo()
Get echo parameter.
Begin & addBegin(const char *label)
Add a Begin object representing a class name and bracket.
virtual void writeParam(std::ostream &out)
Write the opening line.
Definition: Begin.cpp:80
bool isIoProcessor() const
Can this processor do file I/O ?
Definition: MpiFileIo.h:92
virtual void readParameters(std::istream &in)
Read the body of parameter block, without begin and end lines.
virtual void writeParam(std::ostream &out)
Write the closing bracket.
Definition: End.cpp:43
Abstract base class for classes that input and ouput parameters to file.
virtual void loadParameters(Serializable::IArchive &ar)
Load state from archive, without adding Begin and End lines.
void setIndent(const ParamComponent &parent, bool next=true)
Set indent level.
void readParamCompositeOptional(std::istream &in, ParamComposite &child, bool next=true)
Add and attempt to read an optional child ParamComposite.
static std::ostream & file()
Get log ostream by reference.
Definition: Log.cpp:57
bool hasIoCommunicator() const
Does this object have an associated MPI communicator?
Definition: MpiFileIo.h:99
virtual void load(Serializable::IArchive &ar)
Load all parameters from an input archive.
Saving archive for binary istream.
virtual void readParam(std::istream &in)
Read the parameter file block.
virtual void readParam(std::istream &in)
Read the closing bracket.
Definition: End.cpp:30
void addParamComposite(ParamComposite &child, bool next=true)
Add a child ParamComposite object to the format array.
bool isActive() const
Is this an active element (has it been read from file)?
Definition: Begin.h:84
void setClassName(const char *className)
Set class name string.
void readParamComposite(std::istream &in, ParamComposite &child, bool next=true)
Add and read a required child ParamComposite.
Begin & readBegin(std::istream &in, const char *label, bool isRequired=true)
Add and read a class label and opening bracket.
virtual void readParam(std::istream &in)
Read the opening line.
Definition: Begin.cpp:33
An object that can read multiple parameters from file.
Blank & addBlank()
Create and add a new Blank object, representing a blank line.
std::string indent() const
Return indent string for this object (string of spaces).
void setIsRequired(bool isRequired)
Set or unset the isActive flag.
Beginning line of a composite parameter block.
Definition: Begin.h:24