Ansys Fluent文档-UDF篇:通用DEFINE宏(三)
①描述
DEFINE_RW_FILE是一种通用宏,可用于指定要写入历史案例或数据文件(即.cas 或.dat文件)的自定义信息,或从传统案例或数据文件中读取信息。可以使用DEFINE_RW_FILE保存和恢复任意数据类型(例如整数型、实数型、CXBoolean、结构体)的自定义变量。在计算求解过程中保存动态信息(例如条件采样中的发生次数)通常非常有用,这也是该函数的另一个应用场景。请注意,使用此功能时,读取顺序与写入顺序必须保持一致。
②用法
DEFINE_RW_FILE (name, fp)
name:UDF名称;
FILE *fp:指向正在读取或写入的历史版文件的指针。
DEFINE_RW_FILE有两个参数:name和fp。需要提供UDF的名称name,而fp则由求解器传递给UDF。
③示例
以下源代码清单包含了将信息写入历史数据文件并读回的函数示例。这些函数被串联到一个单独的源文件中,可在Fluent中解释或编译。执行流程:首次运行kount从0开始,每次迭代显示:kount = 1, kount = 2, kount = 3, …;保存数据执行File → Write → Case & Data,显示:Writing UDF data to legacy data file,当前kount值(如35)被写入数据文件;重新打开并读取数据显示:Reading UDF data from legacy data file,从文件读取保存的kount值(35);继续计算kount从35开始继续递增显示:kount = 36, kount = 37, …
#include"udf.h"// 定义全局整型变量kount,用于统计迭代次数// 使用int类型,并在函数外部定义,使其成为全局变量// 初始化为0int kount = 0; /* define global variable kount */// 定义ADJUST函数,在每个迭代步执行// demo_calc: 函数名// d: 域指针DEFINE_ADJUST(demo_calc, d){kount++; // 每次迭代增加计数器的值(自增1)// 输出当前迭代计数到控制台printf("kount = %d\n", kount);}// 定义写文件函数,当Fluent保存数据文件(.dat)时自动执行// writer: 函数名// fp: 文件指针,指向Fluent的数据文件DEFINE_RW_FILE(writer, fp){// 输出提示信息,表示正在写入UDF数据printf("Writing UDF data to legacy data file...\n");// 条件编译:确保只在主机节点(非计算节点)执行写入操作// RP_NODE: Fluent宏,在计算节点上为真,在主机节点上为假// !RP_NODE: 表示在主机节点上执行#if!RP_NODE// 将kount的值以整数格式写入数据文件// fprintf: 标准C文件写入函数// fp: 文件指针,由Fluent提供// "%d": 整数格式// kount: 要写入的迭代计数器值fprintf(fp, "%d", kount); /* write out kount to legacy data file */#endif}// 定义读文件函数,当Fluent读取数据文件(.dat)时自动执行// reader: 函数名// fp: 文件指针,指向Fluent的数据文件DEFINE_RW_FILE(reader, fp){// 输出提示信息,表示正在从数据文件读取UDF数据printf("Reading UDF data from legacy data file...\n");// 条件编译:确保只在主机节点(非计算节点)执行读取操作#if!RP_NODE// 从数据文件中读取一个整数值到kount变量// fscanf: 标准C文件读取函数// fp: 文件指针,由Fluent提供// "%d": 整数格式// &kount: kount变量的地址,用于存储读取的值fscanf(fp, "%d", &kount); /* read kount from legacy data file */#endif}
(12)DEFINE_RW_HDF_FILE
①描述
DEFINE_RW_HDF_FILE是一个通用宏,可用于从采用通用流体格式(CFF)编写的案例或数据文件(即.cas.h5或.dat.h5文件)中读取或向其写入自定义信息。可读取和写入实数值的自定义数据集以及各种类型的属性。
②用法
DEFINE_RW_HDF_FILE (name,filename)
name:UDF名称;
char *filename:读取或写入的CFF文件名。
DEFINE_RW_HDF_FILE有两个参数:name和filename。需要提供UDF的名称name,而filename则由求解器传递给UDF。由于通用流体格式的结构化特性,系统提供了一系列辅助函数来执行底层读写操作。
③辅助函数
CFF文件采用压缩二进制格式。为了便于读写这些文件,提供了一系列辅助函数在UDF中使用。以下术语在辅助函数的描述中使用:
Datasets:可以被视为存储数据的数组。通常,数据以实数值的形式存储。
Groups:类似于文件系统中的目录。一个组可以包含其他组、数据集或两者的组合。
Attributes:是分配给数据集或组的名称/值,通常用于存储元数据。例如,数据集可能具有一个表示其元素数量的属性。
Link:是一个总称,可能指代群组或数据集,但不指代属性。
Path:是CFF文件中链接的字符串表示形式。文件的根组路径用/表示。通过指定链接的绝对路径(例如,/path/to/link),可以识别文件中的任何链接。
通过在UDF源文件中包含hdfio.h头文件,以下函数将可用,这些函数用于执行CFF读写操作。请注意,所有函数都会在提供的路径参数前自动添加/user前缀。因此,这些函数写入或访问的所有用户自定义数据都存储在/user组下。
Write_Complete_User_Dataset
#include"hdfio.h"Write_Complete_User_Dataset (filename, path, ptr, nelems);char* filename ;char* path ;real* ptr ;size_t nelems ;
filename:要写入数据的CFF文件名称。在DEFINE_RW_HDF_FILE宏中,该参数通常由Fluent传入。
path:文件中的路径,数据集将在此处写入。
ptr:指向将被写入的数据的指针。请注意,数据类型必须为实数。
nelems:从节点写入的数据元素数量。
这是将数据写入CFF文件的基础函数。该函数假定数据仅存在于节点中,且已按节点秩顺序排列。因此,首先写入node0中的数据,随后是node1中的数据,依此类推。将在指定路径创建新数据集,其大小为所有节点nelems的总和。
Write_Partial_User_Dataset
#include"hdfio.h"Write_Partial_User_Dataset (filename, path, ptr, nelems, datasetsize, datasetoffset);char* filename ;char* path ;real* ptr ;size_t nelems ;size_t datasetsize ;size_t datasetoffset ;
filename:要写入数据的CFF文件名称。在DEFINE_RW_HDF_FILE宏中,该参数通常由Fluent传入。
path:文件中的路径,数据集将在此处写入。
ptr:指向将被写入的数据的指针。请注意,数据类型必须为实数。
nelems:从节点写入的数据元素数量。
datasetsize:数据集的总大小,数据将被写入其中。此大小必须大于所有节点上nelems的总和。
datasetoffset:数据集内开始写入的偏移量。
此功能适用于需要通过多次调用向同一数据集写入数据的情况。首次调用时将创建数据集,随后各计算节点的调用会将数据写入该数据集。
Write_User_Attributes
#include"hdfio.h"Write_User_Attributes (filename, path, name, mpttype, value, ..., NULL );char* filename ;char* path ;char* name ;MPT_Datatype mpttype ;type value ;... ;NULL ;
filename:CFF文件的名称。
path:将写入属性的文件中的链接路径。
name:属性的名称。
mpttype:属性值的数据类型。可以是MPT_SHORT、MPT_INT、MPT_LONG、MPT_LONG_LONG、MPT_SIZE_T、MPT_DOUBLE 中的一种。
value:属性的值。根据mpttype的值,属性类型应为short、int、long、long long、size_t或double。
…:可以通过包含额外的name、mpttype和value三元组来指定多个属性。
NULL:参数列表必须以NULL结尾。
Read_Complete_User_Dataset
#include"hdfio.h"Read_Complete_User_Dataset (filename, path, ptr, nelems);char* filename ;char* path ;real* ptr ;size_t nelems ;
filename:从中读取数据的CFF文件名称。在DEFINE_RW_HDF_FILE宏中,该参数通常由Fluent传入。
path:从文件中读取数据集所在的路径。
ptr:指向存储读取数据的位置的指针。请注意,数据类型被假定为实数。
nelems:要读取到节点中的数据元素数量。
这是从CFF文件读取数据的基本功能。与Write_Complete_User_Data函数类似,数据根据节点等级按顺序读取。因此,先读取的数据会先填充node0,接着是node1,依次类推。
Read_Partial_User_Dataset
#include"hdfio.h"Read_Partial_User_Dataset (filename, path, ptr, nelems, datasetoffset);char* filename ;char* path ;real* ptr ;size_t nelems ;size_t datasetoffset ;
filename:从中读取数据的CFF文件名称。在DEFINE_RW_HDF_FILE宏中,该参数通常由Fluent传入。
path:从文件中读取数据集所在的路径。
ptr:指向存储读取数据的位置的指针。请注意,数据类型被假定为实数。
nelems:要读取到节点中的数据元素数量。
datasetoffset:数据集中读取起始的偏移量。
此功能可用于从CFF文件中读取数据集的一部分。
Read_User_Attributes
#include"hdfio.h"Read_User_Attributes (filename, path, name, mpttype, ptr, ..., NULL);char* filename ;char* path ;char* name ;MPT_Datatype mpttype ;type* ptr ;... ;NULL ;
filename:CFF文件的名称。
path:将读取属性的文件中链接的路径。
name:要读取的属性的名称。
mpttype:属性值的数据类型。可以是MPT_SHORT、MPT_INT、MPT_LONG、MPT_LONG_LONG、MPT_SIZE_T或MPT_DOUBLE中的一种。
ptr:指向存储属性值的位置的指针。根据mpttype的值,指针类型应为short、int、long、long long、size_t或double。
…:通过包含name、mpttype和ptr的额外三元组,可以读取多个属性。
NULL:参数列表必须以NULL结尾。
Get_Next_User_Link_Name
#include"hdfio.h"Get_Next_User_Link_Name (filename, path, prev_name, next_name);char* filename ;char* path ;char* prev_name ;char* next_name ;
filename:CFF文件的名称。
path:文件下链接所在组的路径。
prev_name:路径下组内链接的名称。prev_name之后的下一个链接名称(根据文档创建顺序)将在next_name中返回。可以使用NULL值来获取组内的第一个链接。
next_name:prev_name之后链接的名称将在next_name中返回。如果prev_name是组中的最后一个链接,则将返回空字符串。
④示例
#include"udf.h"#include"hdfio.h"// 包含HDF5输入输出头文件,提供HDF5读写函数// 定义宏,指定每个节点要处理的元素数量为50#define ELEM_COUNT 50// 定义写HDF5文件函数,当Fluent保存HDF5格式文件时自动执行// write_complete_dataset: 函数名// filename: 文件名,由Fluent传入DEFINE_RW_HDF_FILE(write_complete_dataset, filename){size_t i, nelems = ELEM_COUNT; // 声明循环变量i和元素数量nelems,初始化为50real* ptr = NULL; // 声明实数指针,初始化为NULLchar* path = "/test/complete_data"; // 定义HDF5文件中的数据路径/* Assign equal number of elements in all the nodes* and fill with some values. Write a dataset with* all the values at the end. Also write an attribute* with total number of elements.*/// 在计算节点上分配内存并填充数据// RP_NODE: 在计算节点上为真(并行计算)#if RP_NODE// 为每个节点分配内存,大小为nelems个real类型ptr = (real*)CX_Malloc(sizeof(real) * nelems);// 填充数据:每个节点的数据值 = (节点ID + 1) * 索引值for (i = 0; i < nelems; ++i) {ptr[i] = (real)((myid + 1) * i); // myid是节点ID(从0开始)}#endif// 写入完整的数据集到HDF5文件// Write_Complete_User_Dataset: 将所有节点数据收集并写入HDF5文件// filename: HDF5文件名// path: 数据集在HDF5文件中的路径// ptr: 数据指针(在主机节点上可能为NULL)// nelems: 每个节点贡献的数据量Write_Complete_User_Dataset(filename, path, ptr, nelems);// 写入属性到HDF5数据集// Write_User_Attributes: 为数据集写入元数据属性// filename: HDF5文件名// path: 数据集路径// "totalElems": 属性名,表示总元素数量// MPT_SIZE_T: 属性数据类型(size_t类型)// (size_t)(nelems * compute_node_count): 属性值,总元素数 = 每个节点元素数 × 节点总数// compute_node_count: 是 Fluent 内部自动维护的全局变量,它会自动获取并返回当前并行计算环境中的计算节点总数。// NULL: 参数列表终止符Write_User_Attributes(filename, path,"totalElems", MPT_SIZE_T, (size_t)(nelems * compute_node_count),NULL);// 释放分配的内存// NNULLP: 检查指针是否不为NULLif (NNULLP(ptr)) {CX_Free(ptr); // 释放内存}}DEFINE_RW_HDF_FILE(read_complete_dataset, filename){size_t nelems = 0, totalElems = 0; // 声明元素数量变量real* ptr = NULL; // 声明实数指针char* path = "/test/complete_data"; // 定义HDF5文件中的数据路径/* Read complete dataset and check the elements. */// 从HDF5文件中读取属性信息// Read_User_Attributes: 读取数据集的属性// filename: HDF5文件名// path: 数据集路径// "totalElems": 要读取的属性名// MPT_SIZE_T: 属性数据类型// &totalElems: 存储属性值的变量地址// NULL: 参数列表终止符Read_User_Attributes(filename, path,"totalElems", MPT_SIZE_T, &totalElems,NULL);// 在计算节点上分配内存#if RP_NODE// 计算每个节点应该读取的元素数量:总元素数 ÷ 节点总数nelems = totalElems / compute_node_count;// 分配内存ptr = (real*)CX_Malloc(sizeof(real) * nelems);#endif// 从HDF5文件中读取完整数据集// Read_Complete_User_Dataset: 读取数据集并将其分发到各个节点// filename: HDF5文件名// path: 数据集路径// ptr: 存储数据的指针// nelems: 每个节点应该读取的数据量Read_Complete_User_Dataset(filename, path, ptr, nelems);// 释放分配的内存if (NNULLP(ptr)) {CX_Free(ptr);}}
参考资料:《Ansys Fluent UDF Manual》 2023R1
CFD理论基础合集(持续更新中):
Ansys Fluent帮助文档-UDF篇:用户自定义函数概述(UDFs)(一)
Ansys Fluent帮助文档-UDF篇:用户自定义函数概述(UDFs)(二)
Ansys Fluent帮助文档-UDF篇:通用DEFINE宏(一)(更新)
特别感谢您的阅读、点赞、转发、推荐!
夜雨聆风
