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.
AppFlow/FITK_Interface/FITKInterfaceIOHDF5/FITKInterfaceHDF5AdaptorMes...

308 lines
12 KiB
C++

#include "FITKInterfaceHDF5AdaptorMesh.h"
#include "FITK_Kernel/FITKCore/FITKVec3D.h"
#include "FITK_Kernel/FITKCore/FITKEnumTransformer.hpp"
#include "FITK_Interface/FITKInterfaceIO/FITKAbstractHDF5Reader.h"
#include "FITK_Interface/FITKInterfaceModel/FITKElementFactory.h"
#include "FITK_Interface/FITKInterfaceIO/FITKAbstractHDF5Writer.h"
#include "FITK_Interface/FITKInterfaceModel/FITKElementHex.h"
#include "FITK_Interface/FITKInterfaceModel/FITKElementQuad.h"
#include "FITK_Interface/FITKInterfaceModel/FITKElementTet.h"
#include "FITK_Interface/FITKInterfaceModel/FITKElementTri.h"
#include "FITK_Interface/FITKInterfaceModel/FITKModelSet.h"
#include "FITK_Interface/FITKInterfaceModel/FITKAbstractElement.h"
#include "FITK_Interface/FITKInterfaceModel/FITKComponentManager.h"
#include "FITK_Interface/FITKInterfaceModel/FITKUnstructuredMesh.h"
#include "FITK_Interface/FITKInterfaceModel/FITKUnstructuredMesh.h"
#include <array>
#include <QSet>
#include <QList>
#include <QMultiHash>
#include "H5Cpp.h"
namespace IO
{
QString FITKInterfaceHDF5AdaptorMesh::getAdaptorClass()
{
return "FITKInterfaceHDF5AdaptorMesh";
}
bool FITKInterfaceHDF5AdaptorMesh::adaptR()
{
//auto mesh = dynamic_cast<Interface::FITKUnstructuredMesh*>(_dataObj);
//if (!_reader || !mesh || !_h5Group) return false;
//bool isR = true;
////写出节点
//isR &= readNode(mesh, *_h5Group);
////写出单元
//isR &= readElement(mesh, *_h5Group);
//return isR;
return false;
}
bool FITKInterfaceHDF5AdaptorMesh::adaptW()
{
//auto mesh = dynamic_cast<Interface::FITKUnstructuredMesh*>(_dataObj);
//if (!_writer || !mesh || !_h5Group) return false;
//bool isW = true;
////写出节点
//isW &= writeNode(mesh, *_h5Group);
////写出单元
//isW &= writeElement(mesh, *_h5Group);
//return isW;
return false;
}
bool FITKInterfaceHDF5AdaptorMesh::readNode(Interface::FITKUnstructuredMesh* mesh, H5::Group& h5Group)
{
if (mesh == nullptr) return false;
//PointIDs
if (!h5Group.nameExists("PointIDs")) return false;
auto PointIDSet = h5Group.openDataSet("PointIDs");
int n, m;
//Points
if (!getDataSetDim(h5Group, "Points", n, m)) return false;
auto pointsSet = h5Group.openDataSet("Points");
//点
// 行数 // 列数
hsize_t dimPtData[2]{ n ,m };
H5::DataSpace ptDataSpace(2, dimPtData);
//点ID
// 行数 // 列数
hsize_t dimPtIDData[2]{ n ,1 };
H5::DataSpace ptIDDataSpace(2, dimPtIDData);
//点数据
hsize_t dim3[] = { 3 };
H5::DataSpace mspace3(1, dim3);
//点ID数据
hsize_t dim1[] = { 1 };
H5::DataSpace mspace1(1, dim1);
//表格
hsize_t coordPtData[3][2];
coordPtData[0][1] = 0;
coordPtData[1][1] = 1;
coordPtData[2][1] = 2;
for (int i = 0; i < n; ++i)
{
coordPtData[0][0] = i;
coordPtData[1][0] = i;
coordPtData[2][0] = i;
//点
std::array< double, 3 > point;
ptDataSpace.selectElements(H5S_SELECT_SET, 3, (const hsize_t*)coordPtData);
pointsSet.read(&point, H5::PredType::NATIVE_DOUBLE, mspace3, ptDataSpace);
//点ID
int pID;
ptIDDataSpace.selectElements(H5S_SELECT_SET, 1, (const hsize_t*)coordPtData);
PointIDSet.read(&pID, H5::PredType::NATIVE_INT, mspace1, ptIDDataSpace);
mesh->addNode(pID, point[0], point[1], point[2]);
}
return true;
}
bool FITKInterfaceHDF5AdaptorMesh::readElement(Interface::FITKUnstructuredMesh* mesh, H5::Group& h5Group)
{
if (mesh == nullptr) return false;
//创建Grid->Cells子节点 用于存储单元数据
if (!h5Group.nameExists("Cells")) return false;
H5::Group eleGroup = h5Group.openGroup("Cells");
//循环类型
int EleTypeCount = eleGroup.getNumAttrs();
for (int i = 0; i < EleTypeCount; ++i)
{
auto eleType = eleGroup.openAttribute(i);
//name
std::string elementTypeName;
H5::StrType datatype(H5::PredType::C_S1, H5T_VARIABLE);
eleType.read(datatype, elementTypeName);
int n, m;
if (!getDataSetDim(eleGroup, elementTypeName, n, m)) return false;
hsize_t dimEleData[2]{ n ,m };
H5::DataSpace eleDataSpace(2, dimEleData);
H5::DataSet eleDataSet = eleGroup.openDataSet(elementTypeName);
int i_Ele = -1;
//枚举转换字符 确定解析的单元类型
Core::FITKEnumTransfer<Interface::FITKModelEnum::FITKEleType> fitkEleTypeTrafer;
bool isValid = false;
auto elementType = fitkEleTypeTrafer.fromString(QString::fromStdString(elementTypeName), isValid);
auto element = Interface::FITKElementFactory::createElement(elementType);
if (!element) return false;
// 对同类单元进行每行循环读取数据
for (int j = 0; j < n; ++j)
{
// hyperslab的开始
hsize_t start[2] = { ++i_Ele, 0 };
// hyperslab的步长
hsize_t stride[2] = { 1, m };
hsize_t count[2] = { 1, 1 };
// Block sizes
hsize_t block[2] = { 1, m };
eleDataSpace.selectHyperslab(H5S_SELECT_SET, count, start, stride, block);
hsize_t dim[] = { m * 2 };
H5::DataSpace mspace2(1, dim);
hsize_t start2[1] = { 0 };
hsize_t stride2[1] = { 1 };
hsize_t count2[1] = { m };
hsize_t block2[1] = { 1 };
mspace2.selectHyperslab(H5S_SELECT_SET, count2, start2, stride2, block2);
int* ptIDArray = new int[m];
eleDataSet.read(ptIDArray, H5::PredType::NATIVE_INT, mspace2, eleDataSpace);
QList<int> nodes;
for (int k = 1; k < m; k++)
{
nodes.append(ptIDArray[k]);
}
//添加点与单元
element->setEleID(ptIDArray[0]);
element->setNodeID(nodes);
mesh->appendElement(element);
delete[] ptIDArray;
}
}
return true;
}
bool FITKInterfaceHDF5AdaptorMesh::writeNode(Interface::FITKUnstructuredMesh* mesh, H5::Group& h5Group)
{
if (mesh == nullptr) return false;
// 写出节点函数主体
int nodeCount = mesh->getNodeCount();
//点
// 行数 // 列数
hsize_t dimPtData[2]{ nodeCount ,3 };
H5::DataSpace ptDataSpace(2, dimPtData);
H5::DataSet ptData = h5Group.createDataSet("Points", H5::PredType::NATIVE_DOUBLE, ptDataSpace);
//点ID
// 行数 // 列数
hsize_t dimPtIDData[2]{ nodeCount ,1 };
H5::DataSpace ptIDDataSpace(2, dimPtIDData);
H5::DataSet ptIDData = h5Group.createDataSet("PointIDs", H5::PredType::NATIVE_ULLONG, ptIDDataSpace);
// 写入点数据
hsize_t dim1[] = { 1 };
H5::DataSpace mspace1(1, dim1);
//写入点ID数据
hsize_t dim3[] = { 3 };
H5::DataSpace mspace3(1, dim3);
//表格
hsize_t coordPtData[3][2];
coordPtData[0][1] = 0;
coordPtData[1][1] = 1;
coordPtData[2][1] = 2;
for (int i = 0; i < dimPtData[0]; ++i)
{
coordPtData[0][0] = i;
coordPtData[1][0] = i;
coordPtData[2][0] = i;
//点
auto node = mesh->getNodeAt(i);
const std::array< double, 3 > pt0{ node->x() ,node->y() ,node->z() };
ptDataSpace.selectElements(H5S_SELECT_SET, 3, (const hsize_t*)coordPtData);
ptData.write(&pt0, H5::PredType::NATIVE_DOUBLE, mspace3, ptDataSpace);
//点ID
int pID = node->getNodeID();
ptIDDataSpace.selectElements(H5S_SELECT_SET, 1, (const hsize_t*)coordPtData);
ptIDData.write(&pID, H5::PredType::NATIVE_INT, mspace1, ptIDDataSpace);
}
return true;
}
bool FITKInterfaceHDF5AdaptorMesh::writeElement(Interface::FITKUnstructuredMesh* mesh, H5::Group& h5Group)
{
if (mesh == nullptr) return false;
//创建Grid->Cells子节点 用于存储单元数据
H5::Group eleGroup = h5Group.createGroup("Cells");
//key 单元类型名称 value单元编号
QMultiHash<QString, int> elementType = extractElementInformation(mesh);
QList<QString> typeNames = elementType.keys().toSet().toList();
for (QString typeName : typeNames)
{
auto elIDList = elementType.values(typeName);
auto ele = mesh->getElementByID(elIDList[0]);
const int eleNodeCount = ele->getNodeCount();
int i_Ele = -1;
//行长度+1 将CellID 放在0的位置
int lineSize = eleNodeCount + 1;
hsize_t dimEleData[2]{ elIDList.size() ,lineSize };
H5::DataSpace eleDataSpace(2, dimEleData);
H5::DataSet eleDataSet = eleGroup.createDataSet(typeName.toStdString(), H5::PredType::NATIVE_INT, eleDataSpace);
writeStrAttribute(eleDataSet, "EleType", typeName.toStdString());
// 对同类单元进行循环
for (int j = 0; j < elIDList.size(); ++j)
{
// hyperslab的开始
hsize_t start[2] = { ++i_Ele, 0 };
// hyperslab的步长
hsize_t stride[2] = { 1, lineSize };
hsize_t count[2] = { 1, 1 };
// Block sizes
hsize_t block[2] = { 1, lineSize };
eleDataSpace.selectHyperslab(H5S_SELECT_SET, count, start, stride, block);
hsize_t dim[] = { lineSize * 2 };
H5::DataSpace mspace2(1, dim);
hsize_t start2[1] = { 0 };
hsize_t stride2[1] = { 1 };
hsize_t count2[1] = { lineSize };
hsize_t block2[1] = { 1 };
mspace2.selectHyperslab(H5S_SELECT_SET, count2, start2, stride2, block2);
int* ptIDArray = new int[lineSize];
for (int k = 0; k < eleNodeCount; ++k)
ptIDArray[k + 1] = mesh->getElementByID(elIDList[j])->getNodeID(k);
ptIDArray[0] = elIDList[j];
eleDataSet.write(ptIDArray, H5::PredType::NATIVE_INT, mspace2, eleDataSpace);
delete[] ptIDArray;
}
//存储集合名称的链表 用index作为属性名称添加
int numAttrCount = eleGroup.getNumAttrs();
writeStrAttribute(eleGroup, std::to_string(numAttrCount), typeName.toStdString());
}
return true;
}
//提取单元信息
QMultiHash<QString, int> FITKInterfaceHDF5AdaptorMesh::extractElementInformation(Interface::FITKUnstructuredMesh* mesh)
{
//key 单元类型名称 value单元编号
QMultiHash<QString, int> elementType;
if (mesh == nullptr) return elementType;
//枚举转换字符 确定解析的单元类型
Core::FITKEnumTransfer<Interface::FITKModelEnum::FITKEleType> fitkEleTypeTrafer;
bool isValid = false;
//提取信息
for (int i = 0; i < mesh->getElementCount(); ++i)
{
auto ele = mesh->getElementAt(i);
auto eleType = ele->getEleType();
//枚举转换字符
QString eleTypeStr = fitkEleTypeTrafer.toStrting(eleType, isValid);
elementType.insert(eleTypeStr, ele->getEleID());
}
return elementType;
}
}