/*========================================================================= Program: Visualization Toolkit Module: cgio_helpers.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ // Copyright 2013-2014 Mickael Philit. #include "cgio_helpers.h" namespace CGNSRead { //---------------------------------------------------------------------------- int readNodeStringData(int cgioNum, double nodeId, std::string& data) { int n; cgsize_t size = 1; cgsize_t dimVals[12]; int ndim; if (cgio_get_dimensions(cgioNum, nodeId, &ndim, dimVals) != CG_OK) { cgio_error_exit("cgio_get_dimensions"); return 1; } // allocate data for (n = 0; n < ndim; n++) { size *= dimVals[n]; } if (size <= 0) { return 1; } data.resize(size); // read data if (cgio_read_all_data_type(cgioNum, nodeId, "C1", (void*)data.c_str()) != CG_OK) { return 1; } return 0; } //------------------------------------------------------------------------------ // Specialize char array template <> int readNodeData(int cgioNum, double nodeId, std::vector& data) { int n; cgsize_t size = 1; cgsize_t dimVals[12]; int ndim; if (cgio_get_dimensions(cgioNum, nodeId, &ndim, dimVals) != CG_OK) { cgio_error_exit("cgio_get_dimensions"); return 1; } // allocate data for (n = 0; n < ndim; n++) { size *= dimVals[n]; } if (size <= 0) { return 1; } data.resize(size + 1); // read data if (cgio_read_all_data_type(cgioNum, nodeId, "C1", &data[0]) != CG_OK) { return 1; } data[size] = '\0'; return 0; } //------------------------------------------------------------------------------ int getNodeChildrenId(int cgioNum, double fatherId, std::vector& childrenIds) { int nchildren; int len; cgio_number_children(cgioNum, fatherId, &nchildren); childrenIds.resize(nchildren); double* idList = new double[nchildren]; cgio_children_ids(cgioNum, fatherId, 1, nchildren, &len, idList); if (len != nchildren) { delete[] idList; std::cerr << "Mismatch in number of children and child IDs read" << std::endl; return 1; } for (int child = 0; child < nchildren; child++) { childrenIds[child] = idList[child]; } delete[] idList; return 0; } //------------------------------------------------------------------------------ int readBaseIds(int cgioNum, double rootId, std::vector& baseIds) { CGNSRead::char_33 nodeLabel; std::size_t nbases = 0; std::size_t nc; baseIds.clear(); getNodeChildrenId(cgioNum, rootId, baseIds); if (baseIds.empty()) { std::cerr << "Error: Not enough nodes under the root description file." << std::endl; return 1; } for (nbases = 0, nc = 0; nc < baseIds.size(); nc++) { if (cgio_get_label(cgioNum, baseIds[nc], nodeLabel) != CG_OK) { return 1; } if (strcmp(nodeLabel, "CGNSBase_t") == 0) { if (nbases < nc) { baseIds[nbases] = baseIds[nc]; } nbases++; } else { cgio_release_id(cgioNum, baseIds[nc]); } } baseIds.resize(nbases); if (nbases < 1) { std::cerr << "Error: Not enough bases in the file." << std::endl; return 1; } return 0; } //------------------------------------------------------------------------------ int readBaseCoreInfo(int cgioNum, double baseId, CGNSRead::BaseInformation& baseInfo) { CGNSRead::char_33 dataType; std::vector mdata; if (cgio_get_name(cgioNum, baseId, baseInfo.name) != CG_OK) { std::cerr << "cgio_get_name" << std::endl; return 1; } // read node data type if (cgio_get_data_type(cgioNum, baseId, dataType) != CG_OK) { return 1; } if (strcmp(dataType, "I4") != 0) { std::cerr << "Unexpected data type for dimension data of base" << std::endl; return 1; } if (CGNSRead::readNodeData(cgioNum, baseId, mdata) != 0) { std::cerr << "error while reading base dimension" << std::endl; return 1; } baseInfo.cellDim = mdata[0]; baseInfo.physicalDim = mdata[1]; return 0; } //------------------------------------------------------------------------------ int readBaseIteration(int cgioNum, double nodeId, CGNSRead::BaseInformation& baseInfo) { CGNSRead::char_33 nodeLabel; CGNSRead::char_33 nodeName; CGNSRead::char_33 dataType; bool createTimeStates = true; bool createIterStates = true; std::vector ndata; // read node data type if (cgio_get_data_type(cgioNum, nodeId, dataType) != CG_OK) { return 1; } if (strcmp(dataType, "I4") != 0) { std::cerr << "Unexpected data type for iteration number of steps" << std::endl; return 1; } if (CGNSRead::readNodeData(cgioNum, nodeId, ndata) != 0) { std::cerr << "error while reading number of state in base" << std::endl; return 1; } int nstates = ndata[0]; std::vector childrenIterative; getNodeChildrenId(cgioNum, nodeId, childrenIterative); for (std::size_t nc = 0; nc < childrenIterative.size(); ++nc) { if (cgio_get_label(cgioNum, childrenIterative[nc], nodeLabel) != CG_OK) { return 1; } if (cgio_get_name(cgioNum, childrenIterative[nc], nodeName) != CG_OK) { return 1; } bool isDataArray = (strcmp(nodeLabel, "DataArray_t") == 0); if (isDataArray && (strcmp(nodeName, "TimeValues") == 0)) { // Read time values // read node data type if (cgio_get_data_type(cgioNum, childrenIterative[nc], dataType) != CG_OK) { return 1; } baseInfo.times.clear(); if (strcmp(dataType, "R8") == 0) { CGNSRead::readNodeData(cgioNum, childrenIterative[nc], baseInfo.times); } else if (strcmp(dataType, "R4") == 0) { std::vector iteData; CGNSRead::readNodeData(cgioNum, childrenIterative[nc], iteData); baseInfo.times.resize(iteData.size()); for (std::size_t ii = 0; ii < iteData.size(); ii++) { baseInfo.times[ii] = (double)iteData[ii]; } } else { std::cerr << "Unexpected data type for iterative data" << std::endl; return 1; } if (static_cast(baseInfo.times.size()) != nstates) { std::cerr << "Error reading times node"; return 1; } createTimeStates = false; } else if (isDataArray && (strcmp(nodeName, "IterationValues") == 0)) { // Read time steps // read node data type if (cgio_get_data_type(cgioNum, childrenIterative[nc], dataType) != CG_OK) { return 1; } if (strcmp(dataType, "I4") != 0) { std::cerr << "Unexpected data type for iterative data" << std::endl; return 1; } baseInfo.steps.clear(); CGNSRead::readNodeData(cgioNum, childrenIterative[nc], baseInfo.steps); if (static_cast(baseInfo.steps.size()) != nstates) { std::cerr << "Error reading steps node"; return 1; } createIterStates = false; } else { cgio_release_id(cgioNum, childrenIterative[nc]); } } if (createIterStates == true) { for (int i = 0; i < nstates; ++i) { baseInfo.steps.push_back(i); } } if (createTimeStates == true) { for (int i = 0; i < nstates; ++i) { baseInfo.times.push_back((double)baseInfo.steps[i]); } } return 0; } //------------------------------------------------------------------------------ int readZoneIterInfo(int cgioNum, double nodeId, CGNSRead::BaseInformation& baseInfo) { CGNSRead::char_33 nodeLabel; CGNSRead::char_33 nodeName; std::vector iterChildId; getNodeChildrenId(cgioNum, nodeId, iterChildId); for (std::size_t nn = 0; nn < iterChildId.size(); nn++) { if (cgio_get_name(cgioNum, iterChildId[nn], nodeName) != CG_OK) { return 1; } if (cgio_get_label(cgioNum, iterChildId[nn], nodeLabel) != CG_OK) { return 1; } bool isDataArray = (strcmp(nodeLabel, "DataArray_t") == 0); if (isDataArray && (strcmp(nodeName, "GridCoordinatesPointers") == 0)) { baseInfo.useGridPointers = true; } else if (isDataArray && (strcmp(nodeName, "FlowSolutionPointers") == 0)) { baseInfo.useFlowPointers = true; // Maybe load FlowSolutionPointers once and for all } cgio_release_id(cgioNum, iterChildId[nn]); } return 0; } //------------------------------------------------------------------------------ int readSolInfo(int cgioNum, double nodeId, CGNSRead::BaseInformation& baseInfo) { CGNS_ENUMT(GridLocation_t) varCentering; varCentering = CGNS_ENUMV(Vertex); CGNSRead::char_33 nodeLabel; std::vector solChildId; getNodeChildrenId(cgioNum, nodeId, solChildId); std::vector cgnsVars; std::vector cgnsVectors; std::size_t nn; std::size_t nvars = 0; for (nvars = 0, nn = 0; nn < solChildId.size(); nn++) { if (cgio_get_label(cgioNum, solChildId[nn], nodeLabel) != CG_OK) { std::cerr << "Error while reading nodelabel" << std::endl; return 1; } if (strcmp(nodeLabel, "DataArray_t") == 0) { CGNSRead::CGNSVariable curVar; if (cgio_get_name(cgioNum, solChildId[nn], curVar.name) != CG_OK) { return 1; } curVar.isComponent = false; curVar.xyzIndex = 0; // read node data type CGNSRead::char_33 dataType; if (cgio_get_data_type(cgioNum, solChildId[nn], dataType)) { continue; } if (strcmp(dataType, "R8") == 0) { curVar.dt = CGNS_ENUMV(RealDouble); } else if (strcmp(dataType, "R4") == 0) { curVar.dt = CGNS_ENUMV(RealSingle); } else if (strcmp(dataType, "I4") == 0) { curVar.dt = CGNS_ENUMV(Integer); } else if (strcmp(dataType, "I8") == 0) { curVar.dt = CGNS_ENUMV(LongInteger); } else { continue; } cgnsVars.push_back(curVar); cgio_release_id(cgioNum, solChildId[nn]); nvars++; } else if (strcmp(nodeLabel, "GridLocation_t") == 0) { CGNSRead::char_33 dataType; if (cgio_get_data_type(cgioNum, solChildId[nn], dataType) != CG_OK) { return 1; } if (strcmp(dataType, "C1") != 0) { std::cerr << "Unexpected data type for GridLocation_t node" << std::endl; return 1; } std::string location; CGNSRead::readNodeStringData(cgioNum, solChildId[nn], location); if (location == "Vertex") { varCentering = CGNS_ENUMV(Vertex); } else if (location == "CellCenter") { varCentering = CGNS_ENUMV(CellCenter); } else { varCentering = CGNS_ENUMV(GridLocationNull); } } else { cgio_release_id(cgioNum, solChildId[nn]); } } // if (varCentering != CGNS_ENUMV(Vertex) && varCentering != CGNS_ENUMV(CellCenter)) { std::cerr << "Bad Centering encountered !" "Only Vertex and CellCenter are supported" << std::endl; return 1; } CGNSRead::fillVectorsFromVars(cgnsVars, cgnsVectors, baseInfo.physicalDim); for (std::size_t ii = 0; ii < cgnsVars.size(); ++ii) { if (cgnsVars[ii].isComponent == true) { continue; } switch (varCentering) { case CGNS_ENUMV(Vertex): if (!baseInfo.PointDataArraySelection.HasArray(cgnsVars[ii].name)) { baseInfo.PointDataArraySelection.AddArray(cgnsVars[ii].name, false); } break; case CGNS_ENUMV(CellCenter): if (!baseInfo.CellDataArraySelection.HasArray(cgnsVars[ii].name)) { baseInfo.CellDataArraySelection.AddArray(cgnsVars[ii].name, false); } break; default: break; } } for (std::size_t jj = 0; jj < cgnsVectors.size(); ++jj) { switch (varCentering) { case CGNS_ENUMV(Vertex): if (!baseInfo.PointDataArraySelection.HasArray(cgnsVectors[jj].name)) { baseInfo.PointDataArraySelection.AddArray(cgnsVectors[jj].name, false); } break; case CGNS_ENUMV(CellCenter): if (!baseInfo.CellDataArraySelection.HasArray(cgnsVectors[jj].name)) { baseInfo.CellDataArraySelection.AddArray(cgnsVectors[jj].name, false); } break; default: break; } } return 0; } //------------------------------------------------------------------------------ int readBaseFamily( int cgioNum, double nodeId, CGNSRead::BaseInformation& baseInfo, const std::string& parentPath) { CGNSRead::FamilyInformation curFamily; CGNSRead::char_33 nodeLabel; CGNSRead::char_33 nodeName; std::vector famChildId; if (cgio_get_name(cgioNum, nodeId, nodeName) != CG_OK) { return 1; } curFamily.isBC = false; // use a path relative to base to select Family_t part of Family_t tree std::string curPath = std::string(nodeName); if (!parentPath.empty()) { curPath = parentPath + "/" + curPath; } curFamily.name = curPath; getNodeChildrenId(cgioNum, nodeId, famChildId); for (std::size_t nn = 0; nn < famChildId.size(); nn++) { if (cgio_get_label(cgioNum, famChildId[nn], nodeLabel) != CG_OK) { return 1; } if (strcmp(nodeLabel, "FamilyBC_t") == 0) { curFamily.isBC = true; } else if (strcmp(nodeLabel, "Family_t") == 0) { readBaseFamily(cgioNum, famChildId[nn], baseInfo, curPath); } } CGNSRead::releaseIds(cgioNum, famChildId); baseInfo.family.push_back(curFamily); return 0; } //------------------------------------------------------------------------------ int readBaseReferenceState(int cgioNum, double nodeId, CGNSRead::BaseInformation& baseInfo) { CGNSRead::char_33 nodeLabel; CGNSRead::char_33 curName; std::vector children; getNodeChildrenId(cgioNum, nodeId, children); std::size_t nn; for (nn = 0; nn < children.size(); nn++) { if (cgio_get_label(cgioNum, children[nn], nodeLabel) != CG_OK) { std::cerr << "Error while reading nodelabel" << std::endl; return 1; } if (cgio_get_name(cgioNum, children[nn], curName) != CG_OK) { return 1; } bool isDataArray = strcmp(nodeLabel, "DataArray_t") == 0; if (isDataArray && ((strcmp(curName, "Mach") == 0) || (strcmp(curName, "SpecificHeatRatio") == 0) || (strcmp(curName, "IdealGasConstant") == 0) || (strcmp(curName, "SpecificHeatVolume") == 0) || (strcmp(curName, "SpecificHeatPressure") == 0))) { // read node data type CGNSRead::char_33 dataType; if (cgio_get_data_type(cgioNum, children[nn], dataType)) { return 1; } if (strcmp(dataType, "R8") == 0) { std::vector bdata; if (CGNSRead::readNodeData(cgioNum, children[nn], bdata) == 0) { baseInfo.referenceState[curName] = (double)bdata[0]; } } else if (strcmp(dataType, "R4") == 0) { std::vector bdata; if (CGNSRead::readNodeData(cgioNum, children[nn], bdata) == 0) { baseInfo.referenceState[curName] = (double)bdata[0]; } } else { std::cerr << "Unexpected data in ReferenceState_t" << std::endl; return 1; } } cgio_release_id(cgioNum, children[nn]); } return 0; } //------------------------------------------------------------------------------ int readZoneInfo(int cgioNum, double nodeId, CGNSRead::BaseInformation& baseInfo) { CGNSRead::char_33 nodeLabel; std::vector zoneChildId; getNodeChildrenId(cgioNum, nodeId, zoneChildId); int nflows = 0; std::size_t nn; for (nflows = 0, nn = 0; nn < zoneChildId.size(); nn++) { if (cgio_get_label(cgioNum, zoneChildId[nn], nodeLabel) != CG_OK) { std::cerr << "Error while reading nodelabel" << std::endl; return 1; } if ((nflows < 3) && (strcmp(nodeLabel, "FlowSolution_t") == 0)) { // Read only 3 Flow Solution to have a chance // to get Cell and Vertex variables // C=Cell V=Vertex // Layout sample : // 1. C init state (this one may be not processed due // to FlowSolutionPointers but we still // want some information about the two next node) // 2. C time 1s // 3. V time 1s readSolInfo(cgioNum, zoneChildId[nn], baseInfo); nflows++; } else if (strcmp(nodeLabel, "ZoneIterativeData_t") == 0) { // get time information readZoneIterInfo(cgioNum, zoneChildId[nn], baseInfo); } cgio_release_id(cgioNum, zoneChildId[nn]); } return 0; } //------------------------------------------------------------------------------ int readZoneInfo(int cgioNum, double zoneId, CGNSRead::ZoneInformation& zoneInfo) { if (cgio_get_name(cgioNum, zoneId, zoneInfo.name) != CG_OK) { return 1; } std::vector zoneChildren; getNodeChildrenId(cgioNum, zoneId, zoneChildren); for (double zoneChildId : zoneChildren) { CGNSRead::char_33 nodeLabel; if (cgio_get_label(cgioNum, zoneChildId, nodeLabel) == CG_OK) { if (strcmp(nodeLabel, "FamilyName_t") == 0) { CGNSRead::readNodeStringData(cgioNum, zoneChildId, zoneInfo.family); if (!zoneInfo.family.empty() && zoneInfo.family[0] == '/') { // This is a family path std::string::size_type pos = zoneInfo.family.find('/', 1); if (pos == std::string::npos) { // Invalid family path return 1; } // Remove /Base prefix of path for backward compatibility zoneInfo.family = zoneInfo.family.substr(pos + 1); } } else if (strcmp(nodeLabel, "ZoneBC_t") == 0) { std::vector zoneBCChildren; getNodeChildrenId(cgioNum, zoneChildId, zoneBCChildren); for (double zoneBCChildId : zoneBCChildren) { if (cgio_get_label(cgioNum, zoneBCChildId, nodeLabel) == CG_OK && strcmp(nodeLabel, "BC_t") == 0) { CGNSRead::ZoneBCInformation bcinfo; cgio_get_name(cgioNum, zoneBCChildId, bcinfo.name); // now read family info for this BC_t. std::vector bcChildren; getNodeChildrenId(cgioNum, zoneBCChildId, bcChildren); for (double bcChildId : bcChildren) { if (cgio_get_label(cgioNum, bcChildId, nodeLabel) == CG_OK && strcmp(nodeLabel, "FamilyName_t") == 0) { CGNSRead::readNodeStringData(cgioNum, bcChildId, bcinfo.family); if (!bcinfo.family.empty() && bcinfo.family[0] == '/') { // This is a family path std::string::size_type pos = bcinfo.family.find('/', 1); if (pos == std::string::npos) { // Invalid family path return 1; } bcinfo.family = bcinfo.family.substr(pos + 1); } break; } } releaseIds(cgioNum, bcChildren); zoneInfo.bcs.push_back(bcinfo); } } releaseIds(cgioNum, zoneBCChildren); } } } releaseIds(cgioNum, zoneChildren); return 0; } //------------------------------------------------------------------------------ void releaseIds(int cgioNum, const std::vector& ids) { for (auto iter = ids.begin(); iter != ids.end(); ++iter) { cgio_release_id(cgioNum, *iter); } } }