乐于分享
好东西不私藏

Ansys Fluent文档-UDF篇:通用DEFINE宏(三)

Ansys Fluent文档-UDF篇:通用DEFINE宏(三)

11DEFINE_RW_FILE

①描述

DEFINE_RW_FILE是一种通用宏,可用于指定要写入历史案例或数据文件(即.cas .dat文件)的自定义信息,或从传统案例或数据文件中读取信息。可以使用DEFINE_RW_FILE保存和恢复任意数据类型(例如整数型、实数型、CXBoolean、结构体)的自定义变量。在计算求解过程中保存动态信息(例如条件采样中的发生次数)通常非常有用,这也是该函数的另一个应用场景。请注意,使用此功能时,读取顺序与写入顺序必须保持一致。

②用法

DEFINE_RW_FILE (name, fp)

nameUDF名称;

FILE *fp:指向正在读取或写入的历史版文件的指针。

DEFINE_RW_FILE有两个参数:namefp。需要提供UDF的名称name,而fp则由求解器传递给UDF

③示例

以下源代码清单包含了将信息写入历史数据文件并读回的函数示例。这些函数被串联到一个单独的源文件中,可在Fluent中解释或编译。执行流程:首次运行kount0开始,每次迭代显示: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);继续计算kount35开始继续递增显示: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}

12DEFINE_RW_HDF_FILE

①描述

DEFINE_RW_HDF_FILE是一个通用宏,可用于从采用通用流体格式(CFF)编写的案例或数据文件(即.cas.h5.dat.h5文件)中读取或向其写入自定义信息。可读取和写入实数值的自定义数据集以及各种类型的属性。

②用法

DEFINE_RW_HDF_FILE (name,filename)

nameUDF名称;

char *filename:读取或写入的CFF文件名。

DEFINE_RW_HDF_FILE有两个参数:namefilename。需要提供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 ;

filenameCFF文件的名称。

path:将写入属性的文件中的链接路径。

name:属性的名称。

mpttype:属性值的数据类型。可以是MPT_SHORTMPT_INTMPT_LONGMPT_LONG_LONGMPT_SIZE_TMPT_DOUBLE 中的一种。

value:属性的值。根据mpttype的值,属性类型应为shortintlonglong longsize_tdouble

:可以通过包含额外的namempttypevalue三元组来指定多个属性。

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 ;

filenameCFF文件的名称。

path:将读取属性的文件中链接的路径。

name:要读取的属性的名称。

mpttype:属性值的数据类型。可以是MPT_SHORTMPT_INTMPT_LONGMPT_LONG_LONGMPT_SIZE_TMPT_DOUBLE中的一种。

ptr:指向存储属性值的位置的指针。根据mpttype的值,指针类型应为shortintlonglong longsize_tdouble

:通过包含namempttypeptr的额外三元组,可以读取多个属性。

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 ;

filenameCFF文件的名称。

path:文件下链接所在组的路径。

prev_name:路径下组内链接的名称。prev_name之后的下一个链接名称(根据文档创建顺序)将在next_name中返回。可以使用NULL值来获取组内的第一个链接。

next_nameprev_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,初始化为50    real* ptr = NULL;               // 声明实数指针,初始化为NULL    char* 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: 检查指针是否不为NULL    if (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宏(一)(更新)

特别感谢您的阅读、点赞、转发、推荐!

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » Ansys Fluent文档-UDF篇:通用DEFINE宏(三)

评论 抢沙发

8 + 1 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
×
订阅图标按钮