Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Rocout.C
Go to the documentation of this file.
1 /* *******************************************************************
2  * Rocstar Simulation Suite *
3  * Copyright@2015, Illinois Rocstar LLC. All rights reserved. *
4  * *
5  * Illinois Rocstar LLC *
6  * Champaign, IL *
7  * www.illinoisrocstar.com *
8  * sales@illinoisrocstar.com *
9  * *
10  * License: See LICENSE file in top level of distribution package or *
11  * http://opensource.org/licenses/NCSA *
12  *********************************************************************/
13 /* *******************************************************************
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
16  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
17  * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
21  * USE OR OTHER DEALINGS WITH THE SOFTWARE. *
22  *********************************************************************/
26 /* Author John Norris
27  * Initial date: May 17, 2004
28  */
29 
30 #include <sys/stat.h>
31 #include <fstream>
32 #include <iomanip>
33 #include <iostream>
34 #include <sstream>
35 #include <string>
36 #include <algorithm>
37 #include <errno.h>
38 
39 #include "Rocout.h"
40 #include "Rocout_hdf4.h"
41 #ifdef USE_CGNS
42 #include "Rocout_cgns.h"
43 #endif // USE_CGNS
44 
45 #ifndef DOXYGEN_SHOULD_SKIP_THIS
46 USE_COM_NAME_SPACE
47 #endif
48 
49 static const int MAX_ASYNC_WRITES = 10;
50 
52 struct WriteAttrInfo {
53  WriteAttrInfo( Rocout *rout, const char* filename_pre, const Attribute* attr,
54  const char* material, const char* timelevel,
55  const char* mfile_pre = NULL, const MPI_Comm* pComm = NULL,
56  const int* pane_id = NULL, int append = -1,
57  bool cloned = false)
58  : m_rout(rout), m_prefix(filename_pre), m_attr(attr), m_material(material),
59  m_timelevel(timelevel), m_meshPrefix(mfile_pre != NULL ? mfile_pre : ""),
60  m_pComm(pComm), m_pPaneId(pane_id), m_append(append), m_cloned(cloned) {}
61 
63  const std::string m_prefix;
64  const Attribute* m_attr;
65  const std::string m_material;
66  const std::string m_timelevel;
67  const std::string m_meshPrefix;
68  const MPI_Comm* m_pComm;
69  const int* m_pPaneId;
70  const int m_append;
71  const bool m_cloned;
72 };
73 
74 #define SwitchOnDataType(dType, funcCall) \
75  switch (dType) { \
76  case COM_CHAR: \
77  case COM_BYTE: \
78  { typedef char TT; \
79  funcCall; } \
80  break; \
81  case COM_UNSIGNED_CHAR: \
82  { typedef unsigned char TT; \
83  funcCall; } \
84  break; \
85  case COM_SHORT: \
86  { typedef short TT; \
87  funcCall; } \
88  break; \
89  case COM_UNSIGNED_SHORT: \
90  { typedef unsigned short TT; \
91  funcCall; } \
92  break; \
93  case COM_INT: \
94  { typedef int TT; \
95  funcCall; } \
96  break; \
97  case COM_UNSIGNED: \
98  { typedef unsigned int TT; \
99  funcCall; } \
100  break; \
101  case COM_LONG: \
102  { typedef long TT; \
103  funcCall; } \
104  break; \
105  case COM_UNSIGNED_LONG: \
106  { typedef unsigned long TT; \
107  funcCall; } \
108  break; \
109  case COM_FLOAT: \
110  { typedef float TT; \
111  funcCall; } \
112  break; \
113  case COM_DOUBLE: \
114  { typedef double TT; \
115  funcCall; } \
116  break; \
117  case COM_LONG_DOUBLE: \
118  { typedef long double TT; \
119  funcCall; } \
120  break; \
121  }
122 
123 #define ERROR_MSG(msg) \
124 { if (_options["errorhandle"] != "ignore") { \
125  std::cerr << msg << std::endl; \
126  if (_options["errorhandle"] == "abort") { \
127  if (COMMPI_Initialized()) \
128  MPI_Abort(MPI_COMM_WORLD, 0); \
129  else \
130  abort(); \
131  } \
132  } \
133 }
134 
135 #ifdef USE_PTHREADS
136 Semaphore Rocout::_writesem(MAX_ASYNC_WRITES, MAX_ASYNC_WRITES);
137 #endif // USE_PTHREADS
138 
139 void Rocout::init(const std::string &mname) {
140 
141  HDF4::init();
142 
143  Rocout *rout = new Rocout();
144 
145  // Masoud, changing default to CGNS
146  //rout->_options["format"] = "HDF4";
147  rout->_options["format"] = "CGNS";
148  //
149  rout->_options["async"] = "off";
150  rout->_options["mode"] = "w";
151  rout->_options["localdir"] = "";
152  rout->_options["rankwidth"] = "4";
153  rout->_options["pnidwidth"] = "0";
154  rout->_options["separator"] = "_";
155  rout->_options["errorhandle"] = "abort";
156  rout->_options["rankdir"] = "off";
157  rout->_options["ghosthandle"] = "write";
158 
159  COM_new_window( mname.c_str(), MPI_COMM_SELF);
160 
161  std::string glb=mname+".global";
162 
163  COM_new_attribute( glb.c_str(), 'w', COM_VOID, 1, "");
164  COM_set_object( glb.c_str(), 0, rout);
165 
166 
167  // Register the function write_attribute
170  COM_set_member_function( (mname+".write_attribute").c_str(),
171  (Member_func_ptr)&Rocout::write_attribute,
172  glb.c_str(), "biiiiIII", types);
173  COM_set_member_function( (mname+".put_attribute").c_str(),
174  (Member_func_ptr)&Rocout::put_attribute,
175  glb.c_str(), "biiiiIII", types);
176  COM_set_member_function( (mname+".add_attribute").c_str(),
177  (Member_func_ptr)&Rocout::add_attribute,
178  glb.c_str(), "biiiiIII", types);
179  COM_set_member_function( (mname+".write_window").c_str(),
180  (Member_func_ptr)&Rocout::write_attribute,
181  glb.c_str(), "biiiiIII", types);
182 
183  // Register the function write_rocin_control_file
184  types[2] = types[3] = COM_STRING;
185  COM_set_member_function( (mname+".write_rocin_control_file").c_str(),
186  (Member_func_ptr)&Rocout::write_rocin_control_file,
187  glb.c_str(), "biii", types);
188 
189  // Register the function sync
190  COM_set_member_function( (mname+".sync").c_str(),
191  (Member_func_ptr)&Rocout::sync,
192  glb.c_str(), "b", types);
193 
194  // Register the function set_option
195  COM_set_member_function( (mname+".set_option").c_str(),
196  (Member_func_ptr)&Rocout::set_option,
197  glb.c_str(), "bii", types);
198 
199  // Register the function write_parameter_file
200  types[3] = COM_MPI_COMM;
201  COM_set_member_function( (mname+".write_parameter_file").c_str(),
202  (Member_func_ptr)&Rocout::write_parameter_file,
203  glb.c_str(), "biiI", types);
204 
205  // Register the function read_control_file
206  COM_set_member_function( (mname+".read_control_file").c_str(),
207  (Member_func_ptr)&Rocout::read_control_file,
208  glb.c_str(), "bi", types);
209 
210  COM_window_init_done( mname.c_str());
211 }
212 
213 void Rocout::finalize(const std::string &mname) {
214  Rocout *rout;
215  std::string glb=mname+".global";
216 
217  COM_get_object( glb.c_str(), 0, &rout);
218 
219  COM_delete_window( mname.c_str());
220 
221 #ifdef USE_PTHREADS
222  // Wait for any writer threads to finish.
223  void* ret;
224  std::vector<pthread_t>::iterator p = rout->_writers.begin();
225  while (p != rout->_writers.end()) {
226  pthread_join(*p, &ret);
227  ++p;
228  }
229 # endif // USE_PTHREADS
230 
231  delete rout;
232  HDF4::finalize();
233 }
234 
236 
246 void Rocout::write_attribute( const char* filename_pre,
247  const Attribute* attr, const char* material,
248  const char* timelevel, const char* mfile_pre,
249  const MPI_Comm* pComm, const int* pane_id)
250 {
251  WriteAttrInfo* pWAI;
252 
253 #ifdef USE_PTHREADS
254  if (_options["async"] == "off") {
255 #endif // USE_PTHREADS
256  pWAI = new WriteAttrInfo(this, filename_pre, attr, material, timelevel,
257  mfile_pre, pComm, pane_id);
258  write_attr_internal(pWAI);
259 #ifdef USE_PTHREADS
260  } else {
261  pWAI = new WriteAttrInfo(this, filename_pre, attr, material, timelevel,
262  mfile_pre, pComm, pane_id, -1, true);
263  pthread_attr_t attr;
264  pthread_attr_init(&attr);
265  pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
266 
267  pthread_t id;
268  pthread_create(&id, &attr, write_attr_internal, pWAI);
269  pthread_attr_destroy(&attr);
270  _writers.push_back(id);
271  }
272 #endif // USE_PTHREADS
273 }
274 
276 
286 void Rocout::put_attribute( const char* filename_pre,
287  const Attribute* attr, const char* material,
288  const char* timelevel, const char* mfile_pre,
289  const MPI_Comm* pComm, const int* pane_id)
290 {
291  //std::cout << __FILE__ << __LINE__ << std::endl;
292  //std::cout << "Attribute = " << (attr)->fullname() << std::endl;
293  //std::cout << "Size = " << (attr)->size_of_items() << std::endl;
294  WriteAttrInfo* pWAI;
295 
296 #ifdef USE_PTHREADS
297  if (_options["async"] == "off") {
298 #endif // USE_PTHREADS
299  pWAI = new WriteAttrInfo(this, filename_pre, attr, material, timelevel,
300  mfile_pre, pComm, pane_id, 0);
301  write_attr_internal(pWAI);
302 #ifdef USE_PTHREADS
303  } else {
304  pWAI = new WriteAttrInfo(this, filename_pre, attr, material, timelevel,
305  mfile_pre, pComm, pane_id, 0, true);
306  pthread_attr_t attr;
307  pthread_attr_init(&attr);
308  pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
309 
310  pthread_t id;
311  pthread_create(&id, &attr, write_attr_internal, pWAI);
312  pthread_attr_destroy(&attr);
313  _writers.push_back(id);
314  }
315 #endif // USE_PTHREADS
316 }
317 
319 
329 void Rocout::add_attribute( const char* filename_pre,
330  const Attribute* attr, const char* material,
331  const char* timelevel, const char* mfile_pre,
332  const MPI_Comm* pComm, const int* pane_id)
333 {
334  //std::cout << __FILE__ << __LINE__ << std::endl;
335  //std::cout << "Attribute = " << (attr)->fullname() << std::endl;
336  //std::cout << "Size = " << (attr)->size_of_items() << std::endl;
337  WriteAttrInfo* pWAI;
338 
339 #ifdef USE_PTHREADS
340  if (_options["async"] == "off") {
341 #endif // USE_PTHREADS
342  pWAI = new WriteAttrInfo(this, filename_pre, attr, material, timelevel,
343  mfile_pre, pComm, pane_id, 1);
344  write_attr_internal(pWAI);
345 #ifdef USE_PTHREADS
346  } else {
347  pWAI = new WriteAttrInfo(this, filename_pre, attr, material, timelevel,
348  mfile_pre, pComm, pane_id, 1, true);
349  pthread_attr_t attr;
350  pthread_attr_init(&attr);
351  pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
352 
353  pthread_t id;
354  pthread_create(&id, &attr, write_attr_internal, pWAI);
355  pthread_attr_destroy(&attr);
356  _writers.push_back(id);
357  }
358 #endif // USE_PTHREADS
359 }
360 
361 void Rocout::write_rocin_control_file(const char* window_name,
362  const char* file_prefixes,
363  const char* control_file_name)
364 {
365  const MPI_Comm default_comm = COM_get_default_communicator();
366  const MPI_Comm comm_null = MPI_COMM_NULL;
367  const MPI_Comm* myComm = COMMPI_Initialized() ? &default_comm : &comm_null;
368 
369 
370  // Obtain process rank
371  int flag = 0, rank = 0, size = 1;
372  MPI_Initialized(&flag);
373 
374  if (flag) {
375  MPI_Comm_rank(*myComm, &rank);
376  MPI_Comm_size(*myComm, &size);
377  }
378 
379  if (rank == 0) {
380  std::vector<std::vector<int> > paneIds(size);
381 
382  /* Get list of panes local each process */
383  int i;
384  for (i=0; i<size; ++i)
385  COM_get_panes(window_name, paneIds[i], i);
386 
387  int rw, pw;
388  {
389  std::istringstream sin(_options["rankwidth"]);
390  sin >> rw;
391  }
392  {
393  std::istringstream sin(_options["pnidwidth"]);
394  sin >> pw;
395  }
396 
397 /*
398  std::ostringstream sout;
399  sout << "@Files:";
400 
401  // Write out file name pattern only if number of panes is nonzero.
402  std::istringstream sin(file_prefixes);
403  while (!sin.eof()) {
404  std::string prefix;
405  sin >> prefix;
406  if (prefix.empty())
407  continue;
408 
409  sout << ' ' << prefix;
410  if (rw > 0)
411  sout << "%0" << rw << 'p';
412  if (pw > 0) {
413  if (rw > 0)
414  sout << _options["separator"];
415  sout << "%0" << pw << 'i';
416  }
417 
418  const std::string fmt = _options["format"];
419  if ( fmt == "HDF4" || fmt == "HDF")
420  sout << ".hdf";
421  else if (fmt == "HDF5")
422  sout << ".hdf5";
423  else if (fmt == "CGNS")
424  sout << ".cgns";
425  }
426 */
427 
428  /* Now write data into control file */
429  std::ofstream fout(control_file_name);
430  COM_assertion_msg( fout.is_open(),
431  (std::string("Rocout cannot open control file:")+control_file_name+" for writing.\n").c_str());
432 
433  const std::string fmt = _options["format"];
434  for (i=0; i<size; i++) {
435  fout << "@Proc: " << i << std::endl;
436  if ( !paneIds[i].empty()) {
437  std::ostringstream sout;
438  sout << "@Files:";
439 
440  // Write out file name pattern only if number of panes is nonzero.
441  std::istringstream sin(file_prefixes);
442  while (!sin.eof()) {
443  std::string prefix;
444  sin >> prefix;
445  if (prefix.empty())
446  continue;
447 
448  sout << ' ';
449  // write output file in <rank> dir
450  if (_options["rankdir"] == "on") {
451  std::ostringstream rank_prefix;
452  rank_prefix << i << "/";
453  sout << rank_prefix.str();
454  }
455  sout << prefix;
456  if (rw > 0)
457  sout << "%0" << rw << 'p';
458  if (pw > 0) {
459  if (rw > 0)
460  sout << _options["separator"];
461  sout << "%0" << pw << 'i';
462  }
463 
464  if ( fmt == "HDF4" || fmt == "HDF")
465  sout << ".hdf";
466  else if (fmt == "HDF5")
467  sout << ".hdf5";
468  else if (fmt == "CGNS")
469  sout << ".cgns";
470  }
471  fout << sout.str() << std::endl;
472  }
473  else // Write out an empty block
474  fout << "@Files: " << std::endl;
475 
476  fout << "@Panes:";
477 
478  /* Write all the panes of this process to control file */
479  std::vector<int>::iterator p;
480  for (p=paneIds[i].begin(); p!=paneIds[i].end(); ++p)
481  fout << ' ' << *p;
482  fout << '\n' << std::endl;
483  }
484 
485  fout.close();
486  }
487 }
488 
492 {
493 #ifdef USE_PTHREADS
494  void* ret;
495  std::vector<pthread_t>::iterator p = _writers.begin();
496  while (p != _writers.end()) {
497  pthread_join(*p, &ret);
498  ++p;
499  }
500  _writers.clear();
501 #endif // USE_PTHREADS
502 }
503 
506 static bool is_option_name(const std::string& name)
507 {
508  return (name == "format" || name == "async" || name == "mode"
509  || name == "localdir" || name == "rankwidth" || name == "pnidwidth"
510  || name == "separator" || name == "errorhandle" || name == "rankdir"
511  || name == "ghosthandle");
512 }
513 
514 // Return true if the given string is a whole number.
515 static bool is_whole(const std::string& s)
516 {
517  if (s.empty())
518  return false;
519 
520  std::istringstream sin(s);
521  int i = 0;
522  sin >> i;
523  return (i >= 0 && sin.eof());
524 }
525 
528 static bool is_option_value(const std::string& name, const std::string& val)
529 {
530  return ((name == "format"
531  && (val == "HDF" || val == "HDF4" || val == "HDF5" || val == "CGNS"))
532  || (name == "async"
533  && (val == "on" || val == "off"))
534  || (name == "mode"
535  && (val == "w" || val == "a"))
536  || (name == "localdir" /* && is_valid_path(val) */ )
537  || ((name == "rankwidth" || name == "pnidwidth") && is_whole(val))
538  || (name == "rankdir"
539  && (val == "on" || val == "off"))
540  || (name == "errorhandle"
541  && (val == "abort" || val == "ignore" || val == "warn"))
542  || (name == "ghosthandle"
543  && (val == "write" || val == "ignore")));
544 }
545 
552 void Rocout::set_option( const char* option_name, const char* option_val)
553 {
554  const std::string name(option_name);
555  const std::string val(option_val);
556 
557  if (!is_option_name(name)) {
558  ERROR_MSG("Rocout::set_option(): unknown option name \"" << name << "\".");
559  return;
560  }
561 
562  if (!is_option_value(name, val)) {
563  ERROR_MSG("Rocout::set_option(): invalid value \"" << val
564  << "\" for option \"" << name << "\".");
565  return;
566  }
567 
568 #ifndef USE_CGNS
569  COM_assertion_msg(name != "format" || val != "CGNS",
570  "Roccom not built with option CGNS=1.\n");
571 #endif // USE_CGNS
572 
573  _options[name] = val;
574 }
575 
580 void Rocout::read_control_file( const char* filename)
581 {
582  // Attempt to open the control file.
583  std::ifstream fin(filename);
584  if (!fin.is_open()) {
585  ERROR_MSG("Rocout::read_control_file(): could not open file \""
586  << filename << "\".");
587  return;
588  }
589 
590  // Each line of the control file should be of the form "option_name=value",
591  // e.g. "format=HDF4". White space at the beginning, end, and around the
592  // '=' is ignored, as are empty lines and comments (lines that start with
593  // '#').
594  int lineNum = 0;
595  char buffer[256];
596  std::string line, name, val;
597  std::string::size_type eq;
598  while (!fin.eof()) {
599  ++lineNum;
600  // Read a line.
601  fin.getline(buffer, sizeof(buffer));
602  line = buffer;
603 
604  // Skip empty lines and comments.
605  if (line.empty() || line.find_first_not_of(" \t\n") == std::string::npos
606  || line[line.find_first_not_of(" \t\n")] == '#')
607  continue;
608 
609  // Find the '='. It's mandatory.
610  eq = line.find('=');
611  if (eq == std::string::npos) {
612  ERROR_MSG("Rocout::read_control_file(): option without value at line "
613  << lineNum << " of " << filename << '.');
614  continue;
615  }
616 
617  // Split the line into an option name and a value.
618  name = line.substr(0, eq);
619  val = line.substr(eq + 1);
620 
621  // Remove leading whitespace from the option name.
622  if (name.find_first_not_of(" \t\n") != 0)
623  name.erase(0, name.find_first_not_of(" \t\n"));
624 
625  // Check for an empty option name.
626  if (name.empty()) {
627  ERROR_MSG("Rocout::read_control_file(): missing option name at line "
628  << lineNum << " of " << filename << '.');
629  continue;
630  }
631 
632  // Remove trailing whitespace from the option name.
633  if (name.find_last_not_of(" \t\n") != name.length() - 1)
634  name.erase(name.find_last_not_of(" \t\n") + 1);
635 
636  // Make sure it is a valid option name.
637  if (!is_option_name(name)) {
638  ERROR_MSG("Rocout::read_control_file(): unknown option name \"" << name
639  << "\" at line " << lineNum << " of " << filename << '.');
640  continue;
641  }
642 
643  // Remove leading whitespace from the option value.
644  if (val.find_first_not_of(" \t\n") != 0)
645  val.erase(0, val.find_first_not_of(" \t\n"));
646 
647  // Check for an empty option value.
648  if (val.empty()) {
649  ERROR_MSG("Rocout::read_control_file(): option without value at line "
650  << lineNum << " of " << filename << '.');
651  continue;
652  }
653 
654  // Remove trailing whitespace from the option value.
655  if (val.find_last_not_of(" \t\n") != val.length() - 1)
656  val.erase(val.find_last_not_of(" \t\n") + 1);
657 
658  // Make sure it is a valid value for the named option.
659  if (!is_option_value(name, val)) {
660  ERROR_MSG("Rocout::read_control_file(): invalid value \"" << val
661  << "\" for option \"" << name << "\" at line " << lineNum
662  << " of " << filename << '.');
663  continue;
664  }
665 
666  set_option(name.c_str(), val.c_str());
667  }
668 }
669 
670 void* Rocout::write_attr_internal(void* attrInfo)
671 {
672  WriteAttrInfo* ai = static_cast<WriteAttrInfo*>(attrInfo);
673  const Attribute* attr = ai->m_attr;
674  Window* tempWin = NULL;
675 
676  if (ai->m_cloned) {
677 #ifdef USE_PTHREADS
678  _writesem.Wait();
679 #endif // USE_PTHREADS
680  tempWin = new Window(attr->window()->name(),
681  attr->window()->get_communicator());
682  attr = tempWin->inherit(const_cast<Attribute*>(attr), attr->name(),
683  Pane::INHERIT_CLONE, true, NULL, 0);
684  }
685 
686  int flag = 0; MPI_Initialized(&flag);
687 
688  // Obtain process rank
689  int rank;
690  if ( flag) {
691  MPI_Comm wcomm;
692  const MPI_Comm* pComm;
693 
694  if ( ai->m_pComm)
695  pComm = ai->m_pComm;
696  else {
697  wcomm = attr->window()->get_communicator();
698  pComm = &wcomm;
699  }
700 
701  if (*pComm != MPI_COMM_NULL)
702  MPI_Comm_rank(*pComm, &rank);
703  else
704  rank = 0;
705  }
706  else
707  rank = 0;
708 
709  int append = ai->m_append;
710  //std::cout << " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ " << std::endl;
711  //std::cout << __FILE__ << __LINE__
712  // << " append = " << append << std::endl;
713  if (append < 0) {
714  if (ai->m_rout->_options["mode"] == "w")
715  append = 0;
716  else
717  append = 1;
718  }
719 
720  std::vector<int> paneIds;
721  COM_get_panes(attr->window()->name().c_str(), paneIds);
722 
723  std::vector<int>::iterator begin = paneIds.begin(), end = paneIds.end(), p;
724  if (ai->m_pPaneId != NULL && *(ai->m_pPaneId) > 0) {
725  begin = std::find(begin, end, *(ai->m_pPaneId));
726  if (begin != end)
727  end = begin + 1;
728  }
729 
730  // MS
731  /*
732  std::cout << __FILE__ << __LINE__ << std::endl;
733  std::cout << "Attribute requested = " << attr->fullname() << std::endl;
734  std::cout << "Location = " << attr->location() << std::endl;
735  std::cout << "Size of items = " << attr->size_of_items() << std::endl;
736  std::cout << "Size of components = " << attr->size_of_components() << std::endl;
737  std::cout << "Window information :" << std::endl;
738  std::string wname = attr->window()->name();
739  int nNde;
740  for (p=begin; p!=end; ++p) {
741  std::cout << " pane = " << *p << std::endl;
742  COM_get_size((wname+".nc").c_str(), *p, &nNde);
743  std::cout << " number of nodes = " << nNde << std::endl;
744  std::string stringNames;
745  int numConn;
746  COM_get_connectivities(wname.c_str(), *p, &numConn, stringNames);
747  std::istringstream ConnISS(stringNames);
748  std::vector<std::string> connNames;
749  std::cout << "\t # \t Type \t #Elm \t #ElmNde \t Loc \n";
750  std::cout << "\t---\t------\t------\t---------\t-----\n";
751  for (int i=0; i<numConn; ++i) {
752  std::string name;
753  ConnISS >> name;
754  connNames.push_back(name);
755  std::string fullConnName(wname+"."+name);
756  int nElm;
757  COM_get_size(fullConnName, *p, &nElm);
758  int nElmNde;
759  std::string dataItemUnits;
760  char dataItemLoc;
761  COM_Type dataItemType;
762  COM_get_attribute(fullConnName, &dataItemLoc, &dataItemType,
763  &nElmNde, &dataItemUnits);
764  std::cout << "\t " << i+1
765  << "\t " << name
766  << "\t " << nElm
767  << "\t " << nElmNde
768  << "\t " << dataItemLoc
769  << std::endl;
770  }
771  }
772  std::cout << " ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ " << std::endl;
773  */
774  // MS End
775 
776  std::set<std::string> written;
777  for (p=begin; p!=end; ++p) {
778  //std::cout << __FILE__ << __LINE__
779  // << " pane = " << *p << std::endl;
780  std::string fname, mfile;
781  fname = ai->m_rout->get_fname(ai->m_prefix, rank, *p, true);
782  //std::cout << " fname = " << fname << std::endl;
783  if (!ai->m_meshPrefix.empty())
784  mfile = ai->m_rout->get_fname(ai->m_meshPrefix, rank, *p);
785 
786  int ap = append + written.count(fname);
787  written.insert(fname);
788 
789  const std::string fmt = ai->m_rout->_options["format"];
790  if ( fmt == "HDF4" || fmt == "HDF") {
791 
792  write_attr_HDF4(fname, mfile, attr, ai->m_material.c_str(),
793  ai->m_timelevel.c_str(), *p,
794  ai->m_rout->_options["errorhandle"], ap);
795 
796  } else if ( fmt == "CGNS") {
797 #ifdef USE_CGNS
798  write_attr_CGNS(fname, mfile, attr, ai->m_material.c_str(),
799  ai->m_timelevel.c_str(), *p,
800  ai->m_rout->_options["ghosthandle"],
801  ai->m_rout->_options["errorhandle"], ap);
802 #endif // USE_CGNS
803 
804  }
805  }
806 
807  if (ai->m_cloned) {
808 #ifdef USE_PTHREADS
809  _writesem.Post();
810 #endif // USE_PTHREADS
811  delete tempWin;
812  }
813 
814  delete ai;
815 
816  return NULL;
817 }
818 
825 std::string Rocout::get_fname(const std::string& prefix,
826  int rank /* = -1 */,
827  int paneId /* = 0 */,
828  bool check /* = false */)
829 {
830  // Modify the prefix using the "localdir" option.
831  std::string pre(_options["localdir"]);
832  if (!pre.empty()) {
833  // Make sure there's exactly one '/' between the localdir and given prefix.
834  if (prefix[0] == '/') {
835  if (pre[pre.length()-1] == '/')
836  pre.erase(pre.length() - 1);
837  } else {
838  if (pre[pre.length()-1] != '/')
839  pre += '/';
840  }
841  }
842  pre += prefix;
843 
844  if (_options["rankdir"] == "on") { // write output file in <rank> dir
845  std::ostringstream rank_prefix;
846  rank_prefix << "/" << rank;
847  std::string::size_type s = pre.find_last_of('/');
848  if (s != std::string::npos)
849  pre.insert(s, rank_prefix.str());
850  }
851 
852  // Make sure the directory exists. Ignore any errors except for the last.
853  int result = 0;
854  std::string::size_type s = pre.find('/', 1);
855  while (s != std::string::npos) {
856  result = mkdir(pre.substr(0, s).c_str(), 0755);
857  s = pre.find('/', s + 1);
858  }
859  if (result < 0 && errno != EEXIST) {
860  ERROR_MSG("Rocout::write_attribute(): could not create directory '"
861  << pre.substr(0, pre.rfind('/') + 1) << "'.");
862  }
863 
864  if ( pre.find(".hdf") == pre.size()-4) {
865  _options["format"] = "HDF4";
866  return pre;
867  }
868  else if (pre.find(".cgns") == pre.size()-5) {
869  _options["format"] = "CGNS";
870  return pre;
871  }
872 
873  if (rank < 0) {
874  int flag = 0;
875  MPI_Initialized(&flag);
876  if (flag)
877  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
878  else
879  rank = 0;
880  }
881 
882  std::string name;
883 
884  if (!pre.empty()) {
885  int rw, pw;
886  {
887  std::istringstream sin(_options["rankwidth"]);
888  sin >> rw;
889  }
890  {
891  std::istringstream sin(_options["pnidwidth"]);
892  sin >> pw;
893  }
894 
895  std::ostringstream sout;
896  sout << pre;
897  if (rw > 0)
898  sout << std::setw(rw) << std::setfill('0') << rank;
899  if (pw > 0 && paneId > 0) {
900  if (rw > 0)
901  sout << _options["separator"];
902  sout << std::setw(pw) << std::setfill('0') << paneId;
903  }
904 
905  const std::string fmt = _options["format"];
906  if ( fmt == "HDF" || fmt == "HDF4")
907  sout << ".hdf";
908  else if (fmt == "HDF5")
909  sout << ".hdf5";
910  else if (fmt == "CGNS")
911  sout << ".cgns";
912 
913  name = sout.str();
914 
915  if (check) {
916  std::FILE* f;
917  if ((f = std::fopen(name.c_str(), "r")) != NULL)
918  std::fclose(f);
919  else if ((f = std::fopen(name.c_str(), "w")) != NULL) {
920  std::fclose(f);
921  std::remove(name.c_str());
922  } else {
923  // Change the directory to current directory
924  std::string::size_type n = name.rfind('/');
925  if (n != std::string::npos)
926  name.erase(0, n + 1);
927  }
928  }
929  }
930 
931  return name;
932 }
933 
934 extern "C" void Rocout_load_module( const char *name)
935 { Rocout::init( std::string(name)); }
936 
937 extern "C" void Rocout_unload_module( const char *name)
938 { Rocout::finalize( std::string(name)); }
939 
940 #ifndef DOXYGEN_SHOULD_SKIP_THIS
941 // All possible Fortran bindings
942 
943 extern "C" void COM_F_FUNC2(rocout_load_module, ROCOUT_LOAD_MODULE)( const char *name, long int length)
944 { Rocout_load_module( std::string(name, length).c_str()); }
945 extern "C" void COM_F_FUNC2(rocout_unload_module, ROCOUT_UNLOAD_MODULE)( const char *name, long int length)
946 { Rocout_unload_module( std::string(name, length).c_str()); }
947 
948 #endif // DOXYGEN_SHOULD_SKIP_THIS
949 
950 
951 
952 
953 
954 
955 
const bool m_cloned
Definition: Rocout.C:71
const Attribute * m_attr
Definition: Rocout.C:64
std::string get_fname(const std::string &pre, int rank=-1, const int paneId=0, bool check=false)
Builds a filename from the given prefix and rank.
Definition: Rocout.C:825
int COM_Type
Indices for derived data types.
Definition: roccom_basic.h:122
static void finalize(const std::string &mname)
Finalize the module by deregistering it from Roccom.
Definition: Rocout.C:213
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_COMM_WORLD
void write_parameter_file(const char *file_name, const char *window_name, const MPI_Comm *comm=NULL)
Write out the parameters defined in the fiven window into a parameter file.
void set_option(const char *option_name, const char *option_val)
Set an option for Rocout, such as controlling the output format.
Definition: Rocout.C:552
Pass write_attribute arguments to the background worker thread.
Definition: Rocout.C:52
here we put it at the!beginning of the common block The point to point and collective!routines know about but MPI_TYPE_STRUCT as yet does not!MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE are similar objects!Until the underlying MPI library implements the C version of these are declared as arrays of MPI_STATUS_SIZE!The types and are OPTIONAL!Their values are zero if they are not available Note that!using these reduces the portability of MPI_IO INTEGER MPI_BOTTOM INTEGER MPI_DOUBLE_PRECISION INTEGER MPI_LOGICAL INTEGER MPI_2REAL INTEGER MPI_2DOUBLE_COMPLEX INTEGER MPI_LB INTEGER MPI_WTIME_IS_GLOBAL INTEGER MPI_COMM_SELF
const std::string m_timelevel
Definition: Rocout.C:66
static bool is_whole(const std::string &s)
Definition: Rocout.C:515
An Attribute object is a data member of a window.
Definition: Attribute.h:51
void COM_delete_window(const char *wname)
Definition: roccom_c++.h:94
#define COM_assertion_msg(EX, msg)
double s
Definition: blastest.C:80
void put_attribute(const char *filename_pre, const COM::Attribute *attr, const char *material, const char *timelevel, const char *mfile_pre=NULL, const MPI_Comm *comm=NULL, const int *pane_id=NULL)
Write a (possibly aggregate) attribute to a new file.
Definition: Rocout.C:286
Declaration of Rocout CGNS routines.
A Window object contains multiple panes and multiple data attributes.
Definition: Window.h:42
static void * write_attr_internal(void *attrInfo)
Does the actual writing to file.
Definition: Rocout.C:670
const MPI_Comm * m_pComm
Definition: Rocout.C:68
boolean empty(T_VertexSet s)
Definition: Sync.h:65
const std::string m_prefix
Definition: Rocout.C:63
void add_attribute(const char *filename_pre, const COM::Attribute *attr, const char *material, const char *timelevel, const char *mfile_pre=NULL, const MPI_Comm *comm=NULL, const int *pane_id=NULL)
Append a (possibly aggregate) attribute to a file.
Definition: Rocout.C:329
const std::string & name() const
Obtain the window&#39;s name.
Definition: Window.h:92
void COM_set_object(const char *wa_str, int pane_id, Type *addr)
Definition: roccom_c++.h:144
WriteAttrInfo(Rocout *rout, const char *filename_pre, const Attribute *attr, const char *material, const char *timelevel, const char *mfile_pre=NULL, const MPI_Comm *pComm=NULL, const int *pane_id=NULL, int append=-1, bool cloned=false)
Definition: Rocout.C:53
int fclose(std::FILE *file)
Close a file, and check for possible errors.
Definition: CImg.h:5507
const Window * window() const
Obtain a constant pointer to the parent window of the attribute.
Definition: Attribute.C:80
static bool is_option_name(const std::string &name)
Return true if the given string is the name of a Rocout option.
Definition: Rocout.C:506
void write_attr_CGNS(const std::string &fname, const std::string &mfile, const COM::Attribute *attr, const char *material, const char *timelevel, int pane_id, const std::string &ghosthandle, const std::string &errorhandle, int mode)
Write the data for the given attribute to file.
Definition: Rocout_cgns.C:884
#define COM_F_FUNC2(lowcase, uppercase)
Definition: roccom_basic.h:87
#define ERROR_MSG(msg)
Definition: Rocout.C:123
void write_attribute(const char *filename_pre, const COM::Attribute *attr, const char *material, const char *timelevel, const char *mfile_pre=NULL, const MPI_Comm *comm=NULL, const int *pane_id=NULL)
Write a (possibly aggregate) attribute to a file.
Definition: Rocout.C:246
double length(Vector3D *const v, int n)
void COM_get_object(const char *wa_str, int pane_id, Type **addr)
Definition: roccom_c++.h:152
Rocout creates a series of Roccom windows by reading in a list of files.
static void init()
Create and start the I/O thread.
Definition: HDF4.C:108
MPI_Comm get_communicator() const
Obtain the communicator of the window.
Definition: Window.h:95
NT & sin
void sync()
Wait for the completion of an asychronous write operation.
Definition: Rocout.C:491
Definition: Rocout.h:81
const int * m_pPaneId
Definition: Rocout.C:69
blockLoc i
Definition: read.cpp:79
std::map< std::string, std::string > _options
Definition: Rocout.h:235
void COM_window_init_done(const char *w_str, int pane_changed=true)
Definition: roccom_c++.h:102
const int m_append
Definition: Rocout.C:70
static bool is_option_value(const std::string &name, const std::string &val)
Return true if the given Rocout option name/value pair is valid.
Definition: Rocout.C:528
const NT & n
static void init(const std::string &mname)
Initialize the module by registering it to Roccom with the given module name.
Definition: Rocout.C:139
void COM_new_window(const char *wname, MPI_Comm c=MPI_COMM_NULL)
Definition: roccom_c++.h:86
void write_rocin_control_file(const char *window_name, const char *file_prefixes, const char *control_file_name)
Generate a control file for Rocin.
Definition: Rocout.C:361
static void finalize()
Destroy the I/O thread.
Definition: HDF4.C:128
void Rocout_load_module(const char *name)
Load the module Rocout into Roccom using the given module name.
Definition: Rocout.C:934
unsigned long id(const Leda_like_handle &x)
Definition: Handle.h:107
void COM_new_attribute(const char *wa_str, const char loc, const int type, int ncomp, const char *unit)
Registering an attribute type.
Definition: roccom_c++.h:118
void COM_get_panes(const char *wname, std::vector< int > &pane_ids, int rank=-2)
Definition: roccom_c++.h:350
void COM_set_member_function(const char *wf_str, Member_func_ptr func, const char *wa_str, const char *intents, const COM_Type *types)
Definition: roccom_c++.h:330
static int rank
Definition: advectest.C:66
int COMMPI_Initialized()
Definition: commpi.h:168
MPI_Comm COM_get_default_communicator()
Definition: roccom_c++.h:69
void write_attr_HDF4(const std::string &fname, const std::string &mfile, const COM::Attribute *attr, const char *material, const char *timelevel, int pane_id, const std::string &errorhandle, int mode)
Definition: Rocout_hdf4.C:130
void read_control_file(const char *filename)
Set options for Rocout via a control file.
Definition: Rocout.C:580
static USE_COM_NAME_SPACE const int MAX_ASYNC_WRITES
Definition: Rocout.C:49
const std::string m_material
Definition: Rocout.C:65
const std::string m_meshPrefix
Definition: Rocout.C:67
std::FILE * fopen(const char *const path, const char *const mode)
Open a file, and check for possible errors.
Definition: CImg.h:5494
void Rocout_unload_module(const char *name)
Unload the module Rocout from Roccom.
Definition: Rocout.C:937
Attribute * inherit(Attribute *from, const std::string &aname, int inherit_mode, bool withghost, const Attribute *cond, int val)
Inherit the attributes of another window with a different name.
Definition: Window.C:334
Rocout * m_rout
Definition: Rocout.C:62
std::vector< int > paneIds
Array of paneIds.
Definition: hdf2pltV2.C:60