当前位置: 首页 > news >正文

读取OpenFOAM二进制polyMesh格式的C/C++程序

文章目录

  • 读取OpenFOAM二进制polymesh格式的C/C++程序
    • 1. 理解OpenFOAM二进制格式
    • 2. 基本读取步骤
      • 2.1 读取FoamFile头部
      • 2.2 读取二进制数据
      • 2.3 读取faces文件(面数据)
      • 2.4 读取owner/neighbour文件
      • 2.5 读取cellZones数据
    • 3. 注意事项
    • 4. 完整示例
    • 5. 替代方案
  • OpenFOAM网格数据文本格式和二进制格式比较
    • 1. **文件体积对比**
    • 2. **读写性能**
    • 3. **典型文件对比**
    • 4. **何时使用哪种格式**
    • 5. **转换方法**
    • 总结

读取OpenFOAM二进制polymesh格式的C/C++程序

OpenFOAM使用自定义的二进制格式存储网格数据(polymesh),主要包括points、faces、owner、neighbour等文件。以下是编写C/C++程序读取这些二进制文件的方法:

1. 理解OpenFOAM二进制格式

OpenFOAM的二进制polymesh文件具有以下特点:

  • 文件开头有FoamFile头部信息(ASCII格式)
  • 实际数据部分采用二进制格式
  • 数据通常以列表形式存储,前面有列表长度
  • 数值通常采用IEEE浮点格式或整型格式

2. 基本读取步骤

2.1 读取FoamFile头部

首先需要跳过ASCII头部,直到找到第一个左花括号{之后的数据。

void skipHeader(FILE* fp) {char line[256];while (fgets(line, sizeof(line), fp)) {if (strstr(line, "FoamFile")) {// 跳过FoamFile块while (fgets(line, sizeof(line), fp) && !strstr(line, "}"));}if (strchr(line, '{')) {break;  // 找到数据开始位置}}
}

2.2 读取二进制数据

对于points文件(存储顶点坐标):

struct Point { float x, y, z; };std::vector<Point> readPoints(const char* filename) {FILE* fp = fopen(filename, "rb");if (!fp) throw std::runtime_error("Cannot open file");skipHeader(fp);// 读取点数int32_t nPoints;fread(&nPoints, sizeof(int32_t), 1, fp);std::vector<Point> points(nPoints);fread(points.data(), sizeof(Point), nPoints, fp);fclose(fp);return points;
}

2.3 读取faces文件(面数据)

struct Face {std::vector<int32_t> vertices; // 面的顶点索引
};std::vector<Face> readFaces(const char* filename) {FILE* fp = fopen(filename, "rb");if (!fp) throw std::runtime_error("Cannot open file");skipHeader(fp);// 读取面数int32_t nFaces;fread(&nFaces, sizeof(int32_t), 1, fp);std::vector<Face> faces(nFaces);for (auto& face : faces) {int32_t nVertices;fread(&nVertices, sizeof(int32_t), 1, fp);face.vertices.resize(nVertices);fread(face.vertices.data(), sizeof(int32_t), nVertices, fp);}fclose(fp);return faces;
}

2.4 读取owner/neighbour文件

std::vector<int32_t> readCellList(const char* filename) {FILE* fp = fopen(filename, "rb");if (!fp) throw std::runtime_error("Cannot open file");skipHeader(fp);// 读取单元数int32_t nCells;fread(&nCells, sizeof(int32_t), 1, fp);std::vector<int32_t> cells(nCells);fread(cells.data(), sizeof(int32_t), nCells, fp);fclose(fp);return cells;
}

2.5 读取cellZones数据

cellZones文件存储了网格中特定区域的单元分组信息。以下是读取方法:

#include <string>
#include <vector>
#include <map>struct ZoneInfo {std::string name;std::vector<int> cells;
};std::vector<ZoneInfo> readCellZones(const std::string& filename) {std::ifstream file(filename, std::ios::binary);if (!file) {throw std::runtime_error("Cannot open cellZones file");}// 跳过FoamFile头部int32_t numZones;file.read(reinterpret_cast<char*>(&numZones), sizeof(numZones));std::vector<ZoneInfo> zones(numZones);for (auto& zone : zones) {// 读取区域名称长度和名称int32_t nameLength;file.read(reinterpret_cast<char*>(&nameLength), sizeof(nameLength));zone.name.resize(nameLength);file.read(&zone.name[0], nameLength);// 读取单元数量int32_t numCells;file.read(reinterpret_cast<char*>(&numCells), sizeof(numCells));zone.cells.resize(numCells);file.read(reinterpret_cast<char*>(zone.cells.data()), numCells * sizeof(int32_t));}return zones;
}

3. 注意事项

  1. 字节序:OpenFOAM二进制文件通常使用处理器原生字节序,但如果你在不同架构的机器上读取,可能需要处理字节序转换。

  2. 精度:OpenFOAM可以使用单精度(float)或双精度(double)存储数据,通常由writePrecision设置决定。

  3. 边界条件:边界条件信息存储在boundary文件中,需要额外解析。

  4. 并行计算:对于并行计算案例,网格被分割为多个处理器目录(processorN),每个都有自己的polyMesh。

  5. 调试:可以使用foamFormatConvert工具将二进制格式转换为ASCII格式进行调试。

4. 完整示例

#include <iostream>
#include <vector>
#include <fstream>
#include <stdexcept>struct Point { float x, y, z; };
struct Face { std::vector<int32_t> vertices; };void skipHeader(std::ifstream& is) {std::string line;while (std::getline(is, line)) {if (line.find("FoamFile") != std::string::npos) {while (std::getline(is, line) && line.find('}') == std::string::npos);}if (line.find('{') != std::string::npos) break;}
}std::vector<Point> readPoints(const std::string& filename) {std::ifstream is(filename, std::ios::binary);if (!is) throw std::runtime_error("Cannot open file: " + filename);skipHeader(is);int32_t nPoints;is.read(reinterpret_cast<char*>(&nPoints), sizeof(int32_t));std::vector<Point> points(nPoints);is.read(reinterpret_cast<char*>(points.data()), nPoints * sizeof(Point));return points;
}int main() {try {auto points = readPoints("constant/polyMesh/points");std::cout << "Read " << points.size() << " points" << std::endl;return 0;} catch (const std::exception& e) {std::cerr << "Error: " << e.what() << std::endl;return 1;}
}

5. 替代方案

如果不想手动解析二进制格式,可以考虑:

  1. 使用OpenFOAM自带的库函数(需要链接OpenFOAM库)
  2. 先将二进制格式转换为ASCII格式再读取
  3. 使用第三方库如CGNS或VTK的OpenFOAM读取器

以上代码提供了读取OpenFOAM二进制polymesh的基本框架,实际应用中可能需要根据具体情况进行调整。


OpenFOAM网格数据文本格式和二进制格式比较

在OpenFOAM中,网格数据可以以文本(ASCII)或二进制(binary)格式存储,两种格式在文件大小和读写性能上有显著差异,尤其对于大网格数据。以下是关键对比:

1. 文件体积对比

  • 二进制格式
    数据以紧凑的二进制形式存储,通常比文本格式小 3-5倍。例如,一个文本格式的 points 文件为100 MB,二进制版本可能仅20-30 MB。
  • 文本格式
    数据以人类可读的ASCII形式存储,数值(如浮点数)以字符串形式保存,占用更多空间。

2. 读写性能

  • 二进制格式
    • 读取更快:无需解析文本,直接加载二进制数据。
    • 写入更快:减少磁盘I/O操作。
    • 对大网格(如百万级网格),二进制格式的加载时间可缩短数倍。
  • 文本格式
    • 可手动查看/编辑,但读写速度慢,尤其在大数据量时。

3. 典型文件对比

  • points(节点坐标):二进制体积约为文本的 1/4-1/5
  • faces(面连接性):二进制体积约为文本的 1/3-1/4(因整数存储更高效)。
  • owner/neighbour:二进制体积约为文本的 1/3

4. 何时使用哪种格式

  • 二进制:默认选择,尤其适用于大规模仿真(如CFD、DEM)。
  • 文本:仅需调试或手动修改网格时使用(如 polyMesh/convertToASCII 转换)。

5. 转换方法

  • 文本→二进制
    foamFormatConvert -constant -format binary
    
  • 二进制→文本
    foamFormatConvert -constant -format ascii
    

总结

对于大网格数据,二进制格式的文件体积通常为文本格式的1/3到1/5,且读写效率更高。建议仅在调试时使用文本格式。

http://www.xdnf.cn/news/1028071.html

相关文章:

  • 手搓中文字符编程语言
  • 一文掌握 Windows 文件传输:5 种命令行工具的原理、参数与示例
  • 中国人工智能证书综合信息表(2025年版)
  • 基于混合预编码的同时进行无线信息和功率传输的毫米波海量MIMO-NOMA
  • 如何确保邮件群发不会被标记为垃圾邮件?
  • 【测试开发】函数高阶-闭包、装饰器
  • P25:LSTM实现糖尿病探索与预测
  • Spring AOP与代理模式
  • 利用 Python 爬虫按关键字搜索 1688 商品
  • mvnd-快速打包maven项目
  • 如何使用自动化测试来提高接口测试的效率
  • 1Panel 618 年中大促|不止半价!
  • 《二叉堆》题集
  • Ubuntu VMware虚拟机卡在/dev/sda1
  • ubuntu调整硬盘大小-使用gparted
  • 板子接入mipi摄像头
  • HTML+CSS 动态菜单和登录框
  • 共建数据强国:政务数据共享的双轮革命
  • 【力扣 简单 C】160. 相交链表
  • C++笔记-C++11(三)
  • 【Spring AI】MCP Server实现多实例部署
  • 【灵动Mini-F5265-OB】ADC之片内温度传感器与参考电压获取
  • springboot+vue大文件断点续传
  • 04 dnsmasq 的环境搭建
  • 【MIPI屏幕调试记录】个人记录用
  • Python+requests+pytest接口自动化测试框架的搭建
  • 专项提升-分析dump堆文件 服务器内存占用排查
  • 在死胡同里 做加法是什么意思?
  • 坚持做一件事情和好奇做一件事,本质区别和思考
  • 开发者视角:一键拉起功能解析