Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Rocout_hdf4.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 <cmath>
31 #include <cstdlib>
32 #include <fstream>
33 #include <iomanip>
34 #include <iostream>
35 #include <ostream>
36 #include <sstream>
37 #include <string>
38 #include <cstring>
39 #include <algorithm>
40 #include <strings.h>
41 
42 #include "Rocout.h"
43 #include "HDF4.h"
44 
45 #ifndef DOXYGEN_SHOULD_SKIP_THIS
46 USE_COM_NAME_SPACE
47 #endif
48 
49 // #define DEBUG_DUMP_PREFIX "/turing/home/jnorris/rocout/"
50 // #define DEBUG_MSG(x) std::cout << "ROCOUT DEBUG: " << __LINE__ << ": " << x << std::endl
51 #define DEBUG_MSG(x)
52 
53 
54 #ifdef DEBUG_DUMP_PREFIX
55 static std::string s_material;
56 static std::string s_timeLevel;
57 static std::ofstream* s_fout = NULL;
58 #endif // DEBUG_DUMP_PREFIX
59 
60 static void io_pane(const char* fname, const COM::Pane* pane,
61  const COM::Attribute* attr, const char* material,
62  const char* timelevel, const char* mfile,
63  const std::string& errorhandle, const int mode);
64 
65 static void io_pane_header(const char* fname, const COM::Pane* pane,
66  const char* blockname, const char* material,
67  const char* timelevel, const char* mfile,
68  const std::string& errorhandle, const int mode);
69 
70 static void io_pane_coordinates(const char* fname, const COM::Pane* pane,
71  const char* timelevel, const char* coordsys,
72  const char* unit,
73  const std::string& errorhandle, const int mode);
74 
75 static void io_pane_connectivity(const char* fname, const COM::Pane* pane,
76  const char* timelevel, const char* coordsys,
77  const std::string& errorhandle,
78  const int mode);
79 
80 static void io_pane_attribute(const char* fname, const COM::Pane* pane,
81  const COM::Attribute* attr, const char* timelevel,
82  const char* coordsys,
83  const std::string& errorhandle, const int mode);
84 
85 static void io_hdf_data(const char* fname, const char* label, const char* units,
86  const char* format, const char* coordsys, int rank,
87  int shape[], int ng1, int ng2, int dim,
88  const COM_Type type, const void* p, int stride,
89  const std::string& errorhandle, const int mode,
90  const void* minv, const void* maxv);
91 
92 static void min_element(const void* begin, const int rank, const int shape[],
93  const int ng1, const int ng2, const COM_Type type,
94  void* f);
95 
96 static void max_element(const void* begin, const int rank, const int shape[],
97  const int ng1, const int ng2, const COM_Type type,
98  void* f);
99 
100 static void squared_sum(const void* a, const int length, const int stride,
101  const COM_Type type, void* ssum);
102 
103 static void min_sqrt_element(const void* begin, const int rank,
104  const int shape[], const int ng1, const int ng2,
105  const COM_Type type, void* v);
106 
107 static void max_sqrt_element(const void* begin, const int rank,
108  const int shape[], const int ng1, const int ng2,
109  const COM_Type type, void* v);
110 
111 /*
112 static void hdf_error_message(const char* s, int i,
113  const std::string& errorhandle);
114  */
115 
116 static int write_data(const char* fname, const char* label, const char* units,
117  const char* format, const char* coordsys, const int _rank,
118  const int _shape[], const int ng1, const int ng2,
119  const COM_Type type, const void* p, const void* minv,
120  const void* maxv, const std::string& errorhandle,
121  const int mode = 1);
122 
123 static int comtype2hdftype(COM_Type i);
124 
125 inline void append_str(std::vector<char>& vec, const char* str)
126 {
127  vec.insert(vec.end(), str, str + std::strlen(str));
128 }
129 
130 void write_attr_HDF4(const std::string& fname, const std::string& mfile,
131  const COM::Attribute* attr, const char* material,
132  const char* timelevel, int pane_id,
133  const std::string& errorhandle, int mode)
134 {
135  const Window* w = attr->window();
136  COM_assertion(w != NULL);
137  const Pane& pn = w->pane(pane_id);
138  io_pane(fname.c_str(), &pn, attr, material, timelevel,
139  !mfile.empty() ? mfile.c_str() : NULL, errorhandle, mode);
140 }
141 
142 static void io_pane(const char* fname, const COM::Pane* pane,
143  const COM::Attribute* attr, const char* material,
144  const char* timelevel, const char* mfile,
145  const std::string& errorhandle, const int mode)
146 {
147  char buf[20];
148  std::sprintf(buf, "%04d", pane->id());
149  std::string blockname = buf;
150 
151  std::string coordsys(material);
152  coordsys.append("|");
153  coordsys.append(blockname);
154 
155  bool with_mesh = mfile == NULL || std::strlen(mfile) == 0 ||
156  attr->id() == COM::COM_MESH || attr->id() == COM::COM_PMESH ||
157  attr->id() == COM::COM_ALL;
158 
159 #ifdef DEBUG_DUMP_PREFIX
160  s_material = material;
161  {
162  double f;
163  std::istringstream in(timelevel);
164  in >> f;
165  std::ostringstream out;
166  out << f;
167  s_timeLevel = out.str();
168  }
169 #endif // DEBUG_DUMP_PREFIX
170 
171  // Write the pane header only when writing the mesh, or coordinates,
172  // or if mfile is present but not the same with fname.
173  if ( with_mesh || attr->id() == COM::COM_NC ||
174  mfile && std::strcmp( fname, mfile) )
175  io_pane_header(fname, pane, blockname.c_str(), material,
176  timelevel, mfile, errorhandle, mode);
177 
178  if (with_mesh) {
179  COM_assertion_msg( attr->id() != COM_NC && attr->id() != COM_CONN &&
180  attr->id() != COM_PCONN,
181  "Must not write mesh along with nc, conn or pconn");
182 
183  // Write out coordinates
184  io_pane_coordinates( fname, pane, timelevel, coordsys.c_str(),
185  pane->attribute(COM::COM_NC)->unit().c_str(),
186  errorhandle, mode);
187 
188  // Write out connectivity
189  io_pane_connectivity( fname, pane, timelevel, coordsys.c_str(),
190  errorhandle, mode);
191 
192  // Write out ridges
193  io_pane_attribute( fname, pane, pane->attribute(COM::COM_RIDGES),
194  timelevel, NULL, errorhandle, mode);
195  if (attr->id() == COM::COM_MESH) return;
196 
197  // Write out pane connectivity
198  io_pane_attribute( fname, pane, pane->attribute(COM::COM_PCONN),
199  timelevel, NULL, errorhandle, mode);
200  if (attr->id() == COM::COM_PMESH) return;
201  }
202 
203  if ( attr->id() == COM::COM_CONN) {
204  // Write out connectivity
205  io_pane_connectivity( fname, pane, timelevel, coordsys.c_str(),
206  errorhandle, mode);
207  if (attr->id() == COM::COM_CONN || attr->id() == COM::COM_MESH) return;
208  }
209  else if ( attr->id() == COM::COM_ALL || attr->id() == COM::COM_ATTS) {
210  std::vector<const Attribute*> attrs;
211  pane->attributes(attrs);
212  std::vector<const Attribute*>::const_iterator it;
213  for (it=attrs.begin(); it!=attrs.end(); ++it) {
214  io_pane_attribute(fname, pane, *it, timelevel, NULL, errorhandle, mode);
215  }
216  } else {
217  // Call io_pane_attribute on the attribute in the given pane.
218  io_pane_attribute( fname, pane, pane->attribute(attr->id()),
219  timelevel, NULL, errorhandle, mode);
220  }
221 }
222 
223 static void io_pane_header(const char* fname, const COM::Pane* pane,
224  const char* blockname, const char* material,
225  const char* timelevel, const char* mfile,
226  const std::string& errorhandle, const int mode)
227 {
228  // Mesh description array
229  int mesh_type;
230  if (pane->is_structured())
231  mesh_type = 2; // 2 for structured mesh
232  else if (pane->dimension() == 2)
233  mesh_type = 5; // 5 for surface meshes
234  else
235  mesh_type = 3; // 3 for unstructured volume mesh
236 
237  // The header now supports the new format.
238  std::ostringstream sout;
239  if (mesh_type == 2) {
240  sout << mesh_type << '|';
241  COM_assertion(pane->size_of_nodes());
242  sout << pane->size_of_ghost_layers();
243  }
244  else {
245  std::vector<const Connectivity*> elems;
246  pane->connectivities(elems);
247  sout << mesh_type << '|';
248  if (pane->size_of_nodes() == 0) // Add one dummy node
249  sout << 1;
250  else
251  sout << pane->size_of_ghost_nodes();
252 
253  // Loop through the number of connectivity tables
254  std::vector<const Connectivity*>::const_iterator it;
255  for (it=elems.begin(); it!=elems.end(); ++it) {
256  // Write out connectivity for the mesh
257  if ((*it)->size_of_items() == 0)
258  sout << ',' << 1; // Set the number of ghost (dummy) elements to 1
259  else
260  sout << ',' << (*it)->size_of_ghost_elements();
261  }
262  }
263 
264  if (mfile && std::strlen(mfile) != 0 && std::strcmp(fname, mfile) != 0)
265  sout << '|' << mfile;
266  std::string s = sout.str();
267 
268  // Write out the head
269  int shape[2];
270  shape[0] = s.size() + 1;
271 
272  write_data(fname, blockname, timelevel, "block header", material,
273  1, shape, 0, 0, COM_CHAR, s.c_str(), NULL, NULL, errorhandle,
274  mode);
275 }
276 
277 static void io_pane_coordinates(const char* fname, const COM::Pane* pane,
278  const char* timelevel, const char* coordsys,
279  const char* unit,
280  const std::string& errorhandle, const int mode)
281 {
282 #ifdef DEBUG_DUMP_PREFIX
283  s_fout = new std::ofstream((DEBUG_DUMP_PREFIX + s_material + ".nc_" + s_timeLevel + ".hdf").c_str(), std::ios_base::app);
284 #endif // DEBUG_DUMP_PREFIX
285  int ncomp=pane->attribute(COM::COM_NC)->size_of_components();
286  for ( int i=COM::COM_NC1; i<COM::COM_NC1+ncomp; ++i) {
287  io_pane_attribute(fname, pane, pane->attribute(i),
288  timelevel, coordsys, errorhandle, mode);
289  }
290 #ifdef DEBUG_DUMP_PREFIX
291  delete s_fout;
292  s_fout = NULL;
293 #endif // DEBUG_DUMP_PREFIX
294 }
295 
296 static void io_pane_connectivity(const char* fname, const COM::Pane* pane,
297  const char* timelevel, const char* coordsys,
298  const std::string& errorhandle, const int mode)
299 {
300  if (!pane->is_unstructured())
301  return;
302  // Only unstructured mesh has connectivity tables.
303 
304  std::vector<const Connectivity*> elems;
305  pane->connectivities(elems);
306  std::vector<int> conn;
307  int shape[2];
308 
309  std::vector<const Connectivity*>::const_iterator it;
310  for (it=elems.begin(); it!=elems.end(); ++it) {
311  // Write out connectivity for the mesh
312  // Defined as const to avoid error when calling pointer on immutable array
313 
314  const int* e = (*it)->pointer();
315  shape[0] = (*it)->size_of_nodes_pe();
316  shape[1] = (*it)->size_of_items();
317 
318  conn.resize(shape[0] * shape[1]);
319  const int length = (*it)->capacity();
320  bool is_staggered = ((*it)->stride() == 1);
321  int maxv, minv;
322 
323  // Encode size info in the long name
324  std::ostringstream sout;
325  sout << (*it)->name() << "|p";
326  if (shape[1])
327  // Followed by number of ghosts
328  sout << ',' << (*it)->size_of_ghost_items();
329  else
330  sout << "00"; // Followed by 0
331  sout << " AT TIME " << timelevel;
332  std::string label = sout.str();
333 
334  if (shape[1]) {
335  // Permute the connectivity array
336  for (int i=0; i<shape[1]; ++i){
337  for (int j=0; j<shape[0]; ++j) {
338  conn[j*shape[1]+i] = e[is_staggered?j*length+i:i*shape[0]+j];
339  }
340  }
341  minv = 1;
342  maxv = pane->size_of_nodes();
343  }
344  else { // Create a dummy element
345  shape[1] = 1;
346  conn.clear();
347  conn.resize(shape[0], 0);
348  maxv = minv = 0;
349  }
350 
351  // Initialize attribute name
352  std::string str = (*it)->name();
353 
354  // Perform IO
355  io_hdf_data(fname, label.c_str(), "", str.c_str(), coordsys, 2, shape,
356  0, 0, 1, COM_INT, &conn[0], 1, errorhandle, mode, &minv, &maxv);
357  }
358 }
359 
360 static void io_pane_attribute(const char* fname, const COM::Pane* pane,
361  const COM::Attribute* attr, const char* timelevel,
362  const char* coordsys,
363  const std::string& errorhandle, const int mode)
364 {
365  COM_assertion(attr);
366 #ifdef DEBUG_DUMP_PREFIX
367  bool alreadyOpen = (s_fout != NULL);
368  if (!alreadyOpen) {
369  s_fout = new std::ofstream((DEBUG_DUMP_PREFIX + s_material + '.' + attr->name() + '_' + s_timeLevel + ".hdf").c_str(), std::ios_base::app);
370  }
371 #endif // DEBUG_DUMP_PREFIX
372  int ncomp = attr->size_of_components();
373 
374  int rank, shape[3], num_items, ng1 = 0, ng2 = 0;
375  if (attr->is_nodal()) {
376  if (pane->is_unstructured()) {
377  rank = 1;
378  shape[0] = num_items = pane->size_of_nodes();
379  ng2 = pane->size_of_ghost_nodes();
380  shape[1] = shape[2] = 1;
381  } else {
382  rank = 3;
383  ng1 = ng2 = pane->size_of_ghost_layers();
384  shape[0] = pane->size_k(); // We need to reverse the order
385  shape[1] = pane->size_j();
386  shape[2] = pane->size_i();
387  num_items = shape[0] * shape[1] * shape[2];
388  }
389  }
390  else if (attr->is_elemental()) {
391  if (pane->is_unstructured()) {
392  rank = 1;
393  shape[0] = num_items = pane->size_of_elements();
394  ng2 = pane->size_of_ghost_elements();
395  shape[1] = shape[2] = 1;
396  } else {
397  rank = 3;
398  ng1 = ng2 = pane->size_of_ghost_layers();
399  shape[0] = pane->size_k() - 1;
400  shape[1] = pane->size_j() - 1;
401  shape[2] = pane->size_i() - 1;
402  if (shape[0] == 0) shape[0] = 1;
403  num_items = shape[0] * shape[1] * shape[2];
404  }
405  } else if (attr->data_type() != COM_VOID
406  && attr->data_type() != COM_F90POINTER) {
407  rank = 1;
408  shape[0] = num_items = attr->size_of_items();
409  ng2 = attr->size_of_ghost_items();
410  shape[1] = shape[2] = 1;
411  } else { // skip windowed attributes that are pointers
412  return;
413  }
414 
415  // Create a buffer for storing sqrt of values and
416  // for placeholder for empty attributes.
417  int sizeof_type = COM::Attribute::get_sizeof(attr->data_type(), 1);
418  std::vector<char> buf(std::max(num_items, 1) * sizeof_type);
419  std::fill(buf.begin(), buf.end(), 0);
420 
421  double t1, t2; // Buffer for storing the min and max
422  void* minv = NULL;
423  void* maxv = NULL;
424 
425  bool is_vector3 = ncomp==3 && (attr->is_nodal() || attr->is_elemental());
426  bool is_tensor9 = ncomp==9 && (attr->is_nodal() || attr->is_elemental());
427 
428  // Compute the range for vector and tensers
429  if (mode >= 0 && (is_vector3 || is_tensor9)) {
430  void* begin = &buf[0];
431  for (int i=0; i<ncomp; ++i) {
432  const Attribute* pa = pane->attribute(attr->id() + i + 1);
433  if (pa->pointer())
434  squared_sum(pa->pointer(), num_items, pa->stride(),
435  attr->data_type(), &buf[0]);
436  else {
437  begin = NULL;
438  break;
439  }
440  }
441 
442  minv = &t1;
443  min_sqrt_element(begin, rank, shape, ng1, ng2, attr->data_type(), &t1);
444  maxv = &t2;
445  max_sqrt_element(begin, rank, shape, ng1, ng2, attr->data_type(), &t2);
446  }
447 
448  // Initialize unit and attribute name
449  std::string unit = attr->unit();
450 
451  // Initialize label
452  std::ostringstream sout;
453  if (is_vector3)
454  sout << "x-";
455  else if (is_tensor9)
456  sout << "xx-";
457 
458  // Append the name and location of the attribute
459  std::string a_name = attr->name();
460  sout << a_name << '|' << attr->location();
461  int li0 = sout.str().size();
462  sout << ',' << ng2 << " AT TIME " << timelevel;
463 
464  DEBUG_MSG("Preparing to write attribute '" << attr->name() << "' (ncomp == "
465  << ncomp << ')');
466  // Perform IO the data
467  for (int i=0; i<ncomp; ++i) {
468  int label_index = li0;
469  const Attribute* pa = pane->attribute(attr->id() + i + (ncomp>1));
470 
471  DEBUG_MSG("Preparing to write attribute '" << pa->name() << '\'');
472  // Set label
473  std::string label = sout.str();
474  if ( is_vector3 || is_tensor9) {
475  if ( is_vector3)
476  label[0] = 'x'+i;
477  else {
478  label[0] = 'x'+ i / 3;
479  label[1] = 'x' + i % 3;
480  }
481  }
482  else if ( ncomp>1) { // Use <d>-attr as the attribute name.
483  a_name = pa->name();
484  COM_assertion( a_name.find('-')!=a_name.npos);
485  label_index += a_name.find('-') + 1;
486  label = a_name.substr(0,a_name.find('-')+1)+sout.str();
487  }
488 
489  // Special handling for coordinates.
490  if (attr->id() >= COM_NC1 && attr->id() <= COM_NC3) {
491  label[0] = label[0] + ('x' - '1');
492  a_name = "";
493  }
494 
495  if (num_items == 0) {
496  shape[0] = shape[rank-1] = 1;
497  label[label_index] = '0';
498 #ifdef DEBUG_DUMP_PREFIX
499  delete s_fout;
500  s_fout = NULL;
501 #endif // DEBUG_DUMP_PREFIX
502  } else if (pa->pointer() == NULL) {
503  label[label_index] = '@';
504 #ifdef DEBUG_DUMP_PREFIX
505  delete s_fout;
506  s_fout = NULL;
507 #endif // DEBUG_DUMP_PREFIX
508  } else {
509  label[label_index] = ',';
510  }
511 
512  // Set addr and strd
513  const void* addr = pa->pointer();
514  int strd = pa->stride();
515  if (addr == NULL) {
516  addr = &buf[0];
517  strd = 1;
518  }
519 
520  DEBUG_MSG("fname == " << fname << ", label == '" << label << "', unit == '" << unit << "', ng1 == " << ng1 << ", ng2 == " << ng2);
521  io_hdf_data(fname, label.c_str(), unit.c_str(), a_name.c_str(),
522  coordsys, rank, shape, ng1, ng2, 1, attr->data_type(),
523  addr, strd, errorhandle, mode, minv, maxv);
524  }
525 #ifdef DEBUG_DUMP_PREFIX
526  if (!alreadyOpen) {
527  delete s_fout;
528  s_fout = NULL;
529  }
530 #endif // DEBUG_DUMP_PREFIX
531 }
532 
533 
534 static void io_hdf_data(const char* fname, const char* label, const char* units,
535  const char* format, const char* coordsys, int rank,
536  int shape[], int ng1, int ng2, int dim,
537  const COM_Type type, const void* p, int stride,
538  const std::string& errorhandle, const int mode,
539  const void* minv, const void* maxv)
540 {
541  int length = shape[0];
542  for (int i=1; i<rank; ++i)
543  length *= shape[i];
544  COM_assertion(length && p);
545 
546  if (dim == 1) {
547  char crd[3];
548 
549  if (coordsys == NULL) {
550  const char* cend = std::strchr(label, '-');
551 
552  if (cend && label[0] >= 'x' && label[0] <='z') {
553  int n = cend-label;
554  COM_assertion(n < 3);
555  for (int i=0; i<n; ++i)
556  crd[i] = label[i] + ('1' - 'x');
557  crd[n] = 0;
558  } else
559  strcpy(crd, "0");
560  coordsys = crd;
561  }
562 
563  if (stride > 1) {
564  int s = COM::Attribute::get_sizeof(type, 1);
565  std::vector<char> w(s * length);
566  for (int i=0; i<length; ++i)
567  std::memcpy(&w[i*s], &((const char*)p)[i*stride*s], s);
568 
569  write_data(fname, label, units, format, coordsys,
570  rank, shape, ng1, ng2, type, &w[0], minv, maxv, errorhandle);
571  } else {
572  write_data(fname, label, units, format, coordsys,
573  rank, shape, ng1, ng2, type, p, minv, maxv, errorhandle);
574  }
575  } else {
576  COM_assertion(stride == 1);
577  int s = COM::Attribute::get_sizeof(type, 1);
578 
579  std::vector<char> coors(coordsys ? std::strlen(coordsys) + 3 : 3);
580  std::vector<char> l;
581  std::vector<char> fmt;
582  std::vector<char> w(s * length);
583  l.reserve(20);
584  fmt.reserve(std::strlen(format) + 1);
585 
586  for (int k=0; k<dim; ++k) {
587  l.clear();
588  if (coordsys)
589  std::strcpy(&coors[0], coordsys);
590  fmt.clear();
591  append_str(fmt, format);
592 
593  if (dim == 3) {
594  l.push_back('x' + k);
595  if (label != NULL) {
596  l.push_back('-');
597  append_str(l, label);
598  }
599 
600  if (coordsys == NULL) {
601  coors[0] = '1' + k;
602  coors[1] = 0;
603  }
604  } else if (dim == 9) {
605  l.resize(2);
606  l[0] = 'x' + k / 3;
607  l[1] = 'x' + k % 3;
608 
609  if (label != NULL) {
610  l.push_back('-');
611  append_str(l, label);
612  }
613 
614  if (coordsys == NULL) {
615  coors[0] = '1' + k / 3;
616  coors[1] = '1' + k % 3;
617  coors[2]=0;
618  }
619  } else if (label != NULL) {
620  std::vector<char> buf(std::strlen(label) + 5);
621  std::sprintf(&buf[0], "%d-%s", k + 1, label);
622  l = buf;
623 
624  const char* cend = std::strchr(&buf[0], ' ');
625  if (cend) {
626  fmt.clear();
627  fmt.insert(fmt.end(), (const char*)&buf[0], cend);
628  } else
629  fmt = buf;
630 
631  std::strcpy(&coors[0], "0");
632  } else {
633  l = fmt;
634  COM_assertion(coordsys);
635  }
636 
637  l.push_back(0);
638  fmt.push_back(0);
639 
640  for (int i=0; i<length; ++i)
641  std::memcpy(&w[i*s], &((const char*)p)[(i*dim+k)*s], s);
642 
643  write_data(fname, &l[0], units, &fmt[0], &coors[0],
644  rank, shape, ng1, ng2, type, &w[0], minv, maxv, errorhandle);
645  }
646  }
647 }
648 
652 template <typename T>
653 const T* min_element__(const T* begin, const int rank, const int shape[],
654  const int ng1, const int ng2)
655 {
656  if (begin == NULL)
657  return NULL;
658 
659  if (ng1 == 0 && ng2 == 0) {
660  int size = shape[0];
661  for (int i=1; i<rank; ++i)
662  size *= shape[i];
663  return std::min_element(begin, begin + size);
664  }
665 
666  const T* t = begin;
667  const T* result = NULL;
668  for (int i=0; i<shape[0]-ng2; ++i) {
669  for (int j=0; j<(rank>1?shape[1]:1); ++j) {
670  for (int k=0; k<(rank>2?shape[2]:1); ++k, ++t) {
671  if (i >= std::min(ng1, shape[0] - 1) && j >= std::min(ng1, shape[1] - 1)
672  && j < std::max(1, shape[1] - ng2)
673  && k >= std::min(ng1, shape[2] - 1)
674  && k < std::max(1, shape[2] - ng2)) {
675  if (result == NULL || *result > *t)
676  result = t;
677  }
678  }
679  }
680  }
681  return result;
682 }
683 
687 template <typename T>
688 const T* max_element__(const T* begin, const int rank, const int shape[],
689  const int ng1, const int ng2)
690 {
691  if (begin == NULL)
692  return NULL;
693 
694  if (ng1 == 0 && ng2 == 0) {
695  int size = shape[0];
696  for (int i=1; i<rank; ++i)
697  size *= shape[i];
698  return std::max_element(begin, begin + size);
699  }
700  const T* t = begin;
701  const T* result = NULL;
702  for (int i=0; i<shape[0]-ng2; ++i) {
703  for (int j=0; j<(rank>1?shape[1]:1); ++j) {
704  for (int k=0; k<(rank>2?shape[2]:1); ++k, ++t) {
705  if (i >= std::min(ng1, shape[0] - 1) && j >= std::min(ng1, shape[1] - 1)
706  && j < std::max(1, shape[1] - ng2)
707  && k >= std::min(ng1, shape[2] - 1)
708  && k < std::max(1, shape[2] - ng2)) {
709  if (result == NULL || *result < *t)
710  result = t;
711  }
712  }
713  }
714  }
715  return result;
716 }
717 
718 #ifndef HUGE_VALF
719 #define HUGE_VALF 1e+36F
720 #endif
721 
722 static void min_element(const void* begin, const int rank, const int shape[],
723  const int ng1, const int ng2, const COM_Type type,
724  void* f)
725 {
726  switch (type) {
727  case COM_CHAR:
728  case COM_CHARACTER: {
729  const void* p = min_element__((const char*)begin, rank, shape, ng1, ng2);
730  *(char*)f = p ? *(const char*)p : '\0';
731  return;
732  }
733 
734  case COM_INT:
735  case COM_INTEGER: {
736  const void* p = min_element__((const int*)begin, rank, shape, ng1, ng2);
737  *(int*)f = p ? *(const int*)p : 0xEFFFFFFF;
738  return;
739  }
740 
741  case COM_FLOAT:
742  case COM_REAL: {
743  const void* p = min_element__((const float*)begin, rank, shape, ng1, ng2);
744  *(float*)f = p ? *(const float*)p : HUGE_VALF;
745  return;
746  }
747 
748  case COM_DOUBLE:
749  case COM_DOUBLE_PRECISION: {
750  const void* p = min_element__((const double*)begin, rank, shape, ng1,
751  ng2);
752  *(double*)f = p ? *(const double*)p : HUGE_VAL;
753  return;
754  }
755 
756  default:
757  COM_assertion(false);
758  return;
759  }
760 }
761 
762 static void max_element(const void* begin, const int rank, const int shape[],
763  const int ng1, const int ng2, const COM_Type type,
764  void* f)
765 {
766  switch (type) {
767  case COM_CHAR:
768  case COM_CHARACTER: {
769  const void* p = max_element__((const char*)begin, rank, shape, ng1, ng2);
770  *(char*)f = p ? *(const char*)p : '\0';
771  return;
772  }
773 
774  case COM_INT:
775  case COM_INTEGER: {
776  const void* p = max_element__((const int*)begin, rank, shape, ng1, ng2);
777  *(int*)f = p ? *(const int*)p : -0xEFFFFFFF;
778  return;
779  }
780 
781  case COM_FLOAT:
782  case COM_REAL: {
783  const void* p = max_element__((const float*)begin, rank, shape, ng1, ng2);
784  *(float*)f = p ? *(const float*)p : -HUGE_VALF;
785  return;
786  }
787 
788  case COM_DOUBLE:
789  case COM_DOUBLE_PRECISION: {
790  const void* p = max_element__((const double*)begin, rank, shape, ng1,
791  ng2);
792  *(double*)f = p ? *(const double*)p : -HUGE_VAL;
793  return;
794  }
795 
796  default:
797  COM_assertion(false);
798  return;
799  }
800 }
801 
802 static void squared_sum(const void* a, const int length, const int stride,
803  const COM_Type type, void* ssum)
804 {
805  switch (type) {
806  case COM_FLOAT:
807  case COM_REAL:
808  for (int i=0; i<length; ++i) {
809  float t = ((float*)a)[i*stride];
810  ((float*)ssum)[i] += t * t;
811  }
812  break;
813 
814  case COM_DOUBLE:
815  case COM_DOUBLE_PRECISION:
816  for (int i=0; i<length; ++i) {
817  double t = ((double*)a)[i*stride];
818  ((double*)ssum)[i] += t * t;
819  }
820  break;
821 
822  case COM_INT:
823  case COM_INTEGER: {
824  for (int i=0; i<length; ++i) {
825  int t = ((int*)a)[i*stride];
826  ((int*)ssum)[i] += t * t;
827  }
828  break;
829  }
830 
831  default:
832  COM_assertion(false);
833  abort();
834  }
835 }
836 
837 static void min_sqrt_element(const void* begin, const int rank,
838  const int shape[], const int ng1, const int ng2,
839  const COM_Type type, void* v)
840 {
841  switch (type) {
842  case COM_FLOAT:
843  case COM_REAL: {
844  const void* t = min_element__((const float*)begin, rank, shape, ng1, ng2);
845  if (t)
846  *(float*)v = std::sqrt(*(const float*)t);
847  else
848  *(float*)v = HUGE_VALF;
849  break;
850  }
851 
852  case COM_DOUBLE:
853  case COM_DOUBLE_PRECISION: {
854  const void* t = min_element__((const double*)begin, rank, shape, ng1,
855  ng2);
856  if (t)
857  *(double*)v = std::sqrt(*(const double*)t);
858  else
859  *(double*)v = HUGE_VAL;
860  break;
861  }
862 
863  case COM_INT:
864  case COM_INTEGER: {
865  const void* t = min_element__((const int*)begin, rank, shape, ng1,
866  ng2);
867  if (t)
868  *(int*)v = (int)std::sqrt(double(*(const int*)t));
869  else
870  *(int*)v = 0xEFFFFFFF;
871  break;
872  }
873 
874  default:
875  COM_assertion( false); abort();
876  }
877 }
878 
879 static void max_sqrt_element(const void* begin, const int rank,
880  const int shape[], const int ng1, const int ng2,
881  const COM_Type type, void* v)
882 {
883  switch (type) {
884  case COM_FLOAT:
885  case COM_REAL: {
886  const void* t = max_element__((const float*)begin, rank, shape, ng1, ng2);
887  if (t)
888  *(float*)v = std::sqrt(*(const float*)t);
889  else
890  *(float*)v = 0.;
891  break;
892  }
893 
894  case COM_DOUBLE:
895  case COM_DOUBLE_PRECISION: {
896  const void* t = max_element__((const double*)begin, rank, shape, ng1,
897  ng2);
898  if (t)
899  *(double*)v = std::sqrt(*(const double*)t);
900  else
901  *(double*)v = 0.;
902  break;
903  }
904 
905  case COM_INT:
906  case COM_INTEGER: {
907  const void* t = max_element__((const int*)begin, rank, shape, ng1,
908  ng2);
909  if (t)
910  *(int*)v = (int)std::sqrt(double(*(const int*)t));
911  else
912  *(int*)v = 0;
913  break;
914  }
915 
916  default:
917  COM_assertion(false);
918  abort();
919  }
920 }
921 
922 #include <hdf.h>
923 
924 /* Old error reporting routine
925 static void hdf_error_message(const char* s, int i,
926  const std::string& errorhandle)
927 {
928  if (errorhandle != "ignore") {
929  std::cerr << "Rocout Error: HDF routine " << s << " returned value " << i
930  << ": " << std::endl;
931  if (errorhandle == "abort") {
932  if (COMMPI_Initialized())
933  MPI_Abort(MPI_COMM_WORLD, 0);
934  else
935  abort();
936  }
937  }
938 }
939  */
940 
943 #define HDF_CHECK(routine, args) \
944 { \
945  intn status = HDF4::routine args; \
946  if (status == FAIL && errorhandle != "ignore") { \
947  std::cerr << "Rocout::write_attribute: " #routine " (line " \
948  << __LINE__ << " in " << __FILE__ << ") failed: " \
949  << HDF4::error_msg() << '\n' \
950  << "in write_data( fname == '" << fname << "', label == '" \
951  << label << "', units == '" << units << "', ... , rank == " \
952  << rank << ", shape[] == { " << shape[0]; \
953  { int x; for (x=1; x<rank; ++x) std::cerr << ", " << shape[x]; } \
954  std::cerr << " }, ... )" << std::endl; \
955  if (errorhandle == "abort") { \
956  if (COMMPI_Initialized()) \
957  MPI_Abort(MPI_COMM_WORLD, 0); \
958  else \
959  abort(); \
960  } \
961  } \
962 }
963 
964 static int write_data(const char* fname, const char* label, const char* units,
965  const char* format, const char* coordsys, const int _rank,
966  const int _shape[], const int ng1, const int ng2,
967  const COM_Type type, const void* p, const void* minv,
968  const void* maxv, const std::string& errorhandle,
969  const int mode)
970 {
971  int32 rank = _rank;
972  int32 shape[] = { _shape[0], _shape[1], _shape[2] };
973 #ifdef DEBUG_DUMP_PREFIX
974  int32 numItems = 1;
975 #endif // DEBUG_DUMP_PREFIX
976 
977  if (_shape[0] == 0 || _shape[rank-1] == 0)
978  return false;
979  for (int i=0; i<rank; ++i) {
980 #ifdef DEBUG_DUMP_PREFIX
981  numItems *= shape[i];
982 #endif // DEBUG_DUMP_PREFIX
983  if (shape[i] < 1) {
984  std::cerr << "Rocout Error: Dimension (starting with 1) " << i + 1
985  << " of data " << format << " is " << shape[i]
986  << ".\n A positive number is expected. Aborting..."
987  << std::endl;
988  abort();
989  }
990  }
991 
992 #ifdef DEBUG_DUMP_PREFIX
993  {
994  if (s_fout) {
995  int i;
996  switch (comtype2hdftype(type)) {
997  case DFNT_CHAR8:
998  for (i=0; i<numItems; ++i)
999  *s_fout << i << " : " << (int)((const char*)p)[i] << '\n';
1000  break;
1001  case DFNT_INT32:
1002  for (i=0; i<numItems; ++i)
1003  *s_fout << i << " : " << ((const int*)p)[i] << '\n';
1004  break;
1005  case DFNT_FLOAT32:
1006  for (i=0; i<numItems; ++i)
1007  *s_fout << i << " : " << ((const float*)p)[i] << '\n';
1008  break;
1009  case DFNT_FLOAT64:
1010  for (i=0; i<numItems; ++i)
1011  *s_fout << i << " : " << ((const double*)p)[i] << '\n';
1012  break;
1013  default:
1014  *s_fout << "Datatype is " << comtype2hdftype(type) << '\n';
1015  break;
1016  }
1017  *s_fout << "###########################################\n";
1018  }
1019  }
1020 #endif // DEBUG_DUMP_PREFIX
1021 
1022  HDF_CHECK(DFSDsetdims, (rank, shape));
1023  HDF_CHECK(DFSDsetNT, (comtype2hdftype(type)));
1024 
1025  HDF_CHECK(DFSDsetdatastrs, (label, units, format, coordsys));
1026 
1027  double t1, t2;
1028  if (minv == NULL) { // Compute the max and min
1029  minv = &t1;
1030  min_element(p, _rank, _shape, ng1, ng2, type, &t1);
1031  maxv = &t2;
1032  max_element(p, _rank, _shape, ng1, ng2, type, &t2);
1033  }
1034 
1035  HDF_CHECK(DFSDsetrange, (const_cast<void*>(maxv), const_cast<void*>(minv)));
1036 
1037  if (mode > 0) { // append
1038  HDF_CHECK(DFSDadddata, (fname, rank, shape, const_cast<void*>(p)));
1039  } else {
1040  HDF_CHECK(DFSDputdata, (fname, rank, shape, const_cast<void*>(p)));
1041  }
1042 
1043  return true;
1044 };
1045 
1047 {
1048  switch (i) {
1049  case COM_CHAR:
1050  case COM_CHARACTER:
1051  return DFNT_CHAR8;
1052 
1053  case COM_INT:
1054  case COM_INTEGER:
1055  return (sizeof(int) == 4) ? DFNT_INT32 : DFNT_INT64;
1056 
1057  case COM_FLOAT:
1058  case COM_REAL:
1059  return (sizeof(float) == 4) ? DFNT_FLOAT32 : DFNT_FLOAT64;
1060 
1061  case COM_DOUBLE:
1062  case COM_DOUBLE_PRECISION:
1063  if (sizeof(double) == 4)
1064  return DFNT_FLOAT32;
1065  else if ( sizeof( double) == 8)
1066  return DFNT_FLOAT64;
1067  else
1068  return DFNT_FLOAT128;
1069 
1070  default:
1071  COM_assertion(false);
1072  return 0;
1073  }
1074 }
1075 
1076 
1077 
1078 
1079 
1080 
int COM_Type
Indices for derived data types.
Definition: roccom_basic.h:122
A Pane object contains a mesh, pane attribute, and field variables.
Definition: Pane.h:43
static void io_pane_connectivity(const char *fname, const COM::Pane *pane, const char *timelevel, const char *coordsys, const std::string &errorhandle, const int mode)
Definition: Rocout_hdf4.C:296
#define COM_assertion(EX)
Error checking utility similar to the assert macro of the C language.
static void min_element(const void *begin, const int rank, const int shape[], const int ng1, const int ng2, const COM_Type type, void *f)
Definition: Rocout_hdf4.C:722
void append_str(std::vector< char > &vec, const char *str)
Definition: Rocout_hdf4.C:125
#define HDF_CHECK(routine, args)
New informative error-checking macro to replace hdf_error_message().
Definition: Rocout_hdf4.C:943
An Attribute object is a data member of a window.
Definition: Attribute.h:51
j indices k indices k
Definition: Indexing.h:6
#define COM_assertion_msg(EX, msg)
double s
Definition: blastest.C:80
Vector_n max(const Array_n_const &v1, const Array_n_const &v2)
Definition: Vector_n.h:354
A Window object contains multiple panes and multiple data attributes.
Definition: Window.h:42
static void io_pane_header(const char *fname, const COM::Pane *pane, const char *blockname, const char *material, const char *timelevel, const char *mfile, const std::string &errorhandle, const int mode)
Definition: Rocout_hdf4.C:223
const T * max_element__(const T *begin, const int rank, const int shape[], const int ng1, const int ng2)
Template implementation for determining the maximum entry in an array.
Definition: Rocout_hdf4.C:688
C/C++ Data types.
Definition: roccom_basic.h:129
double sqrt(double d)
Definition: double.h:73
static void max_sqrt_element(const void *begin, const int rank, const int shape[], const int ng1, const int ng2, const COM_Type type, void *v)
Definition: Rocout_hdf4.C:879
double length(Vector3D *const v, int n)
*********************************************************************Illinois Open Source License ****University of Illinois NCSA **Open Source License University of Illinois All rights reserved ****Developed free of to any person **obtaining a copy of this software and associated documentation to deal with the Software without including without limitation the rights to and or **sell copies of the and to permit persons to whom the **Software is furnished to do subject to the following this list of conditions and the following disclaimers ****Redistributions in binary form must reproduce the above **copyright this list of conditions and the following **disclaimers in the documentation and or other materials **provided with the distribution ****Neither the names of the Center for Simulation of Advanced the University of nor the names of its **contributors may be used to endorse or promote products derived **from this Software without specific prior written permission ****THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY **EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES **OF FITNESS FOR A PARTICULAR PURPOSE AND **NONINFRINGEMENT IN NO EVENT SHALL THE CONTRIBUTORS OR **COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN AN ACTION OF TORT OR **ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE **USE OR OTHER DEALINGS WITH THE SOFTWARE v
Definition: roccomf90.h:20
static int write_data(const char *fname, const char *label, const char *units, const char *format, const char *coordsys, const int _rank, const int _shape[], const int ng1, const int ng2, const COM_Type type, const void *p, const void *minv, const void *maxv, const std::string &errorhandle, const int mode=1)
Definition: Rocout_hdf4.C:964
Rocout creates a series of Roccom windows by reading in a list of files.
const void * pointer() const
Obtain a constant pointer to the physical address.
Definition: Attribute.h:150
static void max_element(const void *begin, const int rank, const int shape[], const int ng1, const int ng2, const COM_Type type, void *f)
Definition: Rocout_hdf4.C:762
const T * min_element__(const T *begin, const int rank, const int shape[], const int ng1, const int ng2)
Template implementation for determining the minimum entry in an array.
Definition: Rocout_hdf4.C:653
const std::string & name() const
Obtain the name of the attribute.
Definition: Attribute.h:113
static void io_pane_coordinates(const char *fname, const COM::Pane *pane, const char *timelevel, const char *coordsys, const char *unit, const std::string &errorhandle, const int mode)
Definition: Rocout_hdf4.C:277
blockLoc i
Definition: read.cpp:79
const NT & n
static int get_sizeof(MPI_Datatype i)
Get the size of a given MPI data type.
Definition: commpi.C:44
int stride() const
Obtain the stride of the attribute in base datatype.
Definition: Attribute.h:233
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
Definition: Vector_n.h:346
Pane & pane(const int pane_id, bool insert=false)
Find the pane with given ID. If not found, insert a pane with given ID.
Definition: Window.C:769
static void io_hdf_data(const char *fname, const char *label, const char *units, const char *format, const char *coordsys, int rank, int shape[], int ng1, int ng2, int dim, const COM_Type type, const void *p, int stride, const std::string &errorhandle, const int mode, const void *minv, const void *maxv)
Definition: Rocout_hdf4.C:534
j indices j
Definition: Indexing.h:6
#define HUGE_VALF
Definition: Rocout_hdf4.C:719
static void squared_sum(const void *a, const int length, const int stride, const COM_Type type, void *ssum)
Definition: Rocout_hdf4.C:802
static void io_pane_attribute(const char *fname, const COM::Pane *pane, const COM::Attribute *attr, const char *timelevel, const char *coordsys, const std::string &errorhandle, const int mode)
Definition: Rocout_hdf4.C:360
static void min_sqrt_element(const void *begin, const int rank, const int shape[], const int ng1, const int ng2, const COM_Type type, void *v)
Definition: Rocout_hdf4.C:837
static int comtype2hdftype(COM_Type i)
Definition: Rocout_hdf4.C:1046
static int rank
Definition: advectest.C:66
Fortran Data types.
Definition: roccom_basic.h:133
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
#define DEBUG_MSG(x)
Definition: Rocout_hdf4.C:51
static void io_pane(const char *fname, const COM::Pane *pane, const COM::Attribute *attr, const char *material, const char *timelevel, const char *mfile, const std::string &errorhandle, const int mode)
Definition: Rocout_hdf4.C:142