64 #include <sys/types.h>
71 #ifndef DOXYGEN_SHOULD_SKIP_THIS
79 #ifdef DEBUG_DUMP_PREFIX
80 static void DebugDump(std::ofstream& fout,
int n,
int dType,
void* data)
86 char* p = (
char*)data;
88 fout << i <<
": " << (
int)p[
i] <<
'\n';
94 fout << i <<
": " << p[i] <<
'\n';
98 float* p = (
float*)data;
100 fout << i <<
": " << p[i] <<
'\n';
104 double* p = (
double*)data;
106 fout << i <<
": " << p[i] <<
'\n';
109 fout <<
"Unhandled COM datatype " << dType << std::endl;
113 #endif // DEBUG_DUMP_PREFIX
122 std::cerr <<
"Rocstar: Error (glob): error in pattern `" << epath <<
"': "
123 << strerror(gerrno) << std::endl;
131 int (*errfunc)(
const char*,
int))
132 {
return reinterpret_cast<T
>(errfunc); }
144 #define HDF4_CHECK_RET(routine, args, retval) \
146 if((routine args) == FAIL) { \
148 if((routine args) == FAIL) { \
150 if((routine args) == FAIL) { \
152 if((routine args) == FAIL) { \
153 std::cerr << "Rocstar: Error: " #routine " (line " \
154 << __LINE__ << " in " << __FILE__ << ") failed: " \
155 << HDF4::error_msg() << std::endl; \
170 #define HDF4_CHECK(routine, args) HDF4_CHECK_RET(routine, args, )
178 template <
typename T1,
typename T2 = T1>
200 # define CG_CHECK_RET(routine, args, retval) \
202 int ier = routine args; \
204 std::cerr << "Rocstar: Error: " #routine " (line " \
205 << __LINE__ << " in " << __FILE__ << ") failed: " \
206 << cg_get_error() << std::endl; \
210 # define CG_CHECK(routine, args) CG_CHECK_RET(routine, args, )
221 :
m_cwd(getcwd(NULL, 0)) {}
231 bool elementType_to_string(ElementType_t etype, std::string & roccom_elem)
237 case BAR_2: roccom_elem =
":b2:";
239 case BAR_3: roccom_elem =
":b3:" ;
241 case TRI_3: roccom_elem =
":t3:";
243 case TRI_6: roccom_elem =
":t6:" ;
245 case QUAD_4: roccom_elem =
":q4:" ;
247 case QUAD_8: roccom_elem =
":q8:" ;
249 case QUAD_9: roccom_elem =
":q9:" ;
251 case TETRA_4: roccom_elem =
":T4:" ;
253 case TETRA_10: roccom_elem =
":T10:";
255 case PYRA_5: roccom_elem =
":P5:";
257 case PYRA_14: roccom_elem =
":P14:" ;
259 case PENTA_6: roccom_elem =
":P6:" ;
261 case PENTA_15: roccom_elem =
":P15:" ;
263 case PENTA_18: roccom_elem =
":P18:" ;
265 case HEXA_8: roccom_elem =
":B8:" ;
267 case HEXA_20: roccom_elem =
":B20:";
271 default: std::cerr <<
"Rocstar: Error: CGNS element type of " << etype <<
"has no Roccom equivalent\n";
286 const std::string& matName,
287 const std::string& label, int32 hIndex,
291 if (geomFile.empty()) {
307 int32 sds_id,
rank, size[5], dType;
310 std::string target = matName +
'|' + label;
313 for (*index=0; *index<dsCount; ++(*index)) {
315 (geom_id, *index, name, &rank, size, &dType, &nAttrs, dsCount),
342 std::map<int32, COM_Type>& HDF2COM)
344 int32 sd_id, geom_id, sds_id, nDataSets, nAttrs, index, index3;
345 int32
rank, dType, start[1];
346 int32 size[5] = { 0, 0, 0, 0, 0 };
352 int numPoints=0, ghostPoints, gc, gridType=0;
353 std::vector<int> ghostCells;
354 char grid[32], ghost[32], location;
355 std::string geomFile;
363 for (i=0; i<pathc; ++
i) {
365 if (strcmp(&pathv[i][strlen(pathv[i])-4],
".hdf") != 0
366 && strcmp(&pathv[i][strlen(pathv[i])-5],
".hdf4") != 0)
377 for (index=0; index<nDataSets; ++index) {
380 (sd_id, index, name, &rank, size, &dType, &nAttrs, nDataSets),
389 (sds_id, label, timeLevel, varName, matName,
MAX_NC_NAME),
393 if (
strncasecmp(varName,
"block header", 12) != 0) {
400 else if (time != timeLevel)
406 std::cerr <<
"Rocstar: Warning: Dataset " << index <<
" in file " << pathv[
i]
407 <<
" is marked as a block header, but its rank is not 1 "
408 <<
"(rank == " << rank <<
')' << std::endl;
414 if (dType == DFNT_CHAR8) {
417 std::vector<char8> data(size[0]);
419 (sds_id, start, NULL, size, (VOIDP)&data[0]),
424 std::istringstream
sin(&data[0]);
425 sin.getline(grid,
sizeof(grid),
'|');
426 sin.getline(ghost,
sizeof(ghost),
'|');
431 if (
strcasecmp(grid,
"structured") == 0 || strcmp(grid,
"2") == 0) {
433 }
else if (
strcasecmp(grid,
"unstructured") == 0
434 || strcmp(grid,
"3") == 0) {
436 }
else if (
strcasecmp(grid,
"discontinuous") == 0
437 || strcmp(grid,
"4") == 0) {
440 || strcmp(grid,
"5") == 0) {
443 std::cerr <<
"Rocstar: Warning: The block header (dataset " << index
444 <<
" in file " << pathv[
i] <<
") does not have a "
445 <<
"valid grid type (grid = " << grid <<
')'
485 char* c = strchr(ghost,
',');
492 if (gc < 0) std::cerr <<
"Rocstar: Warning: Bad num ghosts " << gc <<
" from string: " << ghost << std::endl;
493 ghostCells.push_back(gc);
499 if (gc < 0) std::cerr <<
"Rocstar: Warning: Bad ghosts " << gc << std::endl;
500 ghostCells.push_back(gc);
504 if (buffer[0] !=
'\0') {
505 if (buffer[0] ==
'/') {
510 std::string::size_type pos = geomFile.find_last_of(
'/');
511 if (pos != std::string::npos) {
512 geomFile.erase(pos + 1);
518 if (stat(geomFile.c_str(), &sb) != 0)
527 if (stat(geomFile.c_str(), &sb) != 0) {
528 std::cerr <<
"Rocstar: Warning: The block header (dataset " << index
529 <<
" in file " << pathv[
i] <<
") has an invalid "
530 <<
"filename for the external geometry data. The "
531 <<
"file does not exist: " << geomFile << std::endl;
536 std::cerr <<
"Rocstar: Warning: Dataset " << index <<
" in file " << pathv[
i]
537 <<
" is marked as a block header, but its datatype is "
538 <<
"not char8." << std::endl;
545 if (geom_id == FAIL) {
546 std::cerr <<
"Rocstar: Warning: Could not open geometry dataset for section "
547 << label <<
" of material " << matName << std::endl;
552 for (xyz=0; xyz<6; xyz+=2,++index3) {
554 (geom_id, index3, name, &rank, size, &dType, &nAttrs),
558 geomIdx[xyz/2] = index3;
562 if ((gridType == 2 && rank != 3) || (gridType != 2 && rank != 1)) {
563 numPoints = size[0] = size[1] = size[2] = 0;
564 geomIdx[0] = geomIdx[1] = geomIdx[2] = FAIL;
569 (sds_id, name, units, NULL, varType,
MAX_NC_NAME));
572 numPoints = size[0] * size[1] * size[2];
574 char* pos = strchr(name,
'|');
576 if (pos && *(pos+2)==
'0')
577 numPoints = ghostPoints = 0;
581 std::istringstream in(pos+3);
589 std::string lbl(label);
590 std::string::size_type pos = lbl.find_first_of(
"0123456789");
591 if (pos != std::string::npos)
594 std::istringstream
sin(lbl);
599 block =
new Block_HDF4(pathv[i], geomFile, geomIdx, paneId, timeLevel,
600 units, numPoints, ghostPoints);
611 std::vector<int>::iterator p;
612 for (p=ghostCells.begin();
613 ghostCells.empty() || p!=ghostCells.end();
615 sds_id =
HDF4::Select(geom_id, index3, name, &rank, size,
617 if (sds_id == FAIL) {
618 if (!ghostCells.empty())
619 std::cerr <<
"Rocstar: Warning: Select() failed on connectivity dataset "
620 << index3 <<
" in file "
621 << (geomFile.empty() ? pathv[
i] : geomFile.c_str())
634 (sds_id, label, units, varName, varType,
MAX_NC_NAME),
638 if (!ghostCells.empty())
642 if (varName[0] !=
':') {
644 if (gridType == 3 || gridType == 4) {
646 strcpy(varName,
":T4:");
647 else if (size[0] == 5)
648 strcpy(varName,
":P5:");
649 else if (size[0] == 6)
650 strcpy(varName,
":P6:");
651 else if (size[0] == 8)
652 strcpy(varName,
":B8:");
653 else if (size[0] == 10)
654 strcpy(varName,
":T10:");
655 else if (size[0] == 20)
656 strcpy(varName,
":B20:");
658 strcpy(varName,
":unknown");
659 }
else if (gridType == 5) {
661 strcpy(varName,
":t3:");
662 else if (size[0] == 4)
663 strcpy(varName,
":q4:");
664 else if (size[0] == 6)
665 strcpy(varName,
":t6:");
666 else if (size[0] == 8)
667 strcpy(varName,
":q8:");
669 strcpy(varName,
":unknown");
671 strcpy(varName,
":unknown");
675 std::cerr <<
"Rocstar: Warning: reading old-style connectivity dataset "
676 << varName <<
" from " << index3 <<
" in file "
677 << (geomFile.empty() ? pathv[
i] : geomFile.c_str())
682 char* pos = strchr(label,
'|');
683 if (pos && *(pos+2)==
'0') {
684 size[1] = ghostCount = 0;
687 std::istringstream in(pos+3);
692 if (size[1]<0 || ghostCount < 0) {
693 std::cerr <<
"Rocstar: Error: Bad number of element or ghosts for attribute " << varName <<
" nElem=" << size[1] <<
" nGhost=" << ghostCount << std::endl;
695 "Bad number of element or ghosts for attribute.");
701 if (geom_id != sd_id) {
708 for (++index; index<nDataSets; ++index) {
710 (sd_id, index, name, &rank, size, &dType, &nAttrs, nDataSets),
716 (sds_id, label, units, varName, varType,
MAX_NC_NAME),
719 if (varName[0] ==
'\0' || varName[0] ==
':') {
724 if (
strncasecmp(varName,
"block header", 12) == 0) {
735 int ng=0;
bool is_null=
false;
737 if ( label[0] !=
':') {
738 char* pos = strchr(label,
'|');
748 if (num==sz) {location=
'n'; ng=0; }
750 if (num==sz) {location=
'n'; ng=g; }
754 if (num==sz) {location=
'e'; ng=0; }
756 if (num==sz) {location=
'e'; ng=g; }
760 std::cerr <<
"Rocstar: Warning: Compatability warning: guessing variable '"
761 << varName <<
"' in dataset " << index <<
" in file "
762 << pathv[
i] <<
" with label " << label
763 <<
" is of type " << location
764 <<
"(" << sz <<
")" << std::endl;
766 std::cerr <<
" size of variable: ";
767 for (
int i=0;i<
rank;i++) std::cerr<<size[i]<<
',';
768 std::cerr << std::endl;
772 location = *(pos + 1);
774 if ( *(pos+2) ==
'0')
775 { size[0] = ng = 0; is_null=
true; }
776 else if ( (*(pos + 2)==
',' || *(pos + 2)==
'@'))
777 { ng = std::atoi( pos+3); is_null=*(pos + 2)==
'@'; }
782 std::istringstream str(varType);
808 std::cerr <<
"Rocstar: Warning: Found a vector component named " << varName
809 <<
" for which there is no X component at "
810 <<
" dataset " << index <<
" (" << name
811 <<
") in file " << pathv[
i] << std::endl;
819 case 21:
case 22:
case 23:
820 case 31:
case 32:
case 33: {
825 std::cerr <<
"Rocstar: Warning: Found a tensor component named " << varName
826 <<
" for which there is no (0,0) component at "
827 <<
"dataset " << index <<
" (" << name
828 <<
") in file " << pathv[
i] << std::endl;
831 vi.
m_indices[3*(vType/10)+(vType%10)-4] = index;
832 vi.
m_is_null[3*(vType/10)+(vType%10)-4] = is_null;
844 if ( varName[0]>=
'0' && varName[0]<=
'9') {
845 if ( std::strncmp( varName,
"1-", 2)==0)
849 unsigned int id = std::atoi( varName);
850 const char *aName = std::strchr(varName,
'-');
852 if ( aName==NULL || vi.
m_name != (aName+1) ||
855 std::cerr <<
"Rocstar: Warning: Found a vector named " << vi.
m_name
856 <<
" whose components are not stored together "
857 <<
" in file " << pathv[
i] << std::endl;
864 << vi.
m_indices.size() <<
" components.");
869 DEBUG_MSG(
"Found variable '" << &varName[offset] <<
"', location == '"
870 << location <<
"', nComp == " << nc <<
", nItems == "
871 << size[0] <<
", nGhost == " << ng <<
", isNull == "
874 (
VarInfo_HDF4(&varName[offset], location, HDF2COM[dType],
875 units, nc, index, size[0], ng, is_null));
877 blocks.insert(BlockMM_HDF4::value_type(matName, block));
883 const BlockMM_HDF4::iterator& end,
884 const std::string& window,
885 const MPI_Comm* comm,
int rank,
int nprocs)
887 int local,
i, ne = 0;
891 int32 sd_id = 0, sds_id, start[3], size[3];
893 std::vector<int32>::iterator r;
894 std::vector<GridInfo_HDF4>::iterator
s;
897 for ( ; p!=end; ++p, ++with_pane) {
903 if (!local)
continue;
907 (block->
m_file.c_str(), DFACC_READ),
916 block->
m_gridInfo.front().m_name.substr(0,3)==
":st");
922 name = window +
".nc";
923 DEBUG_MSG(
"Calling COM_resize_array( name == '" << name <<
"', paneid == " << block->
m_paneId <<
", ptr == NULL, arg == 0 )");
927 for (i=0; i<3; ++
i) {
929 name = window +
'.' + (char)(
'1' + i) +
"-nc";
938 start[0] = start[1] = start[2] = 0;
940 (sds_id, start, NULL, block->
m_gridInfo.front().m_size, data));
946 #ifdef DEBUG_DUMP_PREFIX
948 std::ofstream fout((DEBUG_DUMP_PREFIX + name +
'.' + block->
time_level +
".hdf").c_str());
951 #endif // DEBUG_DUMP_PREFIX
959 name = window +
"." + (*s).m_name;
960 DEBUG_MSG(
"Calling COM_resize_array( name == '" << name <<
"', paneid == " << block->
m_paneId <<
", ptr == " << &data <<
", arg == 1 )");
963 start[0] = start[1] = 0;
964 std::istringstream
sin((*s).m_name);
965 sin.get(); sin.get();
967 size[1] = (*s).m_numElements;
968 ne += (*s).m_numElements;
970 if ( size[1] && data) {
974 #ifdef DEBUG_DUMP_PREFIX
976 std::ofstream fout((DEBUG_DUMP_PREFIX + name +
'.' + block->
time_level +
".hdf").c_str());
977 DebugDump(fout, size[0] * size[1],
COM_INT, data);
979 #endif // DEBUG_DUMP_PREFIX
992 std::vector<VarInfo_HDF4>::iterator
q;
995 if ( (*q).m_is_null[0])
continue;
997 if ( with_pane && (*q).m_position==
'w')
continue;
1002 name = window +
'.' + (*q).m_name;
1003 if ( (*q).m_position!=
'w') {
1004 DEBUG_MSG(
"Calling COM_resize_array( name == '" << name <<
"', paneid == " << block->
m_paneId <<
", ptr == " << &data <<
", arg == 1 )");
1010 for (r=(*q).m_indices.begin();
1011 r!=(*q).m_indices.end(); ++r, ++loop) {
1015 if( (*q).m_indices.size()==1)
1016 name = window +
'.' + (*q).m_name;
1018 std::ostringstream sout;
1019 sout << window <<
'.' << loop <<
'-' << (*q).m_name;
1026 if (structured && ((*q).m_position==
'n' || (*q).m_position==
'e')) {
1027 start[0] = start[1] = start[2] = 0;
1028 if ((*q).m_position ==
'n') {
1029 size[0] = block->
m_gridInfo.front().m_size[0];
1030 size[1] = block->
m_gridInfo.front().m_size[1];
1031 size[2] = block->
m_gridInfo.front().m_size[2];
1045 size[0] = (*q).m_nitems;
1047 nonempty = size[0] && data;
1053 #ifdef DEBUG_DUMP_PREFIX
1055 std::ofstream fout((DEBUG_DUMP_PREFIX + name +
'.' + block->
time_level +
".hdf").c_str());
1056 DebugDump(fout, (*q).m_nitems, (*q).m_dataType, data);
1058 #endif // DEBUG_DUMP_PREFIX
1074 static void scan_files_CGNS(
int pathc,
char* pathv[],
1076 std::map<DataType_t, COM_Type>& CGNS2COM)
1078 bool has_timesteps =
true;
1080 std::string timeLevel;
1084 if (!time.empty()) {
1085 std::istringstream in(time);
1088 std::ostringstream sout;
1090 timeLevel = sout.str();
1097 for (i=0; i<pathc; ++
i) {
1099 if (strcmp(&pathv[i][strlen(pathv[i])-5],
".cgns") != 0)
1103 std::string fname(pathv[i]);
1104 std::string::size_type cloc = fname.rfind(
'/');
1105 if (cloc != std::string::npos) {
1106 chdir(fname.substr(0, cloc).c_str());
1107 fname.erase(0, cloc + 1);
1111 CG_CHECK_RET(cg_open, (fname.c_str(), MODE_READ, &fn),
continue);
1116 CG_CHECK_RET(cg_nbases, (fn, &nBases),
continue);
1121 for (B=1; B<=nBases; ++B) {
1126 int cellDim, physDim;
1127 CG_CHECK_RET(cg_base_read, (fn, B, baseName, &cellDim, &physDim),
1131 int nameLen = std::strlen(baseName);
1132 if (nameLen > 7 && std::strcmp(&baseName[nameLen-7],
"_ridges") == 0)
1136 if (timeLevel.empty()) {
1139 int error_code = cg_biter_read(fn, B, buffer, &nSteps);
1140 if (error_code == CG_NODE_NOT_FOUND) {
1141 std::cerr <<
"Rocstar: Warning: cg_biter_read() failed with CG_NODE_NOT_FOUND"
1142 <<
" on Base " << B <<
" in file " << pathv[
i] << std::endl;
1143 std::cerr <<
"Rocstar: Warning: No time steps given with Base "<< B <<std::endl;
1144 has_timesteps =
false;
1145 }
else if (error_code == CG_ERROR) {
1146 std::cerr <<
"Rocstar: Warning: cg_biter_read() failed with CG_ERROR on Base " << B
1147 <<
" in file " << pathv[
i] << std::endl;
1150 if (has_timesteps) {
1151 CG_CHECK(cg_goto, (fn, B,
"BaseIterativeData_t", 1,
"end"));
1153 std::vector<double> times(nSteps);
1155 CG_CHECK(cg_array_read_as, (1, RealDouble, ×[0]));
1158 for (ti=0; ti<nSteps; ++ti)
1159 DEBUG_MSG(
"Time " << ti <<
" == " << times[ti]);
1161 std::ostringstream sout;
1163 timeLevel = sout.str();
1164 DEBUG_MSG(
"timeLevel == " << timeLevel);
1167 sprintf(buffer,
"%9.6f", times[0]);
1174 CG_CHECK_RET(cg_nzones, (fn, B, &nZones),
continue);
1183 std::string gridAttrName;
1186 gridAttrName =
"Grid";
1187 if (timeLevel.length() + gridAttrName.length() > 32)
1188 gridAttrName.erase(32 - timeLevel.length());
1189 gridAttrName += timeLevel;
1193 gridAttrName =
"GridCoordinates";
1198 std::string winAttrName(
"WinData");
1199 if (timeLevel.length() + winAttrName.length() > 32)
1200 winAttrName.erase(32 - timeLevel.length());
1201 winAttrName += timeLevel;
1204 std::string paneAttrName(
"PaneData");
1205 if (timeLevel.length() + paneAttrName.length() > 32)
1206 paneAttrName.erase(32 - timeLevel.length());
1207 paneAttrName += timeLevel;
1210 std::string connAttrName(
"ConnData");
1211 if (timeLevel.length() + connAttrName.length() > 32)
1212 connAttrName.erase(32 - timeLevel.length());
1213 connAttrName += timeLevel;
1216 std::string elemAttrName(
"ElemData");
1217 if (timeLevel.length() + elemAttrName.length() > 32)
1218 elemAttrName.erase(32 - timeLevel.length());
1219 elemAttrName += timeLevel;
1222 std::string nodeAttrName(
"NodeData");
1223 if (timeLevel.length() + nodeAttrName.length() > 32)
1224 nodeAttrName.erase(32 - timeLevel.length());
1225 nodeAttrName += timeLevel;
1228 for (Z=1; Z<=nZones; ++Z) {
1229 int nPoints, nGhostPoints;
1232 int gridSize[3], coreSize[9];
1233 CG_CHECK_RET(cg_zone_read, (fn, B, Z, zoneName, coreSize),
continue);
1235 ZoneType_t zoneType;
1236 CG_CHECK_RET(cg_zone_type, (fn, B, Z, &zoneType),
continue);
1239 CG_CHECK_RET(cg_ngrids, (fn, B, Z, &nGrids),
continue);
1241 int G, rind[6] = { 0, 0, 0, 0, 0, 0 };
1242 for (G=1; G<=nGrids; ++G) {
1243 CG_CHECK_RET(cg_grid_read, (fn, B, Z, G, buffer),
continue);
1245 if (gridAttrName != buffer)
1248 CG_CHECK_RET(cg_goto,
1249 (fn, B,
"Zone_t", Z,
"GridCoordinates_t", G,
"end"),
1252 if (cg_rind_read(rind) != 0)
1253 std::fill_n(rind, 6, 0);
1255 if (zoneType == Structured) {
1256 gridSize[0] = coreSize[0] + rind[0] + rind[1];
1257 gridSize[cellDim] = coreSize[cellDim] + rind[0] + rind[1];
1258 nPoints = gridSize[0];
1260 gridSize[1] = coreSize[1] + rind[2] + rind[3];
1261 gridSize[cellDim+1] = coreSize[cellDim+1] + rind[2] + rind[3];
1262 nPoints *= gridSize[1];
1264 gridSize[2] = coreSize[2] + rind[4] + rind[5];
1265 gridSize[5] = coreSize[5] + rind[5] + rind[5];
1266 nPoints *= gridSize[2];
1270 nPoints = gridSize[0] = coreSize[0] + rind[0] + rind[1];
1274 nGhostPoints = rind[1];
1277 CG_CHECK_RET(cg_goto,
1278 (fn, B,
"Zone_t", Z,
"GridCoordinates_t", G,
"DataArray_t", 1,
"end"),
1284 CG_CHECK_RET(cg_ndescriptors, (&nDescriptors),
break);
1288 for (D=1; D<=nDescriptors; ++D) {
1289 CG_CHECK_RET(cg_descriptor_read, (D, buffer, &text),
continue);
1291 if (strcmp(buffer,
"Range") == 0) {
1292 if (strcmp(text,
"EMPTY") == 0)
1293 nPoints = nGhostPoints = 0;
1294 }
else if (strcmp(buffer,
"Units") == 0) {
1304 std::string lbl(zoneName);
1305 std::string::size_type pos = lbl.find_first_of(
"0123456789");
1306 if (pos != std::string::npos)
1311 std::istringstream in(lbl);
1316 block =
new Block_CGNS(pathv[i], B, Z, G, paneId, timeLevel, units,
1317 nPoints, nGhostPoints);
1319 if (zoneType == Structured) {
1320 block->m_gridInfo.push_back(GridInfo_CGNS(gridSize, cellDim,
1324 std::string rocElemType;
1326 CG_CHECK_RET(cg_nsections, (fn, B, Z, &nSections),
1327 delete block;
continue);
1329 int totalGhostElems = 0, S;
1330 for (S=1; S<=nSections; ++S) {
1331 ElementType_t elemType;
1332 int iStart, iEnd, iBoundry, pFlag;
1333 CG_CHECK_RET(cg_section_read,
1334 (fn, B, Z, S, buffer, &elemType, &iStart, &iEnd, &iBoundry, &pFlag),
1335 delete block;
continue);
1337 int nElems = iEnd - iStart + 1;
1338 int nGhostElems = 0;
1339 std::string label = buffer;
1340 if (label.substr(0, 4) ==
"Null") {
1343 }
else if (label.substr(0, 5) ==
"Empty") {
1347 CG_CHECK_RET(cg_goto,
1348 (fn, B,
"Zone_t", Z,
"Elements_t", S,
"end"),
1349 delete block;
continue);
1352 if (cg_rind_read(rind) == 0)
1353 nGhostElems = rind[1];
1358 if (label[0] !=
':') {
1359 elementType_to_string(elemType, rocElemType);
1360 label = rocElemType + label;
1363 totalGhostElems += nGhostElems;
1364 block->m_gridInfo.push_back(GridInfo_CGNS(label, nElems,
1367 gridSize[1] += totalGhostElems;
1371 if (cg_goto(fn, B,
"end") != 0) {
1372 std::cerr <<
"Rocstar: Warning: cg_goto() failed to go to Base " << B <<
" in file "
1373 << pathv[
i] << std::endl;
1376 if (cg_nintegrals(&nIntegrals) != 0) {
1377 std::cerr <<
"Rocstar: Warning: cg_nintegrals() failed in Base " << B <<
" in file "
1378 << pathv[
i] << std::endl;
1381 for (I=1; I<=nIntegrals; ++I) {
1382 CG_CHECK_RET(cg_integral_read, (I, buffer),
continue);
1384 if (winAttrName != buffer)
1389 CG_CHECK_RET(cg_goto, (fn, B,
"IntegralData_t", I,
"end"),
break);
1392 CG_CHECK_RET(cg_narrays, (&nArrays),
break);
1395 for (A=1; A<=nArrays; ++
A) {
1396 CG_CHECK_RET(cg_goto, (fn, B,
"IntegralData_t", I,
"end"),
1399 DataType_t dataType;
1401 CG_CHECK_RET(cg_array_info, (A, buffer, &dataType, &rank, size),
1404 CG_CHECK_RET(cg_goto, (fn, B,
"IntegralData_t", I,
"DataArray_t", A,
"end"),
1407 std::string label = buffer;
1409 CG_CHECK_RET(cg_ndescriptors, (&nDescriptors),
continue);
1413 bool isNull =
false;
1414 int nGhostItems = 0, D;
1415 for (D=1; D<=nDescriptors; ++D) {
1416 CG_CHECK_RET(cg_descriptor_read, (D, buffer, &text),
1419 if (strcmp(buffer,
"Range") == 0) {
1420 if (strcmp(text,
"EMPTY") == 0) {
1421 nGhostItems = size[0] = 0;
1423 }
else if (strcmp(text,
"NULL") == 0)
1425 }
else if (strcmp(buffer,
"Ghost") == 0) {
1427 std::istringstream in(text);
1430 }
else if (strcmp(buffer,
"Units") == 0) {
1436 int nComps = 1, comp = 0;
1437 std::string::size_type i = label.rfind(
'#');
1438 if (i != std::string::npos) {
1439 std::istringstream in(&label[i+1]);
1446 i = label.length() - 1;
1447 if (label[i] >=
'X' && label[i] <=
'Z') {
1448 comp = label[
i] -
'X';
1451 if (label[i] >=
'X' && label[i] <=
'Z') {
1452 comp += 3 * (label[
i] -
'X');
1462 VarInfo_CGNS &vi = block->m_variables.back();
1463 vi.m_indices[comp] =
A;
1464 vi.m_is_null[comp] = isNull;
1466 block->m_variables.push_back
1467 (VarInfo_CGNS(label,
'w', CGNS2COM[dataType], units,
1468 nComps, A, size[0], nGhostItems, isNull));
1477 if (cg_goto(fn, B,
"Zone_t", Z,
"end") != 0) {
1478 std::cerr <<
"Rocstar: Warning: cg_goto() failed to go to Zone " << Z <<
" of Base "
1479 << B <<
" in file " << pathv[
i] << std::endl;
1482 if (cg_nintegrals(&nIntegrals) != 0) {
1483 std::cerr <<
"Rocstar: Warning: cg_nintegrals() failed in Zone " << Z <<
" of Base "
1484 << B <<
" in file " << pathv[
i] << std::endl;
1487 for (I=1; I<=nIntegrals && found<2; ++I) {
1488 CG_CHECK_RET(cg_integral_read, (I, buffer),
continue);
1491 if (paneAttrName == buffer) {
1494 }
else if (connAttrName == buffer) {
1502 CG_CHECK_RET(cg_goto,
1503 (fn, B,
"Zone_t", Z,
"IntegralData_t", I,
"end"),
1507 CG_CHECK_RET(cg_narrays, (&nArrays),
break);
1510 for (A=1; A<=nArrays; ++
A) {
1511 CG_CHECK_RET(cg_goto,
1512 (fn, B,
"Zone_t", Z,
"IntegralData_t", I,
"end"),
1515 DataType_t dataType;
1517 CG_CHECK_RET(cg_array_info, (A, buffer, &dataType, &rank, size),
1520 CG_CHECK_RET(cg_goto,
1521 (fn, B,
"Zone_t", Z,
"IntegralData_t", I,
"DataArray_t", A,
"end"),
1524 std::string label = buffer;
1526 CG_CHECK_RET(cg_ndescriptors, (&nDescriptors),
continue);
1530 bool isNull =
false;
1531 int nGhostItems = 0, D;
1532 for (D=1; D<=nDescriptors; ++D) {
1533 CG_CHECK_RET(cg_descriptor_read, (D, buffer, &text),
1536 if (strcmp(buffer,
"Range") == 0) {
1537 if (strcmp(text,
"EMPTY") == 0) {
1538 nGhostItems = size[0] = 0;
1540 }
else if (strcmp(text,
"NULL") == 0)
1542 }
else if (strcmp(buffer,
"Ghost") == 0) {
1544 std::istringstream in(text);
1547 }
else if (strcmp(buffer,
"Units") == 0) {
1553 int nComps = 1, comp = 0;
1554 std::string::size_type i = label.rfind(
'#');
1555 if (i != std::string::npos) {
1556 std::istringstream in(&label[i+1]);
1563 i = label.length() - 1;
1564 if (label[i] >=
'X' && label[i] <=
'Z') {
1565 comp = label[
i] -
'X';
1568 if (label[i] >=
'X' && label[i] <=
'Z') {
1569 comp += 3 * (label[
i] -
'X');
1579 VarInfo_CGNS &vi = block->m_variables.back();
1580 vi.m_indices[comp] =
A;
1581 vi.m_is_null[comp] = isNull;
1584 block->m_variables.push_back
1585 (VarInfo_CGNS(label, attrType, CGNS2COM[dataType], units,
1586 nComps, A, size[0], nGhostItems, isNull));
1595 if (cg_nsols(fn, B, Z, &nSols) != 0) {
1596 std::cerr <<
"Rocstar: Warning: cg_nsols() failed in Zone " << Z <<
" of Base "
1597 << B <<
" in file " << pathv[
i] << std::endl;
1601 for (S=1; S<=nSols && found<2; ++S) {
1602 CG_CHECK_RET(cg_sol_info, (fn, B, Z, S, buffer, &loc),
continue);
1604 bool isNodal =
false;
1605 if (buffer == elemAttrName ) {
1607 }
else if (buffer == nodeAttrName ) {
1615 CG_CHECK_RET(cg_goto,
1616 (fn, B,
"Zone_t", Z,
"FlowSolution_t", S,
"end"),
1620 if (cg_rind_read(rind) != 0)
1621 std::fill_n(rind, 6, 0);
1624 int start = isNodal ? 0 : 1;
1625 if (zoneType == Structured) {
1628 nItems = coreSize[start] + rind[0] + rind[1];
1630 nItems *= coreSize[start+1] + rind[2] + rind[3];
1632 nItems *= coreSize[start+2] + rind[4] + rind[5];
1636 nItems = coreSize[start] + rind[0] + rind[1];
1640 CG_CHECK_RET(cg_nfields, (fn, B, Z, S, &nFields),
break);
1643 for (F=1; F<=nFields; ++F) {
1644 DataType_t dataType;
1645 CG_CHECK_RET(cg_field_info, (fn, B, Z, S, F, &dataType, buffer),
1648 CG_CHECK_RET(cg_goto,
1649 (fn, B,
"Zone_t", Z,
"FlowSolution_t", S,
"DataArray_t", F,
"end"),
1652 std::string label = buffer;
1654 CG_CHECK_RET(cg_ndescriptors, (&nDescriptors),
continue);
1658 bool isNull =
false;
1660 for (D=1; D<=nDescriptors; ++D) {
1661 CG_CHECK_RET(cg_descriptor_read, (D, buffer, &text),
continue);
1663 if (strcmp(buffer,
"Range") == 0) {
1664 if (strcmp(text,
"EMPTY") == 0) {
1665 rind[1] = nItems = 0;
1667 }
else if (strcmp(text,
"NULL") == 0)
1669 }
else if (strcmp(buffer,
"Units") == 0)
1674 int nComps = 1, comp = 0;
1675 std::string::size_type i = label.rfind(
'#');
1676 if (i != std::string::npos) {
1677 std::istringstream in(&label[i+1]);
1684 i = label.length() - 1;
1685 if (label[i] >=
'X' && label[i] <=
'Z') {
1686 comp = label[
i] -
'X';
1689 if (label[i] >=
'X' && label[i] <=
'Z') {
1690 comp += 3 * (label[
i] -
'X');
1701 VarInfo_CGNS &vi = block->m_variables.back();
1702 if (vi.m_name != label)
1703 std::cerr <<
"Rocstar: Warning: attributes for " << label
1704 <<
" are not contiguous." << std::endl;
1705 else if (vi.m_indices.size() != nComps)
1706 std::cerr <<
"Rocstar: Warning: attribute " << label
1707 <<
" has inconsistent component count."
1709 vi.m_indices[comp] = F;
1710 vi.m_is_null[comp] = isNull;
1712 block->m_variables.push_back
1713 (VarInfo_CGNS(label, isNodal ?
'n' :
'e', CGNS2COM[dataType],
1714 units, nComps, F, nItems, rind[1], isNull));
1722 if (cg_ndiscrete(fn, B, Z, &nDiscrete) != 0) {
1723 std::cerr <<
"Rocstar:Warning: cg_ndiscrete() failed in Zone " << Z <<
" of Base "
1724 << B <<
" in file " << pathv[
i] << std::endl;
1727 for (S=1; S<=nDiscrete; ++S) {
1728 CG_CHECK_RET(cg_discrete_read, (fn, B, Z, S, buffer),
continue);
1730 if (nodeAttrName != buffer)
1735 CG_CHECK_RET(cg_goto,
1736 (fn, B,
"Zone_t", Z,
"DiscreteData_t", S,
"end"),
1740 if (cg_rind_read(rind) != 0)
1741 std::fill_n(rind, 6, 0);
1744 if (zoneType == Structured) {
1746 nItems = coreSize[0] + rind[0] + rind[1];
1748 nItems *= coreSize[1] + rind[2] + rind[3];
1750 nItems *= coreSize[2] + rind[4] + rind[5];
1754 nItems = coreSize[0] + rind[0] + rind[1];
1758 CG_CHECK_RET(cg_narrays, (&nArrays),
break);
1761 for (A=1; A<=nArrays; ++
A) {
1762 CG_CHECK_RET(cg_goto,
1763 (fn, B,
"Zone_t", Z,
"DiscreteData_t", S,
"end"),
1766 DataType_t dataType;
1768 CG_CHECK_RET(cg_array_info, (A, buffer, &dataType, &rank, size),
1770 std::string label = buffer;
1776 (
"Bad rank for nodal attribute '"
1777 + label +
"'\n").c_str());
1780 CG_CHECK_RET(cg_goto,
1781 (fn, B,
"Zone_t", Z,
"DiscreteData_t", S,
"DataArray_t", A,
"end"),
1785 CG_CHECK_RET(cg_ndescriptors, (&nDescriptors),
continue);
1789 bool isNull =
false;
1791 for (D=1; D<=nDescriptors; ++D) {
1792 CG_CHECK_RET(cg_descriptor_read, (D, buffer, &text),
continue);
1794 if (strcmp(buffer,
"Range") == 0) {
1795 if (strcmp(text,
"EMPTY") == 0) {
1796 rind[1] = nItems = 0;
1798 }
else if (strcmp(text,
"NULL") == 0)
1800 }
else if (strcmp(buffer,
"Units") == 0)
1805 int nComps = 1, comp = 0;
1806 std::string::size_type i = label.rfind(
'#');
1807 if (i != std::string::npos) {
1808 std::istringstream in(&label[i+1]);
1815 i = label.length() - 1;
1816 if (label[i] >=
'X' && label[i] <=
'Z') {
1817 comp = label[
i] -
'X';
1820 if (label[i] >=
'X' && label[i] <=
'Z') {
1821 comp += 3 * (label[
i] -
'X');
1832 VarInfo_CGNS &vi = block->m_variables.back();
1833 vi.m_indices[comp] =
A;
1834 vi.m_is_null[comp] = isNull;
1836 block->m_variables.push_back
1837 (VarInfo_CGNS(label,
'n', CGNS2COM[dataType], units,
1838 nComps, A, nItems, rind[1], isNull));
1846 blocks.insert(BlockMM_CGNS::value_type(baseName, block));
1852 static void load_data_CGNS( BlockMM_CGNS::iterator p,
1853 const BlockMM_CGNS::iterator& end,
1854 const std::string& window,
1855 const MPI_Comm* comm,
int rank,
int nprocs)
1863 for ( with_pane=0; p!=end; ++p, ++with_pane) {
1864 block = (*p).second;
1867 bool local =
COM_get_status( window.c_str(), block->m_paneId) >= 0;
1869 if (!local)
continue;
1872 std::string fname(block->m_file);
1873 std::string::size_type cloc = fname.rfind(
'/');
1874 if (cloc != std::string::npos) {
1875 chdir(fname.substr(0, cloc).c_str());
1876 fname.erase(0, cloc + 1);
1880 CG_CHECK_RET(cg_open, (fname.c_str(), MODE_READ, &fn),
continue);
1883 bool structured = (!block->m_gridInfo.empty() &&
1884 block->m_gridInfo.front().m_name.substr(0,3) ==
":st");
1890 name = window +
".nc";
1891 DEBUG_MSG(
"Calling COM_resize_array( name == '" << name <<
"', paneid == " << block->m_paneId <<
", ptr == NULL, arg == 1 )");
1895 for (i=1; i<4; ++
i) {
1897 name = window +
'.' + (char)(
'0' + i) +
"-nc";
1900 if (block->m_numNodes > 0 && data != NULL) {
1901 CG_CHECK_RET(cg_goto,
1902 (fn, block->m_B,
"Zone_t", block->m_Z,
1903 "GridCoordinates_t", block->m_G,
"end"),
1906 CG_CHECK(cg_array_read, (i, data));
1907 #ifdef DEBUG_DUMP_PREFIX
1909 std::ofstream fout((DEBUG_DUMP_PREFIX + name +
'.'
1910 + block->time_level +
".cgns").c_str());
1911 DebugDump(fout, block->m_numNodes,
COM_DOUBLE, data);
1913 #endif // DEBUG_DUMP_PREFIX
1919 std::vector<GridInfo_CGNS>::iterator
s;
1920 for (i=1,s=block->m_gridInfo.begin();s!=block->m_gridInfo.end();++
i,++
s) {
1921 name = window +
"." + (*s).m_name;
1922 DEBUG_MSG(
"Calling COM_resize_array( name == '" << name
1923 <<
"', paneid == " << block->m_paneId <<
", ptr == "
1924 << &data <<
", arg == 1 )");
1927 if ((*s).m_numElements > 0 && data != NULL) {
1929 std::istringstream in(&(*s).m_name[2]);
1931 std::vector<int> cbuf((*s).m_numElements * nn);
1932 CG_CHECK_RET(cg_elements_read,
1933 (fn, block->m_B, block->m_Z, i, &cbuf[0], NULL),
1938 for (elem=0,zz=0; elem<(*s).m_numElements; ++elem)
1939 for (node=0; node<nn; ++node,++zz)
1940 ((
int*)data)[node*(*s).m_numElements+elem] = cbuf[zz];
1941 #ifdef DEBUG_DUMP_PREFIX
1943 std::ofstream fout((DEBUG_DUMP_PREFIX + name +
'.' + block->time_level +
".cgns").c_str());
1944 DebugDump(fout, (*s).m_numElements * nn,
COM_INT, data);
1946 #endif // DEBUG_DUMP_PREFIX
1952 std::vector<VarInfo_CGNS>::iterator
q;
1953 for (q=block->m_variables.begin(); q!=block->m_variables.end(); ++
q) {
1955 if ( (*q).m_is_null[0])
continue;
1957 if ( with_pane && (*q).m_position==
'w')
continue;
1960 name = window +
'.' + (*q).m_name;
1961 if ( (*q).m_position!=
'w') {
1962 DEBUG_MSG(
"Calling COM_resize_array( name == '" << name <<
"', paneid == " << block->m_paneId <<
", ptr == " << &data <<
", arg == 1 )");
1968 switch((*q).m_position) {
1970 CG_CHECK_RET(cg_goto,
1971 (fn, block->m_B,
"IntegralData_t", block->m_W,
"end"),
1976 CG_CHECK_RET(cg_goto,
1977 (fn, block->m_B,
"Zone_t", block->m_Z,
"IntegralData_t", block->m_P,
"end"),
1982 CG_CHECK_RET(cg_goto,
1983 (fn, block->m_B,
"Zone_t", block->m_Z,
"IntegralData_t", block->m_C,
"end"),
1988 CG_CHECK_RET(cg_goto,
1989 (fn, block->m_B,
"Zone_t", block->m_Z,
"FlowSolution_t", block->m_E,
"end"),
1994 CG_CHECK_RET(cg_goto,
1995 (fn, block->m_B,
"Zone_t", block->m_Z,
"FlowSolution_t", block->m_N,
"end"),
2001 std::vector<int>::iterator r;
2002 for (r=(*q).m_indices.begin(),loop=1; r!=(*q).m_indices.end();
2007 if( (*q).m_indices.size() == 1)
2008 name = window +
'.' + (*q).m_name;
2010 std::ostringstream sout;
2011 sout << window <<
'.' << loop <<
'-' << (*q).m_name;
2017 if ((*q).m_nitems == 0 || data == NULL)
continue;
2019 CG_CHECK(cg_array_read, (*r, data));
2020 #ifdef DEBUG_DUMP_PREFIX
2022 std::ofstream fout((DEBUG_DUMP_PREFIX + name +
'.' + block->time_level +
".cgns").c_str());
2023 DebugDump(fout, (*q).m_nitems, (*q).m_dataType, data);
2025 #endif // DEBUG_DUMP_PREFIX
2033 const BlockMM_HDF4::iterator& hdf4End,
2035 BlockMM_CGNS::iterator cgns,
2036 const BlockMM_CGNS::iterator& cgnsEnd,
2038 const std::string& window,
2039 const MPI_Comm* comm,
int rank,
int nprocs)
2043 std::ostringstream sout;
2044 std::set<std::string> added;
2046 while (hdf4 != hdf4End) {
2047 std::vector<VarInfo_HDF4> &vars = hdf4->second->m_variables;
2048 std::vector<VarInfo_HDF4>::const_iterator
q;
2050 for (q=vars.begin(); q!=vars.end(); ++
q){
2051 if (added.count((*q).m_name) == 0) {
2052 sout << (*q).m_name <<
'!' << (*q).m_position <<
'!'
2053 << (*q).m_dataType <<
'!' << (*q).m_indices.size()
2054 <<
'!' << (*q).m_units <<
'!';
2055 if ( (*q).m_position==
'w')
2056 sout << (*q).m_nitems <<
'!' << (*q).m_ng;
2058 added.insert((*q).m_name);
2065 while (cgns != cgnsEnd) {
2066 std::vector<VarInfo_CGNS> &vars = cgns->second->m_variables;
2067 std::vector<VarInfo_CGNS>::const_iterator
q;
2069 for (q=vars.begin(); q!=vars.end(); ++
q){
2070 if (added.count((*q).m_name) == 0) {
2071 sout << (*q).m_name <<
'!' << (*q).m_position <<
'!'
2072 << (*q).m_dataType <<
'!' << (*q).m_indices.size()
2073 <<
'!' << (*q).m_units <<
'!';
2074 if ( (*q).m_position==
'w')
2075 sout << (*q).m_nitems <<
'!' << (*q).m_ng;
2077 added.insert((*q).m_name);
2085 std::string msg = sout.str();
2086 int len = msg.length();
2087 std::vector<int> lengths(nprocs);
2088 if ( *comm != MPI_COMM_NULL)
2089 MPI_Allgather(&len, 1, MPI_INT, &lengths[0], 1, MPI_INT, *comm);
2094 int globlen = lengths[0];
2095 std::vector<int> disp(nprocs, 0);
2096 for (
int i=1; i<nprocs; ++
i) {
2097 globlen += lengths[
i];
2098 disp[
i] = disp[i-1] + lengths[i-1];
2102 std::vector<char> buffer(len+1,
'\0');
2103 std::vector<char> glob(globlen+1,
'\0');
2104 std::strcpy( &buffer[0], msg.c_str());
2105 if ( *comm != MPI_COMM_NULL)
2106 MPI_Allgatherv(&buffer[0], len, MPI_CHAR, &glob[0], &lengths[0], &disp[0],
2117 char* token = &glob[0];
2121 char *nextToken = strchr(token,
'|');
2122 if (nextToken==0)
break;
2125 std::istringstream
sin(token);
2126 sin.getline(buf,
sizeof(buf),
'!');
2127 if (added.count(buf) == 0) {
2129 name = window +
'.';
2131 position = sin.get(); sin.get();
2132 sin >> dType; sin.get();
2133 sin >> numComponents; sin.get();
2134 sin.getline(buf,
sizeof(buf),
'!');
2135 DEBUG_MSG(
"Calling COM_new_attribute( name == '" << name <<
"', position == '" << position <<
"', datatype == " << dType <<
", nComp == " << numComponents <<
", units == '" << buf <<
"' )");
2138 if ( position ==
'w') {
2140 sin >> nitems; sin.get();
2141 sin >> ng; sin.get();
2142 DEBUG_MSG(
"Calling COM_set_size( name == '" << name <<
"', paneid == 0, nitems == " << nitems <<
", nghost == " << ng <<
" )");
2144 DEBUG_MSG(
"Calling COM_resize_array( name == '" << name <<
"', paneid == 0 )");
2154 const MPI_Comm *comm,
int rank,
2158 int empty = isEmpty ? 1 : 0;
2159 std::vector<int> is_empty(nprocs);
2160 if ( *comm != MPI_COMM_NULL)
2161 MPI_Allgather(&empty, 1, MPI_INT, &is_empty[0], 1, MPI_INT, *comm);
2163 is_empty[0] =
empty;
2166 int last_empty=-1, root=-1;
2167 for (
int i=0; i<nprocs; ++
i) {
2168 if ( is_empty[i]) last_empty =
i;
2172 if ( last_empty<0)
return;
2179 std::istringstream is(atts);
2180 for (
int i=0; i<na; ++
i) {
2182 std::string aname; is >> aname;
2187 if ( loc !=
'w')
continue;
2191 COM_get_array( (window+
"."+aname).c_str(), 0, &addr, &strd, &count);
2194 if ( *comm != MPI_COMM_NULL)
2195 MPI_Bcast( addr, len, MPI_CHAR, root, *comm);
2201 const BlockMM_HDF4::iterator& hdf4End,
2203 BlockMM_CGNS::iterator cgns,
2204 const BlockMM_CGNS::iterator& cgnsEnd,
2206 const std::string& window, RulesPtr
is_local,
2207 const MPI_Comm* comm,
int rank,
int nprocs)
2212 for ( ; hdf4!=hdf4End; ++hdf4) {
2223 if (!local)
continue;
2226 name = window +
".nc";
2227 if (is_first && !block->
m_units.empty()) {
2229 DEBUG_MSG(
"Calling COM_new_attribute( name == '" << name <<
"', position == 'n', datatype == COM_DOUBLE, nComp == 3, units == '" << block->
m_units <<
"' )");
2241 block->
m_gridInfo.front().m_name.substr(0,3) ==
":st") {
2242 int mysize[3], ndim = block->
m_gridInfo.front().m_name[3] -
'0';
2243 mysize[0] = block->
m_gridInfo.front().m_size[2];
2244 mysize[1] = block->
m_gridInfo.front().m_size[1];
2245 mysize[2] = block->
m_gridInfo.front().m_size[0];
2246 name = window +
'.' + block->
m_gridInfo.front().m_name;
2248 DEBUG_MSG(
"Calling COM_set_size( name == '" << name <<
"', paneid == " << block->
m_paneId <<
", nitems == " << ndim <<
", nghost == " << block->
m_gridInfo.front().m_numGhostElements <<
" )");
2250 block->
m_gridInfo.front().m_numGhostElements);
2253 std::vector<GridInfo_HDF4>::iterator
q;
2255 name = window +
"." + (*q).m_name;
2256 DEBUG_MSG(
"Calling COM_set_size( name == '" << name <<
"', paneid == " << block->
m_paneId <<
", nitems == " << (*q).m_numElements <<
", nghost == " << (*q).m_numGhostElements <<
" )");
2258 (*q).m_numElements, (*q).m_numGhostElements);
2263 std::vector<VarInfo_HDF4> &vars = block->
m_variables;
2264 std::vector<VarInfo_HDF4>::const_iterator
q;
2266 for ( q=vars.begin(); q!=vars.end(); ++
q) {
2267 if ( (*q).m_position ==
'p' || (*q).m_position ==
'c') {
2268 name = window +
"." + (*q).m_name;
2269 DEBUG_MSG(
"Calling COM_set_size( name == '" << name <<
"', paneid == " << block->
m_paneId <<
", nitems == " << (*q).m_nitems <<
", nghost == " << (*q).m_ng <<
" )");
2271 (*q).m_nitems, (*q).m_ng);
2277 for ( ; cgns!=cgnsEnd; ++cgns) {
2278 Block_CGNS* block = (*cgns).second;
2282 (this->*
m_is_local)(block->m_paneId, rank, nprocs, &local);
2284 is_local(block->m_paneId, rank, nprocs, &local);
2288 if (!local)
continue;
2291 name = window +
".nc";
2292 if (is_first && !block->m_units.empty()) {
2294 DEBUG_MSG(
"Calling COM_new_attribute( name == '" << name <<
"', position == 'n', datatype == COM_DOUBLE, nComp == 3, units == '" << block->m_units <<
"' )");
2299 DEBUG_MSG(
"Calling COM_set_size( name == '" << name <<
"', paneid == " << block->m_paneId <<
", nitems == " << block->m_numNodes <<
", nghost == " << block->m_numGhostNodes <<
" )");
2301 block->m_numNodes,block->m_numGhostNodes);
2305 if (block->m_gridInfo.size() &&
2306 block->m_gridInfo.front().m_name.substr(0,3) ==
":st") {
2307 int ndim = block->m_gridInfo.front().m_name[3] -
'0';
2308 name = window +
'.' + block->m_gridInfo.front().m_name;
2310 DEBUG_MSG(
"Calling COM_set_size( name == '" << name <<
"', paneid == " << block->m_paneId <<
", nitems == " << ndim <<
", nghost == " << block->m_gridInfo.front().m_numGhostElements <<
" )");
2312 block->m_gridInfo.front().m_numGhostElements);
2314 block->m_gridInfo.front().m_size);
2316 std::vector<GridInfo_CGNS>::iterator
q;
2317 for (q=block->m_gridInfo.begin(); q!=block->m_gridInfo.end(); ++
q){
2318 name = window +
"." + (*q).m_name;
2319 DEBUG_MSG(
"Calling COM_set_size( name == '" << name <<
"', paneid == " << block->m_paneId <<
", nitems == " << (*q).m_numElements <<
", nghost == " << (*q).m_numGhostElements <<
" )");
2321 (*q).m_numElements, (*q).m_numGhostElements);
2326 std::vector<VarInfo_CGNS> &vars = block->m_variables;
2327 std::vector<VarInfo_CGNS>::const_iterator
q;
2329 for ( q=vars.begin(); q!=vars.end(); ++
q) {
2330 if ( (*q).m_position ==
'p' || (*q).m_position ==
'c') {
2331 name = window +
"." + (*q).m_name;
2332 DEBUG_MSG(
"Calling COM_set_size( name == '" << name <<
"', paneid == " << block->m_paneId <<
", nitems == " << (*q).m_nitems <<
", nghost == " << (*q).m_ng <<
" )");
2334 (*q).m_nitems, (*q).m_ng);
2341 template<
class BLOCK>
2344 typename BLOCK::iterator p;
2345 for (p=blocks.begin(); p!=blocks.end(); ++p)
2363 rin->m_CGNS2COM[Character] =
COM_CHAR;
2365 rin->m_CGNS2COM[Integer] =
COM_INT;
2366 rin->m_CGNS2COM[RealSingle] =
COM_FLOAT;
2372 std::string glb=mname+
".global";
2374 DEBUG_MSG(
"Calling COM_new_attribute( name == '" << glb <<
"', position == 'w', datatype == COM_OBJECT, nComp == 1, units == '' )");
2383 glb.c_str(),
"biiIIIBI", types);
2390 glb.c_str(),
"biiIIBI", types);
2396 glb.c_str(),
"biiIBI", types);
2404 glb.c_str(),
"bioI", types);
2412 glb.c_str(),
"biiI", types);
2420 std::string glb=mname+
".global";
2432 COM::Attribute *user_attribute,
2437 "Null attributes are not valid arguments to Rocin::obtain_attribute\n");
2439 if ( attribute_in != user_attribute) {
2440 COM::Window *win = user_attribute->window();
2441 win->inherit(const_cast<Attribute*>(attribute_in), user_attribute->name(),
2442 COM::Pane::INHERIT_COPY,
true, NULL, pane_id?*pane_id:0);
2447 const int& comm_size,
int* il)
2453 const int& comm_size,
int* il)
2455 *il = (pid -
m_offset) % comm_size == comm_rank;
2459 const int& comm_size,
int* il)
2462 if ( proc>=comm_size) proc %= comm_size;
2463 *il = proc == comm_rank;
2467 const char* window_name,
2468 const MPI_Comm* comm,
2473 const MPI_Comm comm_null=MPI_COMM_NULL;
2474 const MPI_Comm* myComm;
2475 int myRank, comm_size;
2478 std::string dir_name = control_file_name;
2479 std::string::size_type pos = dir_name.find_last_of(
'/');
2480 if ( pos == std::string::npos)
2483 dir_name.erase( pos+1);
2485 if ( comm && *comm == MPI_COMM_NULL || !comm)
2496 MPI_Comm_rank(*myComm, &myRank);
2497 MPI_Comm_size(*myComm, &comm_size);
2502 std::ifstream fin(control_file_name);
2503 if (!fin.is_open()) {
2504 std::cerr <<
"Rocstar: Error: read_by_control_file unable to open " << control_file_name
2505 <<
" for reading." << std::endl;
2509 std::vector<std::string> patterns;
2514 while (!fin.eof()) {
2515 std::vector<std::string> local_patterns;
2516 while (!fin.eof() && (myRank<0 || rank != myRank) ) {
2517 if (buffer !=
"@Proc:") {
2522 while (fin.peek() ==
' ' || fin.peek() ==
'\t' || fin.peek() ==
'\n')
2525 if (fin.peek() ==
'*') {
2535 }
else if (rank == myRank)
2543 if ( rank != myRank)
2544 std::cerr <<
"Rocstar: Error (read_by_control_file): control file "
2545 << control_file_name
2546 <<
" does not contain information for process " << myRank
2552 if (buffer !=
"@Files:") {
2553 std::cerr <<
"Rocstar: Error (read_by_control_file): in control file "
2554 << control_file_name
2555 <<
": expected '@Files' but found '" << buffer <<
'\''
2562 while (buffer !=
"@Panes:" && buffer !=
"@Proc:") {
2564 if (fin.eof())
break;
2566 std::string::size_type pos = buffer.find(
"%t");
2567 if (pos != std::string::npos)
2568 buffer.replace(pos, 2, time_level);
2570 pos = buffer.find(
'%');
2571 if ( pos != std::string::npos) {
2572 std::string::size_type pos_key =
2573 buffer.find_first_not_of(
"0123456789", pos+1);
2576 (std::string(
"Incomplete placeholder in file name ")+buffer).c_str());
2578 std::string width = buffer.substr(pos+1, pos_key-pos-1);
2581 if ( !width.empty()) {
2582 std::istringstream
sin(width);
2586 std::ostringstream sout;
2588 switch( buffer[pos_key]) {
2592 for (
int i=0; i<w; ++
i) sout <<
"[0-9]";
2594 sout << std::setfill(
'0') << std::setw(w) << myRank;
2603 for (
int i=0; i<w; ++
i) sout <<
"[0-9]";
2607 COM_assertion_msg(
false, (std::string(
"Unknown keyword in file name ")+buffer).c_str());
2610 buffer.replace(pos, pos_key - pos + 1, sout.str());
2615 if ( !dir_name.empty()) {
2621 if (buffer[0] !=
'/' &&
2622 strncmp(buffer.c_str(), dir_name.c_str(),
std::min(buffer.size(), dir_name.size()))) buffer.insert(0, dir_name);
2626 local_patterns.push_back(buffer);
2632 if (buffer ==
"@Proc:") {
2633 patterns.insert(patterns.end(), local_patterns.begin(),
2634 local_patterns.end());
2648 if (buffer ==
"@Cyclic") {
2651 }
else if (buffer ==
"@BlockCyclic") {
2655 }
else if (buffer ==
"@Block" || buffer ==
"@BlockBlockCyclic") {
2660 int quot = block/comm_size, rem = block-quot*comm_size;
2669 }
else if (buffer ==
"@All" || buffer ==
"*") {
2671 }
else if (buffer[0] ==
'@' && buffer !=
"@Panes:" ) {
2672 if ( buffer !=
"@Proc:") {
2673 std::cerr <<
"Rocstar: Error (read_by_control_file): in control file "
2674 << control_file_name <<
": expected pane info but found '"
2675 << buffer <<
'\'' << std::endl;
2679 local_patterns.clear();
2685 if (buffer[0] <
'0' || buffer[0] >
'9')
2688 std::istringstream
sin(buffer);
2699 if (!fin.eof()) fin >> buffer;
2704 patterns.insert(patterns.end(), local_patterns.begin(),
2705 local_patterns.end());
2707 if ( myRank >= 0 && rank == myRank)
break;
2711 if ( myRank>=0 && rank != myRank)
2712 std::cerr <<
"Rocstar: Warning: Did not find matching control blocks for process " << myRank << std::endl;
2721 std::vector<std::string>::const_iterator p;
2722 for (p=patterns.begin(); p!=patterns.end(); ++p)
2723 files = files+
" "+(*p).c_str();
2727 read_window(files.c_str(), window_name, myComm, NULL, time_level, str_len);
2751 const char* window_name,
2752 const MPI_Comm* comm,
2757 read_windows( filename_patterns, window_name,
"", comm, is_local,
2758 time_level, str_len);
2765 return(std::string(getcwd(buf,1024)));
2787 const char* window_prefix,
2788 const char* material_names,
2789 const MPI_Comm* comm,
2798 const MPI_Comm comm_null=MPI_COMM_NULL;
2799 const MPI_Comm* myComm =
2803 if ( *myComm != MPI_COMM_NULL) {
2804 MPI_Comm_rank(*myComm, &rank);
2805 MPI_Comm_size(*myComm, &nprocs);
2811 DEBUG_MSG(
"time_level == " << (time_level == NULL ?
"<Null>" : time_level));
2812 std::string
time( time_level?time_level:
"");
2815 std::set<std::string> materials;
2820 if (material_names != NULL) {
2821 buffer =
new char[strlen(material_names)+1];
2822 strcpy(buffer, material_names);
2824 token = strtok(buffer,
" \t\n");
2825 while (token != NULL) {
2826 materials.insert(token);
2827 token = strtok(NULL,
" \t\n");
2832 buffer =
new char[strlen(filename_patterns)+1];
2833 strcpy(buffer, filename_patterns);
2837 BlockMM_CGNS blocks_CGNS;
2840 token = strtok(buffer,
" \t\n");
2841 if (token != NULL) {
2846 token = strtok(NULL,
" \t\n");
2847 while (token != NULL) {
2849 token = strtok(NULL,
" \t\n");
2852 if ( globbuf.gl_pathc==0 && buffer[0]!=
'\0')
2853 std::cerr <<
"Rocstar: Warning: Found no matching files for pattern "
2854 << buffer << std::endl;
2865 bool isCGNS =
false;
2866 if ((std::string(globbuf.gl_pathv[0])).find(
".hdf") != std::string::npos){
2868 std::cout <<
"npos = " << (std::string(globbuf.gl_pathv[0])).find(
".hdf") <<std::endl;
2870 isCGNS = isHDF ?
false:
true;
2874 scan_files_HDF4(globbuf.gl_pathc, globbuf.gl_pathv, blocks_HDF4, time,
2879 scan_files_CGNS(globbuf.gl_pathc, globbuf.gl_pathv, blocks_CGNS, time,
2894 #else // No glob function on this system
2897 std::list<std::string> matching_filenames;
2898 while (token != NULL) {
2899 std::string dirname(
CWD());
2900 std::string tstring(token);
2901 std::string::size_type
x = tstring.find_last_of(
"/");
2902 if(x != std::string::npos){
2903 dirname += (
"/" + tstring.substr(0,x));
2904 tstring.erase(0,x+1);
2908 Directory::iterator di = directory.begin();
2909 while(di != directory.end()){
2910 if(!fnmatch(tstring.c_str(),di->c_str(),0))
2911 matching_filenames.push_back(dirname +
"/" + *di);
2915 token = strtok(NULL,
" \t\n");
2917 if(matching_filenames.empty() && buffer[0] !=
'\0')
2918 std::cerr <<
"Rocstar: Warning: Found no matching files for pattern "
2919 << buffer << std::endl;
2920 unsigned int nmatch = matching_filenames.size();
2921 std::vector<char *> matches(nmatch);
2922 std::list<std::string>::iterator li = matching_filenames.begin();
2923 unsigned int ccount = 0;
2924 while(li != matching_filenames.end()){
2925 unsigned int lis = li->size();
2926 matches[ccount++] =
new char [lis+1];
2927 strcpy(matches[ccount-1],li->c_str());
2928 matches[ccount-1][lis] =
'\0';
2935 scan_files_CGNS(nmatch, &matches[0], blocks_CGNS, time,
2939 while(ccount < nmatch){
2941 delete [] matches[ccount];
2950 if ( time_level && str_len && *str_len) {
2953 std::strncpy( time_level, time.c_str(), *str_len-1);
2954 time_level[*str_len-1] =
'\0';
2958 std::set<std::string>::iterator p = materials.begin();
2959 std::pair<BlockMM_HDF4::iterator, BlockMM_HDF4::iterator> range_HDF4;
2961 std::pair<BlockMM_CGNS::iterator, BlockMM_CGNS::iterator> range_CGNS;
2964 if (materials.empty()) {
2968 range_HDF4.first = blocks_HDF4.begin();
2969 range_HDF4.second = blocks_HDF4.end();
2971 range_CGNS.first = blocks_CGNS.begin();
2972 range_CGNS.second = blocks_CGNS.end();
2974 name = window_prefix;
2980 range_CGNS.first, range_CGNS.second,
2982 name, myComm, rank, nprocs);
2985 range_CGNS.first, range_CGNS.second,
2987 name, is_local, myComm, rank, nprocs);
2990 name, myComm, rank, nprocs);
2992 load_data_CGNS(range_CGNS.first, range_CGNS.second,
2993 name, myComm, rank, nprocs);
2998 && range_CGNS.first == range_CGNS.second
3000 , name, myComm, rank, nprocs);
3006 while (p != materials.end()) {
3007 if (blocks_HDF4.count(*p) == 0
3009 && blocks_CGNS.count(*p) == 0
3012 std::cerr <<
"Rocstar: Warning (read_windows): could not find '" << *p <<
"'."
3018 range_HDF4 = blocks_HDF4.equal_range(*p);
3020 range_CGNS = blocks_CGNS.equal_range(*p);
3022 name = window_prefix + *p;
3028 range_CGNS.first, range_CGNS.second,
3030 name, myComm, rank, nprocs);
3033 range_CGNS.first, range_CGNS.second,
3035 name, is_local, myComm, rank, nprocs);
3038 name, myComm, rank, nprocs);
3040 load_data_CGNS(range_CGNS.first, range_CGNS.second,
3041 name, myComm, rank, nprocs);
3046 && range_CGNS.first == range_CGNS.second
3048 , name, myComm, rank, nprocs);
3069 #ifndef DOXYGEN_SHOULD_SKIP_THIS
3072 extern "C" void COM_F_FUNC2(rocin_load_module, ROCIN_LOAD_MODULE)(
const char *name,
long int length)
3074 extern "C" void COM_F_FUNC2(rocin_unload_module, ROCIN_UNLOAD_MODULE)(
const char *name,
long int length)
3077 #endif // DOXYGEN_SHOULD_SKIP_THIS
static void load_data_HDF4(BlockMM_HDF4::iterator p, const BlockMM_HDF4::iterator &end, const std::string &window, const MPI_Comm *comm, int rank, int nprocs)
void blockcyclic_local(const int &pid, const int &comm_rank, const int &comm_size, int *il)
int m_numGhostNodes
Number of ghost nodes in a mesh.
static int32 SDselect(int32 sd_id, int32 index)
Struct containing necessary information on a mesh of a pane.
int COM_Type
Indices for derived data types.
void Rocin_load_module(const char *name)
Load the module Rocin into Roccom using the given module name.
void read_windows(const char *filename_patterns, const char *window_prefix, const char *material_names=NULL, const MPI_Comm *comm=NULL, RulesPtr is_local=NULL, char *time_level=NULL, const int *str_len=NULL)
Create a series of Roccom windows by reading in a list of files.
std::vector< int32 > m_indices
HDF4 dataset indices for each component.
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
Automatically save and restore the current working directory.
void COM_delete_window(const char *wname)
T cast_err_func(int(*glob)(const char *, int, T, glob_t *), int(*errfunc)(const char *, int))
Cast glob_error for portability (IBMSP has a different prototype)
void COM_get_attribute(const std::string wa_str, char *loc, int *type, int *ncomp, std::string *unit)
int m_numNodes
Number of nodes in the mesh.
static intn SDend(int32 sd_id)
std::vector< bool > m_is_null
Whether or not a component in NULL.
#define COM_assertion_msg(EX, msg)
void read_window(const char *filename_patterns, const char *window_name, const MPI_Comm *comm=NULL, RulesPtr is_local=NULL, char *time_level=NULL, const int *str_len=NULL)
Create a single Roccom window by reading in a list of files.
static void finalize(const std::string &mname)
Finalize the module by deregistering it from Roccom.
static intn SDendaccess(int32 sds_id)
Vector_n max(const Array_n_const &v1, const Array_n_const &v2)
void COM_set_size(const char *wa_str, int pane_id, int size, int ng=0)
Set sizes of for a specific attribute.
static void scan_files_HDF4(int pathc, char *pathv[], BlockMM_HDF4 &blocks, std::string &time, std::map< int32, COM_Type > &HDF2COM)
Extract metadata from the list of files.
void COM_get_array(const char *wa_str, int pane_id, void **addr, int *strd, int *cap)
Get the address for an attribute on a specific pane.
boolean empty(T_VertexSet s)
int32 m_indices[3]
HDF4 dataset indices of the nodal coordinates.
std::set< int > m_pane_ids
Struct containing necessary information for a pane.
Automatically close open files, datasets, etc.
real *8 function offset(vNorm, x2, y2, z2)
void COM_set_object(const char *wa_str, int pane_id, Type *addr)
void cyclic_local(const int &pid, const int &comm_rank, const int &comm_size, int *il)
#define COM_F_FUNC2(lowcase, uppercase)
void register_panes(BlockMM_HDF4::iterator hdf4, const BlockMM_HDF4::iterator &hdf4End, const std::string &window, RulesPtr is_local, const MPI_Comm *comm, int rank, int nprocs)
static void broadcast_win_attributes(bool isEmpty, const std::string &window, const MPI_Comm *comm, int rank, int nprocs)
std::string m_geomFile
External geometry file (may be empty).
int strncasecmp(const char *const s1, const char *const s2, const int l)
Compare the first n characters of two C-strings, ignoring the case.
double length(Vector3D *const v, int n)
void COM_get_object(const char *wa_str, int pane_id, Type **addr)
#define HDF4_CHECK(routine, args)
bool is_local(int pid, int comm_rank, int comm_size)
static void init(const std::string &mname)
Initialize the module by registering it to Roccom with the given module name.
std::vector< GridInfo_HDF4 > m_gridInfo
Dimensions or conn table(s)
static void init()
Create and start the I/O thread.
void read_parameter_file(const char *file_name, const char *window_name, const MPI_Comm *comm=NULL)
Read in parameters from a given file into the given window.
void COM_get_attributes(const char *wname, int *na, std::string &names)
static int32 FindFirstGeometryDataset(int32 sd_id, const std::string &geomFile, const std::string &matName, const std::string &label, int32 hIndex, int32 *index)
Find the first geometry dataset for the given block.
std::string m_file
Data file.
int strcasecmp(const char *const s1, const char *const s2)
Compare two C-strings, ignoring the case.
static int32 Select(int32 sd_id, int32 &index, char *name, int32 *rank, int32 *size, int32 *dType, int32 *nAttrs, int32 dsCount=-1)
"Open" and "close" HDF files efficiently.
#define HDF4_CHECK_RET(routine, args, retval)
Perform HDF4 error-checking.
std::string m_name
Name of variable.
static intn SDreaddata(int32 sds_id, int32 *start, int32 *stride, int32 *end, VOIDP data)
Rocin()
Default constructor.
Struct containing necessary information about an attribute in a window.
void COM_window_init_done(const char *w_str, int pane_changed=true)
int COM_get_sizeof(const COM_Type type, int c)
static intn SDfileinfo(int32 id, int32 *dsCount, int32 *nAttrs)
std::string m_units
The mesh's units of measurement.
void COM_new_window(const char *wname, MPI_Comm c=MPI_COMM_NULL)
bool blocks
Input data is block-structured grid.
std::map< int32, COM_Type > m_HDF2COM
Rocin creates a series of Roccom windows by reading in a list of files.
void COM_set_array(const char *wa_str, int pane_id, void *addr, int strd=0, int cap=0)
Associates an array with an attribute for a specific pane.
static void finalize()
Destroy the I/O thread.
void free_blocks(BLOCK &blocks)
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
std::multimap< std::string, Block_HDF4 * > BlockMM_HDF4
unsigned long time()
Get the value of a system timer with a millisecond precision.
void obtain_attribute(const COM::Attribute *attribute_in, COM::Attribute *user_attribute, int *pane_id=NULL)
Fill the destination (second) attribute from files using the data corresponding to the source (first)...
void explicit_local(const int &pid, const int &comm_rank, const int &comm_size, int *il)
void read_by_control_file(const char *control_file_name, const char *window_name, const MPI_Comm *comm=NULL, char *time_level=NULL, const int *str_len=NULL)
Create a single Roccom window by reading in the files specified by the given control file...
static int32 SDstart(const char *filename, int32 accessMode)
AutoCloser(T1 id, T2(*f)(T1))
static void new_attributes(BlockMM_HDF4::iterator hdf4, const BlockMM_HDF4::iterator &hdf4End, const std::string &window, const MPI_Comm *comm, int rank, int nprocs)
static intn SDgetdatastrs(int32 sds_id, char *label, char *units, char *format, char *coordsys, intn length)
void COM_new_attribute(const char *wa_str, const char loc, const int type, int ncomp, const char *unit)
Registering an attribute type.
void COM_free_buffer(int **buf)
void COM_set_member_function(const char *wf_str, Member_func_ptr func, const char *wa_str, const char *intents, const COM_Type *types)
static int glob_error(const char *epath, int gerrno)
Error callback for glob.
std::vector< VarInfo_HDF4 > m_variables
Info on each variable.
MPI_Comm COM_get_default_communicator()
*********************************************************************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 ** files(the"Software")
void COM_resize_array(const char *wa_str, int pane_id=0, void **addr=NULL, int strd=-1, int cap=0)
Resize an attribute on a specific pane and return the address by setting addr.
#define CG_CHECK(routine, args)
Perform CGNS error-checking.
int COM_get_status(const char *waname, const int pane_id)
std::string time_level
The dataset's time stamp.
void Rocin_unload_module(const char *name)
Unload the module Rocin from Roccom.