You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1276 lines
35 KiB
C++
1276 lines
35 KiB
C++
3 weeks ago
|
/*=========================================================================
|
||
|
|
||
|
Program: Visualization Toolkit
|
||
|
Module: vtkCGNSReaderInternal.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 "vtkCGNSReaderInternal.h"
|
||
|
|
||
|
#include "cgio_helpers.h"
|
||
|
#include "vtkCellType.h"
|
||
|
#include "vtkMultiProcessStream.h"
|
||
|
|
||
|
#include <algorithm>
|
||
|
|
||
|
namespace CGNSRead
|
||
|
{
|
||
|
//------------------------------------------------------------------------------
|
||
|
int setUpRind(const int cgioNum, const double rindId, int* rind)
|
||
|
{
|
||
|
CGNSRead::char_33 dataType;
|
||
|
if (cgio_get_data_type(cgioNum, rindId, dataType) != CG_OK)
|
||
|
{
|
||
|
std::cerr << "Problem while reading Rind data type\n";
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if (strcmp(dataType, "I4") == 0)
|
||
|
{
|
||
|
std::vector<vtkTypeInt32> mdata;
|
||
|
CGNSRead::readNodeData<vtkTypeInt32>(cgioNum, rindId, mdata);
|
||
|
for (std::size_t index = 0; index < mdata.size(); index++)
|
||
|
{
|
||
|
rind[index] = static_cast<int>(mdata[index]);
|
||
|
}
|
||
|
}
|
||
|
else if (strcmp(dataType, "I8") == 0)
|
||
|
{
|
||
|
std::vector<vtkTypeInt64> mdata;
|
||
|
CGNSRead::readNodeData<vtkTypeInt64>(cgioNum, rindId, mdata);
|
||
|
for (std::size_t index = 0; index < mdata.size(); index++)
|
||
|
{
|
||
|
rind[index] = static_cast<int>(mdata[index]);
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
int getFirstNodeId(
|
||
|
const int cgioNum, const double parentId, const char* label, double* id, const char* name)
|
||
|
{
|
||
|
int nId, n, nChildren, len;
|
||
|
int ier = 0;
|
||
|
char nodeLabel[CGIO_MAX_NAME_LENGTH + 1];
|
||
|
char nodeName[CGIO_MAX_NAME_LENGTH + 1];
|
||
|
|
||
|
if (cgio_number_children(cgioNum, parentId, &nChildren) != CG_OK)
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
if (nChildren < 1)
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
double* idList = new double[nChildren];
|
||
|
cgio_children_ids(cgioNum, parentId, 1, nChildren, &len, idList);
|
||
|
if (len != nChildren)
|
||
|
{
|
||
|
delete[] idList;
|
||
|
std::cerr << "Mismatch in number of children and child IDs read" << std::endl;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
nId = 0;
|
||
|
for (n = 0; n < nChildren; n++)
|
||
|
{
|
||
|
|
||
|
if (cgio_get_label(cgioNum, idList[n], nodeLabel))
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if (name != nullptr && cgio_get_name(cgioNum, idList[n], nodeName))
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if (0 == strcmp(nodeLabel, label) && (name == nullptr || 0 == strcmp(nodeName, name)))
|
||
|
{
|
||
|
*id = idList[n];
|
||
|
nId = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cgio_release_id(cgioNum, idList[n]);
|
||
|
}
|
||
|
if (nId != 0)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
n++;
|
||
|
while (n < nChildren)
|
||
|
{
|
||
|
cgio_release_id(cgioNum, idList[n]);
|
||
|
n++;
|
||
|
}
|
||
|
|
||
|
if (nId < 1)
|
||
|
{
|
||
|
*id = 0.0;
|
||
|
ier = 1;
|
||
|
}
|
||
|
|
||
|
delete[] idList;
|
||
|
return ier;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
int get_section_connectivity(const int cgioNum, const double cgioSectionId, const int dim,
|
||
|
const cgsize_t* srcStart, const cgsize_t* srcEnd, const cgsize_t* srcStride,
|
||
|
const cgsize_t* memStart, const cgsize_t* memEnd, const cgsize_t* memStride,
|
||
|
const cgsize_t* memDim, vtkIdType* localElements)
|
||
|
{
|
||
|
const char* connectivityPath = "ElementConnectivity";
|
||
|
double cgioElemConnectId;
|
||
|
char dataType[3];
|
||
|
std::size_t sizeOfCnt = 0;
|
||
|
|
||
|
cgio_get_node_id(cgioNum, cgioSectionId, connectivityPath, &cgioElemConnectId);
|
||
|
cgio_get_data_type(cgioNum, cgioElemConnectId, dataType);
|
||
|
|
||
|
if (strcmp(dataType, "I4") == 0)
|
||
|
{
|
||
|
sizeOfCnt = sizeof(int);
|
||
|
}
|
||
|
else if (strcmp(dataType, "I8") == 0)
|
||
|
{
|
||
|
sizeOfCnt = sizeof(cglong_t);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
std::cerr << "ElementConnectivity data_type unknown\n";
|
||
|
}
|
||
|
|
||
|
if (sizeOfCnt == sizeof(vtkIdType))
|
||
|
{
|
||
|
if (cgio_read_data_type(cgioNum, cgioElemConnectId, srcStart, srcEnd, srcStride, dataType, dim,
|
||
|
memDim, memStart, memEnd, memStride, (void*)localElements) != CG_OK)
|
||
|
{
|
||
|
char message[81];
|
||
|
cgio_error_message(message);
|
||
|
std::cerr << "cgio_read_data_type :" << message;
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Need to read into temp array to convert data
|
||
|
cgsize_t nn = 1;
|
||
|
for (int ii = 0; ii < dim; ii++)
|
||
|
{
|
||
|
nn *= memDim[ii];
|
||
|
}
|
||
|
if (sizeOfCnt == sizeof(int))
|
||
|
{
|
||
|
int* data = new int[nn];
|
||
|
if (data == nullptr)
|
||
|
{
|
||
|
std::cerr << "Allocation failed for temporary connectivity array\n";
|
||
|
}
|
||
|
|
||
|
if (cgio_read_data_type(cgioNum, cgioElemConnectId, srcStart, srcEnd, srcStride, "I4", dim,
|
||
|
memDim, memStart, memEnd, memStride, (void*)data) != CG_OK)
|
||
|
{
|
||
|
delete[] data;
|
||
|
char message[81];
|
||
|
cgio_error_message(message);
|
||
|
std::cerr << "cgio_read_data_type :" << message;
|
||
|
return 1;
|
||
|
}
|
||
|
for (cgsize_t n = 0; n < nn; n++)
|
||
|
{
|
||
|
localElements[n] = static_cast<vtkIdType>(data[n]);
|
||
|
}
|
||
|
delete[] data;
|
||
|
}
|
||
|
else if (sizeOfCnt == sizeof(cglong_t))
|
||
|
{
|
||
|
cglong_t* data = new cglong_t[nn];
|
||
|
if (data == nullptr)
|
||
|
{
|
||
|
std::cerr << "Allocation failed for temporary connectivity array\n";
|
||
|
return 1;
|
||
|
}
|
||
|
if (cgio_read_data_type(cgioNum, cgioElemConnectId, srcStart, srcEnd, srcStride, "I8", dim,
|
||
|
memDim, memStart, memEnd, memStride, (void*)data) != CG_OK)
|
||
|
{
|
||
|
delete[] data;
|
||
|
char message[81];
|
||
|
cgio_error_message(message);
|
||
|
std::cerr << "cgio_read_data_type :" << message;
|
||
|
return 1;
|
||
|
}
|
||
|
for (cgsize_t n = 0; n < nn; n++)
|
||
|
{
|
||
|
localElements[n] = static_cast<vtkIdType>(data[n]);
|
||
|
}
|
||
|
delete[] data;
|
||
|
}
|
||
|
}
|
||
|
cgio_release_id(cgioNum, cgioElemConnectId);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
int get_section_start_offset(const int cgioNum, const double cgioSectionId, const int dim,
|
||
|
const cgsize_t* srcStart, const cgsize_t* srcEnd, const cgsize_t* srcStride,
|
||
|
const cgsize_t* memStart, const cgsize_t* memEnd, const cgsize_t* memStride,
|
||
|
const cgsize_t* memDim, vtkIdType* localElementsIdx)
|
||
|
{
|
||
|
const char* offsetPath = "ElementStartOffset";
|
||
|
double cgioElemOffsetId;
|
||
|
char dataType[3];
|
||
|
std::size_t sizeOfCnt = 0;
|
||
|
|
||
|
if (cgio_get_node_id(cgioNum, cgioSectionId, offsetPath, &cgioElemOffsetId) != CG_OK)
|
||
|
{
|
||
|
// std::cerr << "ElementStartOffset not found\n";
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
cgio_get_data_type(cgioNum, cgioElemOffsetId, dataType);
|
||
|
|
||
|
if (strcmp(dataType, "I4") == 0)
|
||
|
{
|
||
|
sizeOfCnt = sizeof(int);
|
||
|
}
|
||
|
else if (strcmp(dataType, "I8") == 0)
|
||
|
{
|
||
|
sizeOfCnt = sizeof(cglong_t);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
std::cerr << "ElementStartOffset data_type unknown\n";
|
||
|
}
|
||
|
|
||
|
if (sizeOfCnt == sizeof(vtkIdType))
|
||
|
{
|
||
|
if (cgio_read_data_type(cgioNum, cgioElemOffsetId, srcStart, srcEnd, srcStride, dataType, dim,
|
||
|
memDim, memStart, memEnd, memStride, (void*)localElementsIdx) != CG_OK)
|
||
|
{
|
||
|
char message[81];
|
||
|
cgio_error_message(message);
|
||
|
std::cerr << "cgio_read_data_type :" << message;
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Need to read into temp array to convert data
|
||
|
cgsize_t nn = 1;
|
||
|
for (int ii = 0; ii < dim; ii++)
|
||
|
{
|
||
|
nn *= memDim[ii];
|
||
|
}
|
||
|
if (sizeOfCnt == sizeof(int))
|
||
|
{
|
||
|
int* data = new int[nn];
|
||
|
if (data == nullptr)
|
||
|
{
|
||
|
std::cerr << "Allocation failed for temporary connectivity offset array\n";
|
||
|
}
|
||
|
|
||
|
if (cgio_read_data_type(cgioNum, cgioElemOffsetId, srcStart, srcEnd, srcStride, "I4", dim,
|
||
|
memDim, memStart, memEnd, memStride, (void*)data) != CG_OK)
|
||
|
{
|
||
|
delete[] data;
|
||
|
char message[81];
|
||
|
cgio_error_message(message);
|
||
|
std::cerr << "cgio_read_data_type :" << message;
|
||
|
return 1;
|
||
|
}
|
||
|
for (cgsize_t n = 0; n < nn; n++)
|
||
|
{
|
||
|
localElementsIdx[n] = static_cast<vtkIdType>(data[n]);
|
||
|
}
|
||
|
delete[] data;
|
||
|
}
|
||
|
else if (sizeOfCnt == sizeof(cglong_t))
|
||
|
{
|
||
|
cglong_t* data = new cglong_t[nn];
|
||
|
if (data == nullptr)
|
||
|
{
|
||
|
std::cerr << "Allocation failed for temporary connectivity array\n";
|
||
|
return 1;
|
||
|
}
|
||
|
if (cgio_read_data_type(cgioNum, cgioElemOffsetId, srcStart, srcEnd, srcStride, "I8", dim,
|
||
|
memDim, memStart, memEnd, memStride, (void*)data) != CG_OK)
|
||
|
{
|
||
|
delete[] data;
|
||
|
char message[81];
|
||
|
cgio_error_message(message);
|
||
|
std::cerr << "cgio_read_data_type :" << message;
|
||
|
return 1;
|
||
|
}
|
||
|
for (cgsize_t n = 0; n < nn; n++)
|
||
|
{
|
||
|
localElementsIdx[n] = static_cast<vtkIdType>(data[n]);
|
||
|
}
|
||
|
delete[] data;
|
||
|
}
|
||
|
}
|
||
|
cgio_release_id(cgioNum, cgioElemOffsetId);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
int GetVTKElemType(
|
||
|
CGNS_ENUMT(ElementType_t) elemType, bool& higherOrderWarning, bool& cgnsOrderFlag)
|
||
|
{
|
||
|
int cellType;
|
||
|
higherOrderWarning = false;
|
||
|
cgnsOrderFlag = false;
|
||
|
//
|
||
|
switch (elemType)
|
||
|
{
|
||
|
case CGNS_ENUMV(NODE):
|
||
|
cellType = VTK_VERTEX;
|
||
|
break;
|
||
|
case CGNS_ENUMV(BAR_2):
|
||
|
cellType = VTK_LINE;
|
||
|
break;
|
||
|
case CGNS_ENUMV(BAR_3):
|
||
|
cellType = VTK_QUADRATIC_EDGE;
|
||
|
higherOrderWarning = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(BAR_4):
|
||
|
cellType = VTK_CUBIC_LINE;
|
||
|
higherOrderWarning = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(TRI_3):
|
||
|
cellType = VTK_TRIANGLE;
|
||
|
break;
|
||
|
case CGNS_ENUMV(TRI_6):
|
||
|
cellType = VTK_QUADRATIC_TRIANGLE;
|
||
|
higherOrderWarning = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(QUAD_4):
|
||
|
cellType = VTK_QUAD;
|
||
|
break;
|
||
|
case CGNS_ENUMV(QUAD_8):
|
||
|
cellType = VTK_QUADRATIC_QUAD;
|
||
|
higherOrderWarning = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(QUAD_9):
|
||
|
cellType = VTK_BIQUADRATIC_QUAD;
|
||
|
higherOrderWarning = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(TETRA_4):
|
||
|
cellType = VTK_TETRA;
|
||
|
break;
|
||
|
case CGNS_ENUMV(TETRA_10):
|
||
|
cellType = VTK_QUADRATIC_TETRA;
|
||
|
higherOrderWarning = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(PYRA_5):
|
||
|
cellType = VTK_PYRAMID;
|
||
|
break;
|
||
|
case CGNS_ENUMV(PYRA_14):
|
||
|
cellType = VTK_QUADRATIC_PYRAMID;
|
||
|
higherOrderWarning = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(PENTA_6):
|
||
|
cellType = VTK_WEDGE;
|
||
|
break;
|
||
|
case CGNS_ENUMV(PENTA_15):
|
||
|
cellType = VTK_QUADRATIC_WEDGE;
|
||
|
higherOrderWarning = true;
|
||
|
cgnsOrderFlag = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(PENTA_18):
|
||
|
cellType = VTK_BIQUADRATIC_QUADRATIC_WEDGE;
|
||
|
higherOrderWarning = true;
|
||
|
cgnsOrderFlag = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(HEXA_8):
|
||
|
cellType = VTK_HEXAHEDRON;
|
||
|
break;
|
||
|
case CGNS_ENUMV(HEXA_20):
|
||
|
cellType = VTK_QUADRATIC_HEXAHEDRON;
|
||
|
higherOrderWarning = true;
|
||
|
cgnsOrderFlag = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(HEXA_27):
|
||
|
cellType = VTK_TRIQUADRATIC_HEXAHEDRON;
|
||
|
higherOrderWarning = true;
|
||
|
cgnsOrderFlag = true;
|
||
|
break;
|
||
|
#if VTK_MAJOR_VERSION >= 8
|
||
|
case CGNS_ENUMV(TRI_10):
|
||
|
cellType = VTK_LAGRANGE_TRIANGLE;
|
||
|
higherOrderWarning = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(QUAD_16):
|
||
|
cellType = VTK_LAGRANGE_QUADRILATERAL;
|
||
|
higherOrderWarning = true;
|
||
|
cgnsOrderFlag = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(TETRA_20):
|
||
|
cellType = VTK_LAGRANGE_TETRAHEDRON;
|
||
|
higherOrderWarning = true;
|
||
|
cgnsOrderFlag = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(PYRA_30):
|
||
|
cellType = VTK_LAGRANGE_PYRAMID;
|
||
|
higherOrderWarning = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(PENTA_40):
|
||
|
cellType = VTK_LAGRANGE_WEDGE;
|
||
|
higherOrderWarning = true;
|
||
|
cgnsOrderFlag = true;
|
||
|
break;
|
||
|
case CGNS_ENUMV(HEXA_64):
|
||
|
cellType = VTK_LAGRANGE_HEXAHEDRON;
|
||
|
higherOrderWarning = true;
|
||
|
cgnsOrderFlag = true;
|
||
|
break;
|
||
|
#endif
|
||
|
default:
|
||
|
cellType = VTK_EMPTY_CELL;
|
||
|
break;
|
||
|
}
|
||
|
return cellType;
|
||
|
}
|
||
|
//----------------------------------------------------------------------
|
||
|
// static const int NULL_translate[27] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
|
||
|
// 16,17,18,19,20,21,22,23,24,25,26};
|
||
|
|
||
|
// CGNS --> VTK ordering of Elements
|
||
|
// static const int NODE_ToVTK[1] = { 0 };
|
||
|
//
|
||
|
// static const int BAR_2_ToVTK[2] = { 0, 1 };
|
||
|
//
|
||
|
// static const int BAR_3_ToVTK[3] = { 0, 1, 2 };
|
||
|
//
|
||
|
// static const int BAR_4_ToVTK[4] = { 0, 1, 2, 3 };
|
||
|
//
|
||
|
// static const int TRI_3_ToVTK[3] = { 0, 1, 2 };
|
||
|
//
|
||
|
// static const int TRI_6_ToVTK[6] = { 0, 1, 2, 3, 4, 5 };
|
||
|
//
|
||
|
// static const int QUAD_4_ToVTK[4] = { 0, 1, 2, 3 };
|
||
|
//
|
||
|
// static const int QUAD_8_ToVTK[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
|
||
|
//
|
||
|
// static const int QUAD_9_ToVTK[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
|
||
|
//
|
||
|
// static const int TETRA_4_ToVTK[4] = { 0, 1, 2, 3 };
|
||
|
//
|
||
|
// static const int TETRA_10_ToVTK[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||
|
//
|
||
|
// static const int PYRA_5_ToVTK[5] = { 0, 1, 2, 3, 4 };
|
||
|
//
|
||
|
// static const int PYRA_14_ToVTK[14] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
|
||
|
//
|
||
|
// static const int PENTA_6_ToVTK[6] = { 0, 1, 2, 3, 4, 5 };
|
||
|
|
||
|
static const int PENTA_15_ToVTK[15] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14, 9, 10, 11 };
|
||
|
|
||
|
static const int PENTA_18_ToVTK[18] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14, 9, 10, 11, 15, 16,
|
||
|
17 };
|
||
|
|
||
|
// static const int HEXA_8_ToVTK[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
|
||
|
|
||
|
static const int HEXA_20_ToVTK[20] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 12, 13,
|
||
|
14, 15 };
|
||
|
|
||
|
static const int HEXA_27_ToVTK[27] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 12, 13,
|
||
|
14, 15, 24, 22, 21, 23, 20, 25, 26 };
|
||
|
|
||
|
static const int TETRA_20_ToVTK[20] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17,
|
||
|
18, 19, 16 };
|
||
|
|
||
|
static const int PENTA_40_ToVTK[40] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, 19, 20, 21, 22,
|
||
|
23, 12, 13, 14, 15, 16, 17, 24, 37, 25, 26, 28, 27, 29, 30, 32, 31, 34, 33, 35, 36, 38, 39 };
|
||
|
|
||
|
static const int HEXA_64_ToVTK[64] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 12, 15, 14, 24, 25,
|
||
|
26, 27, 29, 28, 31, 30, 16, 17, 18, 19, 22, 23, 20, 21, 49, 48, 50, 51, 40, 41, 43, 42, 36, 37,
|
||
|
39, 38, 45, 44, 46, 47, 32, 33, 35, 34, 52, 53, 55, 54, 56, 57, 59, 58, 60, 61, 63, 62 };
|
||
|
|
||
|
static const int PYRA_30_ToVTK[30] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 9, 12, 11, 13, 14, 15, 16, 17,
|
||
|
18, 19, 20, 25, 26, 27, 28, 21, 22, 24, 23, 29 };
|
||
|
|
||
|
static const int QUAD_16_ToVTK[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 9, 8, 11, 10, 12, 13, 15, 14 };
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
inline const int* getTranslator(const int cellType)
|
||
|
{
|
||
|
switch (cellType)
|
||
|
{
|
||
|
case VTK_VERTEX:
|
||
|
case VTK_LINE:
|
||
|
case VTK_QUADRATIC_EDGE:
|
||
|
case VTK_CUBIC_LINE:
|
||
|
case VTK_TRIANGLE:
|
||
|
case VTK_QUADRATIC_TRIANGLE:
|
||
|
case VTK_QUAD:
|
||
|
case VTK_QUADRATIC_QUAD:
|
||
|
case VTK_BIQUADRATIC_QUAD:
|
||
|
case VTK_TETRA:
|
||
|
case VTK_QUADRATIC_TETRA:
|
||
|
case VTK_PYRAMID:
|
||
|
case VTK_QUADRATIC_PYRAMID:
|
||
|
case VTK_WEDGE:
|
||
|
return nullptr;
|
||
|
case VTK_QUADRATIC_WEDGE:
|
||
|
return CGNSRead::PENTA_15_ToVTK;
|
||
|
case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
|
||
|
return CGNSRead::PENTA_18_ToVTK;
|
||
|
case VTK_HEXAHEDRON:
|
||
|
return nullptr;
|
||
|
case VTK_QUADRATIC_HEXAHEDRON:
|
||
|
return CGNSRead::HEXA_20_ToVTK;
|
||
|
case VTK_TRIQUADRATIC_HEXAHEDRON:
|
||
|
return CGNSRead::HEXA_27_ToVTK;
|
||
|
#if VTK_MAJOR_VERSION >= 8
|
||
|
case VTK_LAGRANGE_QUADRILATERAL:
|
||
|
return CGNSRead::QUAD_16_ToVTK;
|
||
|
case VTK_LAGRANGE_TETRAHEDRON:
|
||
|
return CGNSRead::TETRA_20_ToVTK;
|
||
|
case VTK_LAGRANGE_WEDGE:
|
||
|
return CGNSRead::PENTA_40_ToVTK;
|
||
|
case VTK_LAGRANGE_HEXAHEDRON:
|
||
|
return CGNSRead::HEXA_64_ToVTK;
|
||
|
case VTK_LAGRANGE_PYRAMID:
|
||
|
return CGNSRead::PYRA_30_ToVTK;
|
||
|
#endif
|
||
|
default:
|
||
|
return nullptr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
void CGNS2VTKorder(const vtkIdType size, const int* cells_types, vtkIdType* elements)
|
||
|
{
|
||
|
const int maxPointsPerCells = 64;
|
||
|
int tmp[maxPointsPerCells];
|
||
|
const int* translator;
|
||
|
vtkIdType pos = 0;
|
||
|
for (vtkIdType icell = 0; icell < size; ++icell)
|
||
|
{
|
||
|
translator = getTranslator(cells_types[icell]);
|
||
|
vtkIdType numPointsPerCell = elements[pos];
|
||
|
pos++;
|
||
|
if (translator != nullptr)
|
||
|
{
|
||
|
for (vtkIdType ip = 0; ip < numPointsPerCell; ++ip)
|
||
|
{
|
||
|
tmp[ip] = elements[translator[ip] + pos];
|
||
|
}
|
||
|
for (vtkIdType ip = 0; ip < numPointsPerCell; ++ip)
|
||
|
{
|
||
|
elements[pos + ip] = tmp[ip];
|
||
|
}
|
||
|
}
|
||
|
pos += numPointsPerCell;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
void CGNS2VTKorderMonoElem(const vtkIdType size, const int cell_type, vtkIdType* elements)
|
||
|
{
|
||
|
const int maxPointsPerCells = 64;
|
||
|
|
||
|
int tmp[maxPointsPerCells];
|
||
|
const int* translator;
|
||
|
translator = getTranslator(cell_type);
|
||
|
if (translator == nullptr)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
vtkIdType pos = 0;
|
||
|
for (vtkIdType icell = 0; icell < size; ++icell)
|
||
|
{
|
||
|
vtkIdType numPointsPerCell = elements[pos];
|
||
|
pos++;
|
||
|
for (vtkIdType ip = 0; ip < numPointsPerCell; ++ip)
|
||
|
{
|
||
|
tmp[ip] = elements[translator[ip] + pos];
|
||
|
}
|
||
|
for (vtkIdType ip = 0; ip < numPointsPerCell; ++ip)
|
||
|
{
|
||
|
elements[pos + ip] = tmp[ip];
|
||
|
}
|
||
|
pos += numPointsPerCell;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
bool testValidVector(const CGNSVector& item)
|
||
|
{
|
||
|
// apply some logic and return true or false
|
||
|
return (item.numComp == 0);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
void fillVectorsFromVars(std::vector<CGNSRead::CGNSVariable>& vars,
|
||
|
std::vector<CGNSRead::CGNSVector>& vectors, const int physicalDim)
|
||
|
{
|
||
|
// get number of scalars and vectors
|
||
|
const std::size_t nvar = vars.size();
|
||
|
std::size_t len;
|
||
|
char_33 name;
|
||
|
|
||
|
for (std::size_t n = 0; n < nvar; ++n)
|
||
|
{
|
||
|
vars[n].isComponent = false;
|
||
|
vars[n].xyzIndex = 0;
|
||
|
}
|
||
|
|
||
|
for (std::size_t n = 0; n < nvar; ++n)
|
||
|
{
|
||
|
len = strlen(vars[n].name) - 1;
|
||
|
// CGNS convention uses CamelCase for vector naming (VectorX)
|
||
|
// For added convenience, snake_case is supported (vector_x)
|
||
|
switch (vars[n].name[len])
|
||
|
{
|
||
|
case 'X':
|
||
|
vars[n].xyzIndex = 1;
|
||
|
vars[n].isComponent = true;
|
||
|
break;
|
||
|
case 'Y':
|
||
|
vars[n].xyzIndex = 2;
|
||
|
vars[n].isComponent = true;
|
||
|
break;
|
||
|
case 'Z':
|
||
|
vars[n].xyzIndex = 3;
|
||
|
vars[n].isComponent = true;
|
||
|
break;
|
||
|
case 'x':
|
||
|
if (len > 0 && vars[n].name[len - 1] == '_')
|
||
|
{
|
||
|
vars[n].xyzIndex = 1;
|
||
|
vars[n].isComponent = true;
|
||
|
len -= 1;
|
||
|
}
|
||
|
break;
|
||
|
case 'y':
|
||
|
if (len > 0 && vars[n].name[len - 1] == '_')
|
||
|
{
|
||
|
vars[n].xyzIndex = 2;
|
||
|
vars[n].isComponent = true;
|
||
|
len -= 1;
|
||
|
}
|
||
|
break;
|
||
|
case 'z':
|
||
|
if (len > 0 && vars[n].name[len - 1] == '_')
|
||
|
{
|
||
|
vars[n].xyzIndex = 3;
|
||
|
vars[n].isComponent = true;
|
||
|
len -= 1;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
if (vars[n].isComponent == true)
|
||
|
{
|
||
|
strcpy(name, vars[n].name);
|
||
|
name[len] = '\0';
|
||
|
std::vector<CGNSRead::CGNSVector>::iterator iter = CGNSRead::getVectorFromName(vectors, name);
|
||
|
if (iter != vectors.end())
|
||
|
{
|
||
|
iter->numComp += vars[n].xyzIndex;
|
||
|
iter->xyzIndex[vars[n].xyzIndex - 1] = (int)n;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CGNSRead::CGNSVector newVector;
|
||
|
newVector.xyzIndex[0] = -1;
|
||
|
newVector.xyzIndex[1] = -1;
|
||
|
newVector.xyzIndex[2] = -1;
|
||
|
newVector.numComp = vars[n].xyzIndex;
|
||
|
newVector.xyzIndex[vars[n].xyzIndex - 1] = (int)n;
|
||
|
strcpy(newVector.name, name);
|
||
|
vectors.push_back(newVector);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Detect and tag invalid vector :
|
||
|
bool invalid = false;
|
||
|
for (auto& iter : vectors)
|
||
|
{
|
||
|
// Check if number of component agrees with phys_dim
|
||
|
if (((physicalDim == 3) && (iter.numComp != 6)) || ((physicalDim == 2) && (iter.numComp != 3)))
|
||
|
{
|
||
|
for (int index = 0; index < physicalDim; index++)
|
||
|
{
|
||
|
int nv = iter.xyzIndex[index];
|
||
|
if (nv >= 0)
|
||
|
{
|
||
|
vars[nv].isComponent = false;
|
||
|
}
|
||
|
}
|
||
|
iter.numComp = 0;
|
||
|
invalid = true;
|
||
|
}
|
||
|
// Check if a variable is present with a similar
|
||
|
// name as the vector being built
|
||
|
if (CGNSRead::isACGNSVariable(vars, iter.name) == true)
|
||
|
{
|
||
|
// vtkWarningMacro ( "Warning, vector " << iter->name
|
||
|
// << " can't be assembled." << std::endl );
|
||
|
for (int index = 0; index < physicalDim; index++)
|
||
|
{
|
||
|
int n = iter.xyzIndex[index];
|
||
|
if (n >= 0)
|
||
|
{
|
||
|
vars[n].isComponent = false;
|
||
|
}
|
||
|
}
|
||
|
iter.numComp = 0;
|
||
|
invalid = true;
|
||
|
}
|
||
|
if (iter.numComp > 0)
|
||
|
{
|
||
|
// Check if DataType_t are identical for all components
|
||
|
if ((vars[iter.xyzIndex[0]].dt != vars[iter.xyzIndex[1]].dt) ||
|
||
|
(vars[iter.xyzIndex[0]].dt != vars[iter.xyzIndex[physicalDim - 1]].dt))
|
||
|
{
|
||
|
for (int index = 0; index < physicalDim; index++)
|
||
|
{
|
||
|
int n = iter.xyzIndex[index];
|
||
|
if (n >= 0)
|
||
|
{
|
||
|
vars[n].isComponent = false;
|
||
|
}
|
||
|
}
|
||
|
iter.numComp = 0;
|
||
|
invalid = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// Remove invalid vectors
|
||
|
if (invalid == true)
|
||
|
{
|
||
|
vectors.erase(
|
||
|
std::remove_if(vectors.begin(), vectors.end(), CGNSRead::testValidVector), vectors.end());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
bool vtkCGNSMetaData::Parse(const char* cgnsFileName)
|
||
|
{
|
||
|
|
||
|
if (!cgnsFileName)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (this->LastReadFilename == cgnsFileName)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
int cgioNum;
|
||
|
int ier;
|
||
|
double rootId;
|
||
|
char nodeLabel[CGIO_MAX_NAME_LENGTH + 1];
|
||
|
|
||
|
// use cgio routine to open the file
|
||
|
if (cgio_open_file(cgnsFileName, CGIO_MODE_READ, CG_FILE_NONE, &cgioNum) != CG_OK)
|
||
|
{
|
||
|
cgio_error_exit("cgio_file_open");
|
||
|
}
|
||
|
if (cgio_get_root_id(cgioNum, &rootId) != CG_OK)
|
||
|
{
|
||
|
cgio_error_exit("cgio_get_root_id");
|
||
|
}
|
||
|
|
||
|
// Get base id list :
|
||
|
std::vector<double> baseIds;
|
||
|
ier = readBaseIds(cgioNum, rootId, baseIds);
|
||
|
if (ier != 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (!this->baseList.empty())
|
||
|
{
|
||
|
this->baseList.clear();
|
||
|
}
|
||
|
this->baseList.resize(baseIds.size());
|
||
|
// Read base list
|
||
|
for (std::size_t numBase = 0; numBase < baseIds.size(); numBase++)
|
||
|
{
|
||
|
// base names for later selection
|
||
|
readBaseCoreInfo(cgioNum, baseIds[numBase], this->baseList[numBase]);
|
||
|
|
||
|
std::vector<double> baseChildId;
|
||
|
|
||
|
getNodeChildrenId(cgioNum, baseIds[numBase], baseChildId);
|
||
|
|
||
|
std::size_t nzones = 0;
|
||
|
std::size_t nn;
|
||
|
for (nzones = 0, nn = 0; nn < baseChildId.size(); ++nn)
|
||
|
{
|
||
|
if (cgio_get_label(cgioNum, baseChildId[nn], nodeLabel) != CG_OK)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (strcmp(nodeLabel, "Zone_t") == 0)
|
||
|
{
|
||
|
if (nzones < nn)
|
||
|
{
|
||
|
baseChildId[nzones] = baseChildId[nn];
|
||
|
}
|
||
|
nzones++;
|
||
|
|
||
|
this->baseList[numBase].zones.emplace_back();
|
||
|
if (readZoneInfo(cgioNum, baseChildId[nn], this->baseList[numBase].zones.back()) != CG_OK)
|
||
|
{
|
||
|
this->baseList[numBase].zones.pop_back();
|
||
|
}
|
||
|
}
|
||
|
else if (strcmp(nodeLabel, "Family_t") == 0)
|
||
|
{
|
||
|
readBaseFamily(cgioNum, baseChildId[nn], this->baseList[numBase]);
|
||
|
}
|
||
|
else if (strcmp(nodeLabel, "BaseIterativeData_t") == 0)
|
||
|
{
|
||
|
readBaseIteration(cgioNum, baseChildId[nn], this->baseList[numBase]);
|
||
|
}
|
||
|
else if (strcmp(nodeLabel, "ReferenceState_t") == 0)
|
||
|
{
|
||
|
readBaseReferenceState(cgioNum, baseChildId[nn], this->baseList[numBase]);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cgio_release_id(cgioNum, baseChildId[nn]);
|
||
|
}
|
||
|
}
|
||
|
this->baseList[numBase].nzones = static_cast<int>(nzones);
|
||
|
|
||
|
if (this->baseList[numBase].times.empty())
|
||
|
{
|
||
|
// If no time information were found
|
||
|
// just put default values
|
||
|
this->baseList[numBase].steps.clear();
|
||
|
this->baseList[numBase].times.clear();
|
||
|
this->baseList[numBase].steps.push_back(0);
|
||
|
this->baseList[numBase].times.push_back(0.0);
|
||
|
}
|
||
|
|
||
|
if (nzones > 0)
|
||
|
{
|
||
|
// variable name and more, based on first zone only
|
||
|
readZoneInfo(cgioNum, baseChildId[0], this->baseList[numBase]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Same Timesteps in all root nodes
|
||
|
// or separated time range by root nodes
|
||
|
// timesteps need to be sorted for each root node
|
||
|
this->GlobalTime.clear();
|
||
|
for (std::size_t numBase = 0; numBase < baseList.size(); numBase++)
|
||
|
{
|
||
|
if (numBase == 0)
|
||
|
{
|
||
|
this->GlobalTime = this->baseList[numBase].times;
|
||
|
continue;
|
||
|
}
|
||
|
const std::vector<double>& times = this->baseList[numBase].times;
|
||
|
if (times.front() > this->GlobalTime.back())
|
||
|
{
|
||
|
this->GlobalTime.insert(this->GlobalTime.end(), times.begin(), times.end());
|
||
|
}
|
||
|
|
||
|
if (times.back() < this->GlobalTime.front())
|
||
|
{
|
||
|
this->GlobalTime.insert(this->GlobalTime.begin(), times.begin(), times.end());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this->LastReadFilename = cgnsFileName;
|
||
|
cgio_close_file(cgioNum);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
void vtkCGNSMetaData::PrintSelf(std::ostream& os)
|
||
|
{
|
||
|
os << "--> vtkCGNSMetaData" << std::endl;
|
||
|
os << "LastReadFileName: " << this->LastReadFilename << std::endl;
|
||
|
os << "Base information:" << std::endl;
|
||
|
for (std::size_t b = 0; b < this->baseList.size(); b++)
|
||
|
{
|
||
|
os << " Base name: " << this->baseList[b].name << std::endl;
|
||
|
os << " number of zones: " << this->baseList[b].nzones << std::endl;
|
||
|
os << " number of time steps: " << this->baseList[b].times.size() << std::endl;
|
||
|
os << " use unsteady grid: " << this->baseList[b].useGridPointers << std::endl;
|
||
|
os << " use unsteady flow: " << this->baseList[b].useFlowPointers << std::endl;
|
||
|
|
||
|
for (int i = 0; i < this->baseList[b].PointDataArraySelection.GetNumberOfArrays(); ++i)
|
||
|
{
|
||
|
os << " Vertex :: ";
|
||
|
os << this->baseList[b].PointDataArraySelection.GetArrayName(i) << std::endl;
|
||
|
}
|
||
|
for (int i = 0; i < this->baseList[b].CellDataArraySelection.GetNumberOfArrays(); ++i)
|
||
|
{
|
||
|
os << " Cell :: ";
|
||
|
os << this->baseList[b].CellDataArraySelection.GetArrayName(i) << std::endl;
|
||
|
}
|
||
|
|
||
|
os << " Family Number: " << this->baseList[b].family.size() << std::endl;
|
||
|
for (const auto& fam : this->baseList[b].family)
|
||
|
{
|
||
|
os << " Family: " << fam.name << " is BC: " << fam.isBC << std::endl;
|
||
|
}
|
||
|
|
||
|
os << " Reference State:" << std::endl;
|
||
|
for (const auto& iter : this->baseList[b].referenceState)
|
||
|
{
|
||
|
os << " Variable: " << iter.first;
|
||
|
os << " Value: " << iter.second << std::endl;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
static void BroadcastCGNSString(vtkMultiProcessController* ctrl, CGNSRead::char_33& str)
|
||
|
{
|
||
|
int len = 33;
|
||
|
ctrl->Broadcast(&len, 1, 0);
|
||
|
ctrl->Broadcast(&str[0], len, 0);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
static void BroadcastString(vtkMultiProcessController* controller, std::string& str, int rank)
|
||
|
{
|
||
|
unsigned long len = static_cast<unsigned long>(str.size()) + 1;
|
||
|
controller->Broadcast(&len, 1, 0);
|
||
|
if (len)
|
||
|
{
|
||
|
if (rank)
|
||
|
{
|
||
|
std::vector<char> tmp;
|
||
|
tmp.resize(len);
|
||
|
controller->Broadcast(&(tmp[0]), len, 0);
|
||
|
str = &tmp[0];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
const char* start = str.c_str();
|
||
|
std::vector<char> tmp(start, start + len);
|
||
|
controller->Broadcast(&tmp[0], len, 0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//------------------------------------------------------------------------------
|
||
|
static void BroadcastDoubleVector(
|
||
|
vtkMultiProcessController* controller, std::vector<double>& dvec, int rank)
|
||
|
{
|
||
|
unsigned long len = static_cast<unsigned long>(dvec.size());
|
||
|
controller->Broadcast(&len, 1, 0);
|
||
|
if (rank)
|
||
|
{
|
||
|
dvec.resize(len);
|
||
|
}
|
||
|
if (len)
|
||
|
{
|
||
|
controller->Broadcast(&dvec[0], len, 0);
|
||
|
}
|
||
|
}
|
||
|
//------------------------------------------------------------------------------
|
||
|
static void BroadcastIntVector(
|
||
|
vtkMultiProcessController* controller, std::vector<int>& ivec, int rank)
|
||
|
{
|
||
|
unsigned long len = static_cast<unsigned long>(ivec.size());
|
||
|
controller->Broadcast(&len, 1, 0);
|
||
|
if (rank)
|
||
|
{
|
||
|
ivec.resize(len);
|
||
|
}
|
||
|
if (len)
|
||
|
{
|
||
|
controller->Broadcast(&ivec[0], len, 0);
|
||
|
}
|
||
|
}
|
||
|
//------------------------------------------------------------------------------
|
||
|
static void BroadcastSelection(
|
||
|
vtkMultiProcessController* controller, CGNSRead::vtkCGNSArraySelection& selection, int rank)
|
||
|
{
|
||
|
unsigned long len = static_cast<unsigned long>(selection.size());
|
||
|
controller->Broadcast(&len, 1, 0);
|
||
|
if (rank == 0)
|
||
|
{
|
||
|
int tmp;
|
||
|
for (auto& ite : selection)
|
||
|
{
|
||
|
unsigned long len2 = static_cast<unsigned long>(ite.first.size()) + 1;
|
||
|
controller->Broadcast(&len2, 1, 0);
|
||
|
if (len2)
|
||
|
{
|
||
|
const char* start = ite.first.c_str();
|
||
|
std::vector<char> tmpVector(start, start + len2);
|
||
|
controller->Broadcast(&tmpVector[0], len2, 0);
|
||
|
}
|
||
|
tmp = (int)ite.second;
|
||
|
controller->Broadcast(&tmp, 1, 0);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
unsigned long i;
|
||
|
for (i = 0; i < len; ++i)
|
||
|
{
|
||
|
std::string key;
|
||
|
int tmp;
|
||
|
CGNSRead::BroadcastString(controller, key, rank);
|
||
|
selection[key] = false;
|
||
|
controller->Broadcast(&tmp, 1, 0);
|
||
|
selection[key] = (tmp != 0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
static void BroadcastRefState(
|
||
|
vtkMultiProcessController* controller, std::map<std::string, double>& refInfo, int rank)
|
||
|
{
|
||
|
unsigned long len = static_cast<unsigned long>(refInfo.size());
|
||
|
controller->Broadcast(&len, 1, 0);
|
||
|
if (rank == 0)
|
||
|
{
|
||
|
for (auto& ite : refInfo)
|
||
|
{
|
||
|
unsigned long len2 = static_cast<unsigned long>(ite.first.size()) + 1;
|
||
|
controller->Broadcast(&len2, 1, 0);
|
||
|
if (len2)
|
||
|
{
|
||
|
const char* start = ite.first.c_str();
|
||
|
std::vector<char> tmp(start, start + len2);
|
||
|
controller->Broadcast(&tmp[0], len2, 0);
|
||
|
}
|
||
|
controller->Broadcast(&ite.second, 1, 0);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (unsigned long i = 0; i < len; ++i)
|
||
|
{
|
||
|
std::string key;
|
||
|
CGNSRead::BroadcastString(controller, key, rank);
|
||
|
refInfo[key] = 0.0;
|
||
|
controller->Broadcast(&refInfo[key], 1, 0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
static void BroadcastFamilies(vtkMultiProcessController* controller,
|
||
|
std::vector<CGNSRead::FamilyInformation>& famInfo, int rank)
|
||
|
{
|
||
|
unsigned long len = static_cast<unsigned long>(famInfo.size());
|
||
|
controller->Broadcast(&len, 1, 0);
|
||
|
if (rank != 0)
|
||
|
{
|
||
|
famInfo.resize(len);
|
||
|
}
|
||
|
for (auto& ite : famInfo)
|
||
|
{
|
||
|
BroadcastString(controller, ite.name, rank);
|
||
|
int flags = 0;
|
||
|
if (rank == 0)
|
||
|
{
|
||
|
if (ite.isBC == true)
|
||
|
{
|
||
|
flags = 1;
|
||
|
}
|
||
|
controller->Broadcast(&flags, 1, 0);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
controller->Broadcast(&flags, 1, 0);
|
||
|
if ((flags & 1) != 0)
|
||
|
{
|
||
|
ite.isBC = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
static void BroadcastZones(
|
||
|
vtkMultiProcessController* controller, std::vector<CGNSRead::ZoneInformation>& zoneInfo, int rank)
|
||
|
{
|
||
|
vtkMultiProcessStream stream;
|
||
|
if (rank == 0)
|
||
|
{
|
||
|
stream << static_cast<unsigned int>(zoneInfo.size());
|
||
|
for (auto& zinfo : zoneInfo)
|
||
|
{
|
||
|
stream.Push(zinfo.name, 33);
|
||
|
stream << zinfo.family;
|
||
|
stream << static_cast<unsigned int>(zinfo.bcs.size());
|
||
|
for (auto& bcinfo : zinfo.bcs)
|
||
|
{
|
||
|
stream.Push(bcinfo.name, 33);
|
||
|
stream << bcinfo.family;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
controller->Broadcast(stream, 0);
|
||
|
if (rank != 0)
|
||
|
{
|
||
|
unsigned int count;
|
||
|
stream >> count;
|
||
|
zoneInfo.resize(count);
|
||
|
|
||
|
for (auto& zinfo : zoneInfo)
|
||
|
{
|
||
|
unsigned int size = 33;
|
||
|
char* cref = zinfo.name;
|
||
|
stream.Pop(cref, size);
|
||
|
stream >> zinfo.family;
|
||
|
stream >> count;
|
||
|
zinfo.bcs.resize(count);
|
||
|
for (auto& bcinfo : zinfo.bcs)
|
||
|
{
|
||
|
cref = bcinfo.name;
|
||
|
stream.Pop(cref, size);
|
||
|
stream >> bcinfo.family;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
void vtkCGNSMetaData::Broadcast(vtkMultiProcessController* controller, int rank)
|
||
|
{
|
||
|
unsigned long len = static_cast<unsigned long>(this->baseList.size());
|
||
|
controller->Broadcast(&len, 1, 0);
|
||
|
if (rank != 0)
|
||
|
{
|
||
|
this->baseList.resize(len);
|
||
|
}
|
||
|
for (auto& ite : this->baseList)
|
||
|
{
|
||
|
CGNSRead::BroadcastCGNSString(controller, ite.name);
|
||
|
controller->Broadcast(&ite.cellDim, 1, 0);
|
||
|
controller->Broadcast(&ite.physicalDim, 1, 0);
|
||
|
controller->Broadcast(&ite.baseNumber, 1, 0);
|
||
|
controller->Broadcast(&ite.nzones, 1, 0);
|
||
|
|
||
|
int flags = 0;
|
||
|
if (rank == 0)
|
||
|
{
|
||
|
if (ite.useGridPointers == true)
|
||
|
{
|
||
|
flags = 1;
|
||
|
}
|
||
|
if (ite.useFlowPointers == true)
|
||
|
{
|
||
|
flags = (flags | 2);
|
||
|
}
|
||
|
controller->Broadcast(&flags, 1, 0);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
controller->Broadcast(&flags, 1, 0);
|
||
|
if ((flags & 1) != 0)
|
||
|
{
|
||
|
ite.useGridPointers = true;
|
||
|
}
|
||
|
if ((flags & 2) != 0)
|
||
|
{
|
||
|
ite.useFlowPointers = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CGNSRead::BroadcastRefState(controller, ite.referenceState, rank);
|
||
|
CGNSRead::BroadcastFamilies(controller, ite.family, rank);
|
||
|
CGNSRead::BroadcastZones(controller, ite.zones, rank);
|
||
|
|
||
|
CGNSRead::BroadcastSelection(controller, ite.PointDataArraySelection, rank);
|
||
|
CGNSRead::BroadcastSelection(controller, ite.CellDataArraySelection, rank);
|
||
|
|
||
|
BroadcastIntVector(controller, ite.steps, rank);
|
||
|
BroadcastDoubleVector(controller, ite.times, rank);
|
||
|
}
|
||
|
CGNSRead::BroadcastString(controller, this->LastReadFilename, rank);
|
||
|
BroadcastDoubleVector(controller, this->GlobalTime, rank);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
bool ReadBase(vtkCGNSReader* reader, const BaseInformation& baseInfo)
|
||
|
{
|
||
|
auto baseSelection = reader->GetBaseSelection();
|
||
|
if (!baseSelection->ArrayIsEnabled(baseInfo.name))
|
||
|
{
|
||
|
// base has not been enabled.
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
bool ReadGridForZone(
|
||
|
vtkCGNSReader* reader, const BaseInformation& baseInfo, const ZoneInformation& zoneInfo)
|
||
|
{
|
||
|
if (!reader->GetLoadMesh())
|
||
|
{
|
||
|
return false;
|
||
|
} // mesh (aka grid) is not enabled.
|
||
|
|
||
|
auto baseSelection = reader->GetBaseSelection();
|
||
|
if (!baseSelection->ArrayIsEnabled(baseInfo.name))
|
||
|
{
|
||
|
// base has not been enabled.
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// check if the zone's family is enabled.
|
||
|
auto familySelection = reader->GetFamilySelection();
|
||
|
if (familySelection->ArrayExists(zoneInfo.family.c_str()) &&
|
||
|
!familySelection->ArrayIsEnabled(zoneInfo.family.c_str()))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
bool ReadPatchesForBase(vtkCGNSReader* reader, const BaseInformation&)
|
||
|
{
|
||
|
if (!reader->GetLoadBndPatch())
|
||
|
{
|
||
|
// patches have been globally disabled.
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
bool ReadPatch(vtkCGNSReader* reader, const BaseInformation&, const ZoneInformation&,
|
||
|
const std::string& patchFamilyname)
|
||
|
{
|
||
|
auto familySelection = reader->GetFamilySelection();
|
||
|
|
||
|
if (!patchFamilyname.empty() && !familySelection->ArrayIsEnabled(patchFamilyname.c_str()))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
} // end of namespace
|