MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
NSDFWriter.cpp
Go to the documentation of this file.
1 // NSDFWriter.cpp ---
2 //
3 // Filename: NSDFWriter.cpp
4 // Description:
5 // Author: subha
6 // Maintainer:
7 // Created: Thu Jun 18 23:16:11 2015 (-0400)
8 // Version:
9 // Last-Updated: Sun Dec 20 23:20:19 2015 (-0500)
10 // By: subha
11 // Update #: 49
12 // URL:
13 // Keywords:
14 // Compatibility:
15 //
16 //
17 
18 // Commentary:
19 //
20 //
21 //
22 //
23 
24 // Change log:
25 //
26 //
27 //
28 //
29 // This program is free software; you can redistribute it and/or
30 // modify it under the terms of the GNU General Public License as
31 // published by the Free Software Foundation; either version 3, or
32 // (at your option) any later version.
33 //
34 // This program is distributed in the hope that it will be useful,
35 // but WITHOUT ANY WARRANTY; without even the implied warranty of
36 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
37 // General Public License for more details.
38 //
39 // You should have received a copy of the GNU General Public License
40 // along with this program; see the file COPYING. If not, write to
41 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth
42 // Floor, Boston, MA 02110-1301, USA.
43 //
44 //
45 
46 // Code:
47 #ifdef USE_HDF5
48 
49 #include "hdf5.h"
50 #include "hdf5_hl.h"
51 
52 #include <ctime>
53 #include <deque>
54 
55 #include "header.h"
56 #include "../utility/utility.h"
57 
58 #include "HDF5WriterBase.h"
59 #include "HDF5DataWriter.h"
60 
61 #include "InputVariable.h"
62 #include "NSDFWriter.h"
63 
64 extern template herr_t writeScalarAttr(hid_t file_id, string path, string value);
65 extern template herr_t writeScalarAttr(hid_t file_id, string path, double value);
66 
67 const char* const EVENTPATH = "/data/event";
68 const char* const UNIFORMPATH = "/data/uniform";
69 const char* const MODELTREEPATH = "/model/modeltree";
70 const char* const MAPUNIFORMSRC = "/map/uniform";
71 const char* const MAPEVENTSRC = "/map/event";
72 
73 string iso_time(time_t * t)
74 {
75  struct tm * timeinfo;
76  if (t == NULL){
77  time_t current;
78  std::time(&current);
79  timeinfo = std::gmtime(&current);
80  } else {
81  timeinfo = std::gmtime(t);
82  }
83  assert(timeinfo != NULL);
84  char buf[32];
85  strftime(buf, 32, "%FT%T", timeinfo);
86  return string(buf);
87 }
88 
89 const Cinfo * NSDFWriter::initCinfo()
90 {
92  "eventInput",
93  "Sets up field elements for event inputs",
94  InputVariable::initCinfo(),
95  &NSDFWriter::getEventInput,
96  &NSDFWriter::setNumEventInputs,
97  &NSDFWriter::getNumEventInputs);
98 
99  static ValueFinfo <NSDFWriter, string > modelRoot(
100  "modelRoot",
101  "The moose element tree root to be saved under /model/modeltree",
102  &NSDFWriter::setModelRoot,
103  &NSDFWriter::getModelRoot);
104 
105  static DestFinfo process(
106  "process",
107  "Handle process calls. Collects data in buffer and if number of steps"
108  " since last write exceeds flushLimit, writes to file.",
109  new ProcOpFunc<NSDFWriter>( &NSDFWriter::process));
110 
111  static DestFinfo reinit(
112  "reinit",
113  "Reinitialize the object. If the current file handle is valid, it tries"
114  " to close that and open the file specified in current filename field.",
115  new ProcOpFunc<NSDFWriter>( &NSDFWriter::reinit ));
116 
117  static Finfo * processShared[] = {
118  &process, &reinit
119  };
120 
121  static SharedFinfo proc(
122  "proc",
123  "Shared message to receive process and reinit",
124  processShared, sizeof( processShared ) / sizeof( Finfo* ));
125 
126  static Finfo * finfos[] = {
127  &eventInputFinfo,
128  &proc,
129  };
130 
131  static string doc[] = {
132  "Name", "NSDFWriter",
133  "Author", "Subhasis Ray",
134  "Description", "NSDF file writer for saving data."
135  };
136 
137  static Dinfo< NSDFWriter > dinfo;
138  static Cinfo cinfo(
139  "NSDFWriter",
140  HDF5DataWriter::initCinfo(),
141  finfos,
142  sizeof(finfos)/sizeof(Finfo*),
143  &dinfo,
144  doc, sizeof( doc ) / sizeof( string ));
145 
146  return &cinfo;
147 }
148 
149 static const Cinfo * nsdfWriterCinfo = NSDFWriter::initCinfo();
150 
151 NSDFWriter::NSDFWriter(): eventGroup_(-1), uniformGroup_(-1), dataGroup_(-1), modelGroup_(-1), mapGroup_(-1), modelRoot_("/")
152 {
153  ;
154 }
155 
156 NSDFWriter::~NSDFWriter()
157 {
158  close();
159 }
160 
161 void NSDFWriter::close()
162 {
163  if (filehandle_ < 0){
164  return;
165  }
166  flush();
167  closeUniformData();
168  if (uniformGroup_ >= 0){
169  H5Gclose(uniformGroup_);
170  }
171  closeEventData();
172  if (eventGroup_ >= 0){
173  H5Gclose(eventGroup_);
174  }
175  if (dataGroup_ >= 0){
176  H5Gclose(dataGroup_);
177  }
178  HDF5DataWriter::close();
179 }
180 
181 void NSDFWriter::closeUniformData()
182 {
183  for (map < string, hid_t>::iterator ii = classFieldToUniform_.begin();
184  ii != classFieldToUniform_.end();
185  ++ii){
186  if (ii->second >= 0){
187  H5Dclose(ii->second);
188  }
189  }
190  vars_.clear();
191  data_.clear();
192  src_.clear();
193  func_.clear();
194  datasets_.clear();
195 
196 }
197 
198 void NSDFWriter::sortOutUniformSources(const Eref& eref)
199 {
200  vars_.clear();
201  classFieldToSrcIndex_.clear();
202  objectField_.clear();
203  objectFieldToIndex_.clear();
204  const SrcFinfo * requestOut = (SrcFinfo*)eref.element()->cinfo()->findFinfo("requestOut");
205  unsigned int numTgt = eref.element()->getMsgTargetAndFunctions(eref.dataIndex(),
206  requestOut,
207  src_,
208  func_);
209  assert(numTgt == src_.size());
211  // Go through all the sources and determine the index of the
212  // source message in the dataset
214 
215  for (unsigned int ii = 0; ii < func_.size(); ++ii){
216  string varname = func_[ii];
217  size_t found = varname.find("get");
218  if (found == 0){
219  varname = varname.substr(3);
220  if (varname.length() == 0){
221  varname = func_[ii];
222  } else {
223  varname[0] = tolower(varname[0]);
224  }
225  }
226  assert(varname.length() > 0);
227  string className = Field<string>::get(src_[ii], "className");
228  string datasetPath = className + "/"+ varname;
229  classFieldToSrcIndex_[datasetPath].push_back(ii);
230  vars_.push_back(varname);
231  }
232  data_.resize(numTgt);
233 }
234 
239 void NSDFWriter::openUniformData(const Eref &eref)
240 {
241  sortOutUniformSources(eref);
242  htri_t exists;
243  herr_t status;
244  if (uniformGroup_ < 0){
245  uniformGroup_ = require_group(filehandle_, UNIFORMPATH);
246  }
247 
248  // create the datasets and map them to className/field
249  for (map< string, vector< unsigned int > >::iterator it = classFieldToSrcIndex_.begin();
250  it != classFieldToSrcIndex_.end();
251  ++it){
252  vector< string > tokens;
253  moose::tokenize(it->first, "/", tokens);
254  string className = tokens[0];
255  string fieldName = tokens[1];
256  hid_t container = require_group(uniformGroup_, className);
257  vector < string > srclist;
258  hid_t dataset = createDataset2D(container, fieldName.c_str(), it->second.size());
259  classFieldToUniform_[it->first] = dataset;
260  writeScalarAttr<string>(dataset, "field", fieldName);
261  H5Gclose(container);
262  }
263 }
264 
268 void NSDFWriter::createUniformMap()
269 {
270  // Create the container for all the DS
271  // TODO: make a common function like `mkdir -p` to avoid repeating this
272  htri_t exists;
273  herr_t status;
274  hid_t uniformMapContainer = require_group(filehandle_, MAPUNIFORMSRC);
275  // Create the DS themselves
276  for (map< string, vector < unsigned int > >::iterator ii = classFieldToSrcIndex_.begin();
277  ii != classFieldToSrcIndex_.end(); ++ii){
278  vector < string > pathTokens;
279  moose::tokenize(ii->first, "/", pathTokens);
280  string className = pathTokens[0];
281  string fieldName = pathTokens[1];
282  hid_t container = require_group(uniformMapContainer, className);
283  char ** sources = (char **)calloc(ii->second.size(), sizeof(char*));
284  for (unsigned int jj = 0; jj < ii->second.size(); ++jj){
285  sources[jj] = (char*)calloc(src_[ii->second[jj]].path().length()+1, sizeof(char));
286  strcpy(sources[jj],src_[ii->second[jj]].path().c_str());
287  }
288  hid_t ds = createStringDataset(container, fieldName, (hsize_t)ii->second.size(), (hsize_t)ii->second.size());
289  hid_t memtype = H5Tcopy(H5T_C_S1);
290  status = H5Tset_size(memtype, H5T_VARIABLE);
291  assert(status >= 0);
292  status = H5Dwrite(ds, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, sources);
293 #ifndef NDEBUG
294  cout << "Write dataset: status=" << status << endl;
295 #endif
296  assert(status >= 0);
297  for (unsigned int jj = 0; jj < ii->second.size(); ++jj){
298  free(sources[jj]);
299  }
300  free(sources);
301  status = H5DSset_scale(ds, "source");
302  status = H5DSattach_scale(classFieldToUniform_[ii->first], ds, 0);
303  status = H5DSset_label(classFieldToUniform_[ii->first], 0, "source");
304  status = H5Dclose(ds);
305  status = H5Tclose(memtype);
306  }
307 }
308 
309 void NSDFWriter::closeEventData()
310 {
311  for (unsigned int ii = 0; ii < eventDatasets_.size(); ++ii){
312  if (eventDatasets_[ii] >= 0){
313  H5Dclose(eventDatasets_[ii]);
314  }
315  }
316  events_.clear();
317  eventInputs_.clear();
318  eventDatasets_.clear();
319  eventSrc_.clear();
320  eventSrcFields_.clear();
321 }
322 
328 void NSDFWriter::openEventData(const Eref &eref)
329 {
330  if (filehandle_ <= 0){
331  return;
332  }
333  for (unsigned int ii = 0; ii < eventInputs_.size(); ++ii){
334  stringstream path;
335  path << eref.objId().path() << "/" << "eventInput[" << ii << "]";
336  ObjId inputObj = ObjId(path.str());
337  Element * el = inputObj.element();
338  const DestFinfo * dest = static_cast<const DestFinfo*>(el->cinfo()->findFinfo("input"));
339  vector < ObjId > src;
340  vector < string > srcFields;
341  el->getMsgSourceAndSender(dest->getFid(), src, srcFields);
342  if (src.size() > 1){
343  cerr << "NSDFWriter::openEventData - only one source can be connected to an eventInput" <<endl;
344  } else if (src.size() == 1){
345  eventSrcFields_.push_back(srcFields[0]);
346  eventSrc_.push_back(src[0].path());
347  events_.resize(eventSrc_.size());
348  stringstream path;
349  path << src[0].path() << "." << srcFields[0];
350  hid_t dataSet = getEventDataset(src[0].path(), srcFields[0]);
351  eventDatasets_.push_back(dataSet);
352  } else {
353  cerr <<"NSDFWriter::openEventData - cannot handle multiple connections at single input." <<endl;
354  }
355  }
356 }
357 
358 void NSDFWriter::createEventMap()
359 {
360  herr_t status;
361  hid_t eventMapContainer = require_group(filehandle_, MAPEVENTSRC);
362  // Open the container for the event maps
363  // Create the Datasets themselves (one for each field - each row
364  // for one object).
365  for (map< string, vector < string > >::iterator ii = classFieldToEventSrc_.begin();
366  ii != classFieldToEventSrc_.end();
367  ++ii){
368  vector < string > pathTokens;
369  moose::tokenize(ii->first, "/", pathTokens);
370  string className = pathTokens[0];
371  string fieldName = pathTokens[1];
372  hid_t classGroup = require_group(eventMapContainer, className);
373  hid_t strtype = H5Tcopy(H5T_C_S1);
374  status = H5Tset_size(strtype, H5T_VARIABLE);
375  // create file space
376  hid_t ftype = H5Tcreate(H5T_COMPOUND, sizeof(hvl_t) +sizeof(hobj_ref_t));
377  status = H5Tinsert(ftype, "source", 0, strtype);
378  status = H5Tinsert(ftype, "data", sizeof(hvl_t), H5T_STD_REF_OBJ);
379  hsize_t dims[1] = {ii->second.size()};
380  hid_t space = H5Screate_simple(1, dims, NULL);
381  // The dataset for mapping is named after the field
382  hid_t ds = H5Dcreate2(classGroup, fieldName.c_str(), ftype, space,
383  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
384  status = H5Sclose(space);
385  map_type * buf = (map_type*)calloc(ii->second.size(), sizeof(map_type));
386  // Populate the buffer entries with source uid and data
387  // reference
388  for (unsigned int jj = 0; jj < ii->second.size(); ++jj){
389  buf->source = ii->second[jj].c_str();
390  char * dsname = (char*)calloc(256, sizeof(char));
391  ssize_t size = H5Iget_name(classFieldToEvent_[ii->first][jj], dsname, 255);
392  if (size > 255){
393  free(dsname);
394  dsname = (char*)calloc(size, sizeof(char));
395  size = H5Iget_name(classFieldToEvent_[ii->first][jj], dsname, 255);
396  }
397  status = H5Rcreate(&(buf->data), filehandle_, dsname, H5R_OBJECT, -1);
398  free(dsname);
399  assert(status >= 0);
400  }
401  // create memory space
402  hid_t memtype = H5Tcreate(H5T_COMPOUND, sizeof(map_type));
403  status = H5Tinsert(memtype, "source",
404  HOFFSET(map_type, source), strtype);
405  status = H5Tinsert(memtype, "data",
406  HOFFSET(map_type, data), H5T_STD_REF_OBJ);
407  status = H5Dwrite(ds, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf);
408  free(buf);
409  status = H5Tclose(strtype);
410  status = H5Tclose(ftype);
411  status = H5Tclose(memtype);
412  status = H5Dclose(ds);
413  }
414 }
415 
424 hid_t NSDFWriter::getEventDataset(string srcPath, string srcField)
425 {
426  string eventSrcPath = srcPath + string("/") + srcField;
427  map< string, hid_t >::iterator it = eventSrcDataset_.find(eventSrcPath);
428  if (it != eventSrcDataset_.end()){
429  return it->second;
430  }
431  ObjId source(srcPath);
432  herr_t status;
433  htri_t exists = -1;
434  string className = Field<string>::get(source, "className");
435  string path = EVENTPATH + string("/") + className + string("/") + srcField;
436  hid_t container = require_group(filehandle_, path);
437  stringstream dsetname;
438  dsetname << source.id.value() <<"_" << source.dataIndex << "_" << source.fieldIndex;
439  hid_t dataset = createDoubleDataset(container, dsetname.str().c_str());
440  classFieldToEvent_[className + "/" + srcField].push_back(dataset);
441  classFieldToEventSrc_[className + "/" + srcField].push_back(srcPath);
442  status = writeScalarAttr<string>(dataset, "source", srcPath);
443  assert(status >= 0);
444  status = writeScalarAttr<string>(dataset, "field", srcField);
445  assert(status >= 0);
446  eventSrcDataset_[eventSrcPath] = dataset;
447  return dataset;
448 }
449 
450 void NSDFWriter::flush()
451 {
452  // We need to update the tend on each write since we do not know
453  // when the simulation is getting over and when it is just paused.
454  writeScalarAttr<string>(filehandle_, "tend", iso_time(NULL));
455 
456  // append all uniform data
457  for (map< string, hid_t>::iterator it = classFieldToUniform_.begin();
458  it != classFieldToUniform_.end(); ++it){
459  map< string, vector < unsigned int > >::iterator idxit = classFieldToSrcIndex_.find(it->first);
460  if (idxit == classFieldToSrcIndex_.end()){
461  cerr << "Error: NSDFWriter::flush - could not find entry for " << it->first <<endl;
462  break;
463  }
464  if (data_.size() == 0 || data_[0].size() == 0){
465  break;
466  }
467  double * buffer = (double*)calloc(idxit->second.size() * steps_, sizeof(double));
468  vector< double > values;
469  for (unsigned int ii = 0; ii < idxit->second.size(); ++ii){
470  for (unsigned int jj = 0; jj < steps_; ++jj){
471  buffer[ii * steps_ + jj] = data_[idxit->second[ii]][jj];
472  }
473  data_[idxit->second[ii]].clear();
474  }
475 
476  hid_t filespace = H5Dget_space(it->second);
477  if (filespace < 0){
478  break;
479  }
480  hsize_t dims[2];
481  hsize_t maxdims[2];
482  // retrieve current datset dimensions
483  herr_t status = H5Sget_simple_extent_dims(filespace, dims, maxdims);
484  hsize_t newdims[] = {dims[0], dims[1] + steps_}; // new column count
485  status = H5Dset_extent(it->second, newdims); // extend dataset to new column count
486  H5Sclose(filespace);
487  filespace = H5Dget_space(it->second); // get the updated filespace
488  hsize_t start[2] = {0, dims[1]};
489  dims[1] = steps_; // change dims for memspace & hyperslab
490  hid_t memspace = H5Screate_simple(2, dims, NULL);
491  H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, dims, NULL);
492  status = H5Dwrite(it->second, H5T_NATIVE_DOUBLE, memspace, filespace, H5P_DEFAULT, buffer);
493  H5Sclose(memspace);
494  H5Sclose(filespace);
495  free(buffer);
496  }
497 
498  // append all event data
499  for (unsigned int ii = 0; ii < eventSrc_.size(); ++ii){
500  appendToDataset(getEventDataset(eventSrc_[ii], eventSrcFields_[ii]),
501  events_[ii]);
502  events_[ii].clear();
503  }
504  // flush HDF5 nodes.
505  HDF5DataWriter::flush();
506 }
507 
508 void NSDFWriter::reinit(const Eref& eref, const ProcPtr proc)
509 {
510  // write environment
511  // write model
512  // write map
513  if (filehandle_ >0){
514  close();
515  }
516  // TODO: what to do when reinit is called? Close the existing file
517  // and open a new one in append mode? Or keep adding to the
518  // current file?
519  if (filename_.empty()){
520  filename_ = "moose_data.nsdf.h5";
521  }
522  openFile();
523  writeScalarAttr<string>(filehandle_, "created", iso_time(0));
524  writeScalarAttr<string>(filehandle_, "tstart", iso_time(0));
525  writeScalarAttr<string>(filehandle_, "nsdf_version", "1.0");
526  openUniformData(eref);
527  for (map < string, hid_t >::iterator it = classFieldToUniform_.begin();
528  it != classFieldToUniform_.end();
529  ++it){
530  // tstart is reset to 0 on reinit
531  writeScalarAttr< double >(it->second, "tstart", 0.0);
532  // dt is same for all requested data - that of the NSDFWriter
533  writeScalarAttr< double >(it->second, "dt", proc->dt);
534  }
535  openEventData(eref);
536  writeModelTree();
537  createUniformMap();
538  createEventMap();
539  steps_ = 0;
540 }
541 
542 void NSDFWriter::process(const Eref& eref, ProcPtr proc)
543 {
544  if (filehandle_ < 0){
545  return;
546  }
547  vector < double > uniformData;
548  const Finfo* tmp = eref.element()->cinfo()->findFinfo("requestOut");
549  const SrcFinfo1< vector < double > *>* requestOut = static_cast<const SrcFinfo1< vector < double > * > * >(tmp);
550  requestOut->send(eref, &uniformData);
551  for (unsigned int ii = 0; ii < uniformData.size(); ++ii){
552  data_[ii].push_back(uniformData[ii]);
553  }
554  ++steps_;
555  if (steps_ < flushLimit_){
556  return;
557  }
558  // // TODO this is place holder. Will convert to 2D datasets to
559  // // collect same field from object on same clock
560  // for (unsigned int ii = 0; ii < datasets_.size(); ++ii){
561  // herr_t status = appendToDataset(datasets_[ii], data_[ii]);
562  // data_[ii].clear();
563  // }
564  // for (unsigned int ii = 0; ii < events_.size(); ++ii){
565  // herr_t status = appendToDataset(eventDatasets_[ii], events_[ii]);
566  // }
567  NSDFWriter::flush();
568  steps_ = 0;
569  }
570 
571 NSDFWriter& NSDFWriter::operator=( const NSDFWriter& other)
572 {
573  eventInputs_ = other.eventInputs_;
574  for ( vector< InputVariable >::iterator
575  i = eventInputs_.begin(); i != eventInputs_.end(); ++i )
576  i->setOwner( this );
577  for (unsigned int ii = 0; ii < getNumEventInputs(); ++ii){
578  events_[ii].clear();
579  }
580  return *this;
581 }
582 
583 void NSDFWriter::setNumEventInputs(unsigned int num)
584 {
585  unsigned int prevSize = eventInputs_.size();
586  eventInputs_.resize(num);
587  for (unsigned int ii = prevSize; ii < num; ++ii){
588  eventInputs_[ii].setOwner(this);
589  }
590 }
591 
592 unsigned int NSDFWriter::getNumEventInputs() const
593 {
594  return eventInputs_.size();
595 }
596 
597 void NSDFWriter::setEnvironment(string key, string value)
598 {
599  env_[key] = value;
600 }
601 
602 
603 void NSDFWriter::setInput(unsigned int index, double value)
604 {
605  events_[index].push_back(value);
606 }
607 
608 InputVariable* NSDFWriter::getEventInput(unsigned int index)
609 {
610  static InputVariable dummy;
611  if (index < eventInputs_.size()){
612  return &eventInputs_[index];
613  }
614  cout << "Warning: NSDFWriter::getEventInput: index: " << index <<
615  " is out of range: " << eventInputs_.size() << endl;
616  return &dummy;
617 }
618 
619 void NSDFWriter::setModelRoot(string value)
620 {
621  modelRoot_ = value;
622 }
623 
624 string NSDFWriter::getModelRoot() const
625 {
626  return modelRoot_;
627 }
628 
629 
630 void NSDFWriter::writeModelTree()
631 {
632  vector< string > tokens;
633  ObjId mRoot(modelRoot_);
634  string rootPath = MODELTREEPATH + string("/") + mRoot.element()->getName();
635  hid_t rootGroup = require_group(filehandle_, rootPath);
636  hid_t tmp;
637  htri_t exists;
638  herr_t status;
639  deque<Id> nodeQueue;
640  deque<hid_t> h5nodeQueue;
641  nodeQueue.push_back(mRoot);
642  h5nodeQueue.push_back(rootGroup);
643  // TODO: need to clarify what happens with array elements. We can
644  // have one node per vec and set a count field for the number of
645  // elements
646  while (nodeQueue.size() > 0){
647  ObjId node = nodeQueue.front();
648  nodeQueue.pop_front();
649  hid_t prev = h5nodeQueue.front();;
650  h5nodeQueue.pop_front();
651  vector < Id > children;
652  Neutral::children(node.eref(), children);
653  for ( unsigned int ii = 0; ii < children.size(); ++ii){
654  string name = children[ii].element()->getName();
655  // skip the system elements
656  if (children[ii].path() == "/Msgs"
657  || children[ii].path() == "/clock"
658  || children[ii].path() == "/classes"
659  || children[ii].path() == "/postmaster"){
660  continue;
661  }
662  exists = H5Lexists(prev, name.c_str(), H5P_DEFAULT);
663  if (exists > 0){
664  tmp = H5Gopen2(prev, name.c_str(), H5P_DEFAULT);
665  } else {
666  tmp = H5Gcreate2(prev, name.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
667  }
668  writeScalarAttr< string >(tmp, "uid", children[ii].path());
669  nodeQueue.push_back(children[ii]);
670  h5nodeQueue.push_back(tmp);
671  }
672  status = H5Gclose(prev);
673  }
674 }
675 #endif // USE_HDF5
676 
677 //
678 // NSDFWriter.cpp ends here
uint32_t value
Definition: moosemodule.h:42
char map_type(const std::type_info &t)
Definition: cnpy.cpp:36
Definition: Dinfo.h:60
static DestFinfo dummy("dummy","This Finfo is a dummy. If you are reading this you have used an invalid index", 0)
unsigned int dataIndex() const
Definition: Eref.h:50
unsigned int getMsgTargetAndFunctions(DataId srcDataId, const SrcFinfo *finfo, vector< ObjId > &tgt, vector< string > &func) const
Definition: Element.cpp:772
Definition: ObjId.h:20
static void children(const Eref &e, vector< Id > &ret)
Definition: Neutral.cpp:342
Element * element() const
Definition: Eref.h:42
void send(const Eref &er, T arg) const
Definition: SrcFinfo.h:106
string path() const
Definition: ObjId.cpp:119
FuncId getFid() const
Definition: DestFinfo.cpp:45
double dt
Definition: ProcInfo.h:18
ObjId objId() const
Definition: Eref.cpp:57
Definition: Eref.h:26
const Cinfo * cinfo() const
Definition: Element.cpp:66
Element * element() const
Definition: ObjId.cpp:124
static char name[]
Definition: mfield.cpp:401
Eref eref() const
Definition: ObjId.cpp:66
void tokenize(const string &str, const string &delimiters, vector< string > &tokens)
Definition: strutil.cpp:19
static A get(const ObjId &dest, const string &field)
Definition: SetGet.h:284
Definition: Cinfo.h:18
static char path[]
Definition: mfield.cpp:403
const Finfo * findFinfo(const string &name) const
Definition: Cinfo.cpp:224
Definition: Finfo.h:12
static SrcFinfo1< vector< double > * > * requestOut()
Definition: Function.cpp:82