Fluent UDF利用的是C语言,本文简单介绍在UDF中经常会用到的C语言常识。

本文部分内容来自UDF手册。

1 C语言中的注释

C语言中的注释利用/*及*/来实现。例如:

/*这是一个注释*/

注释也可以跨行实现,如:

/*这是一个
跨行注释*/

注意:在编写UDF的过程中,不能把DEFINE宏(如DEFINE_PROFILE)放置在注释中,否则会引起编译错误

2 基本数据类型

Fluent UDF解释器支持的标准C数据类型包括:

  • int。整形,存储形如1,2,3之类的整数。
  • long。长整形。存储数据与int类似,但范围更广。
  • float。浮点型。存储小数,如1.234等
  • double。双精度浮点型。与float类似。
  • char。字符型,如'a','b','c'等。

    Fluent UDF中还有real型,其实这是Fluent自定义的数据类型,在双精度求解器中,real类型与double类型相同,而在单精度求解器中,real类型等同于float类型。UDF自动进行转换,因此在需要浮点数时,可以全部采用real类型。

3 常数

在C语言中可以利用#define来定义常数。需要注意的是,定义为常数类型后,该变量的值不能改变。如:

#define WALL_ID 5
#define YMIN 0.0
#define YMAX 0.4

这样定义完毕后,WALL_ID的值不能再发生改变,因此如下的语句会引发编译错误:

WALL_ID = WALL_ID +1 ;

4 变量

变量用于存储数据。所有变量都包含类型、名称以及值,有时候还包含存储标记(如静态变量和外部变量)。C语言中所有的变量在使用之前都必须声明,这样C编译器才会知道该如何为此变量分配内存。

4.1 全局变量和局部变量

C语言中的全局变量定义在函数的外部,该变量可以被源文件中所有的函数引用。全局变量如果未被声明为静态变量的话,还可以被外部函数引用。如下例中的全局变量声明:

#include "udf.h"
real volume; /*此处定义的是全局变量*/
DEFINE_ADJUST(vol,domain)
{
/*此处可以访问变量volume*/
}

局部变量一般定义在函数体内,其只在函数体内起作用,在函数体外无法被访问到。如下程序中的局部变量定义。

DEFINE_PROPERTY(cell_viscosity, cell, thread)
{
real mu_lam; /*局部变量 */
real temp = C_T(cell, thread); /* 局部变量 */
if (temp > 288.)
mu_lam = 5.5e-3;
else if (temp > 286.)
mu_lam = 143.2135 - 0.49725 * temp;
else
mu_lam = 1.;
return mu_lam;
}

4.2 外部变量

当在某个源文件中定义了一个未加static的全局变量后,若想在另一个源文件中调用此变量,此时可以使用外部变量声明来实现。采用如下声明:

extern real volume;

注意:extern声明只能用于编译型UDF中。

以下是一个利用extern的案例。

假设在源文件file1.c中定义了全局变量:

#include "udf.h"
real volume;
DEFINE_ADJUST(compute_volume, domain)
{
volume = ....
}

若其他的的源文件想要利用此全局变量volume, 此时可以创建头文件,并将变量volume声明为extern变量,如创建头文件extfile.h,写入内容:

extern real volume;

之后就可以在其他的源文件中使用此变量volume了,如在源文件file2.c中:

#include "udf.h"
#include "extfile.h"
DEFINE_SOURCE(heat_source,c,t,ds,eqn)
{
real total_source = ...;
real source;
source = total_source/volume;
return source;
}

温馨提示:外部变量使用起来很麻烦也很容易出错,如果对其不甚了解的话,建议不要使用。

4.3 静态变量

静态变量(声明时添加static关键字)在用于局部变量或全局变量时具有不同的作用。局部变量被声明为static时,当函数返回后变量并不销毁,变量的值依旧被保留。

全局变量被声明为static时,该变量能够被此源文件中的所有函数调用,但不能被其他源文件中的函数调用。实际上是变量被隐藏了。

例如在文件mysource.c中有如下代码:

#include "udf.h"
static real abs_coeff = 1.0; /*静态全局变量*/
/* 此变量只能被本文件中的其他函数调用 */ DEFINE_SOURCE(energy_source, c, t, dS, eqn)
{
real source; /* 局部变量*/
int P1 = ....; /* 局部变量*/
/*变量只能被当前函数调用,但在函数返回时变量并不释放 */
dS[eqn] = -16.* abs_coeff;
source =-abs_coeff *(4.* SIGMA_SBC );
return source;
} DEFINE_SOURCE(p1_source, c, t, dS, eqn)
{
real source;
int P1 = ...;
dS[eqn] = -abs_coeff;
source = abs_coeff *(4.* SIGMA_SBC);
return source;
}

更多关于static的描述可参见文章[www.cnblogs.com/stoneJin/archive/2011/09/21/2183313.html] (www.cnblogs.com/stoneJin/archive/2011/09/21/2183313.html)

温馨提示:与全局变量类似,静态变量也尽量少用,容易造成不必要的麻烦。

5 用户自定义数据类型

C语言允许用户自己定义数据类型,通过使用结构体及typedef关键字。如定义类型:

typedef struct list
{
int a;
real b;
int c;
}mylist;
mylist x,y,z;

上例定义了一个结构体类型mylist,并定义了三个结构体变量x,y,z。

6 强制转换

在C语言中,有时需要对类型进行强制转换,如将浮点型强制转换为整形,如下例中。

int x =1;
real y=3.1415926;
int z=x+(int)y;

计算完毕后,z=4。

7 函数

C语言中的函数执行独立的任务。函数能够被同一源文件中的其他函数调用,也可以由源文件之外的函数调用。

函数定义包含函数名以及被传递给函数的零个或多个参数列表。函数包含一个包含在大括号内的主体,主体中包含执行任务的指令。 函数可以返回特定类型的值。

函数返回特定数据类型的值(例如,实数),如果类型为void,则不返回任何值。 要确定DEFINE宏的返回数据类型,可查看udf.h文件中宏的相应#define语句。

8 数组

C语言中数组变量定义为name[size],其中name为数组变量的名称,size为数组中存储的单元数量。C语言中数组索引从0开始。

int a[10], b[10][10];
/*a
real rad[5];
a[0] = 1;
rad[4] = 3.14159265;
b[10][10] = 4;

9 指针

指针是一种存储变量内存地址的变量。换句话说,指针是一个变量,这个变量指向另外一个变量的内存地址。指针变量的声明:

int *ip;/*定义指针变量ip*/

定义了指针变量后,可以利用取址运算符将其他变量的地址赋予指针变量,如:

int *ip;
ip =&a;

也可以为指针变量赋值,如:

*ip =4;

当指针作为函数的参数,此时为传址调用,在函数体内修改指针参数的值,会改变调用函数时传递的参数的值。此功能可以实现一个函数返回多个值。

如下的C程序:

#include <stdio.h>
int add(int *a,int b)
{
int sum = 0;
sum = *a + b;
*a = 5;
return sum;
} int main() { int *ip;
int a = 1;
int b = 2;
int sum = 0;
ip = &a;
sum = add(ip,b);
printf("sum=%d,a=%d\n",sum,a);
return 0;
}

输出结果:

sum=3,a=5

传递的参数值被函数体内的程序改变。

10 流程控制

C语言中可以用逻辑判断和循环来进行流程控制。

10.1 if语句

if语句用于逻辑判断。可写成:

if(逻辑判断表达式)
{
语句块;
}

例如:

if(q!=1)
{
a=0;
b=1;
}

若逻辑判断存在多个分支,可以采用if-else结构。如:

if(x<0)
{
y = x/50;
}
else(x>=0 && x<3)
{
x=-x;
y = x/25;
}
else
{
x= 0;
y = 0;
}

10.2 for循环

for语句常用于循环表达。

int i,j,n<=10;
for(i=1;i<n;i++)
{
j = i*i;
printf("%d%d\n",i,j)
}

11 操作符

常用的代数操作符:

= 赋值操作
+ 加法计算
- 减法计算
* 乘法运算
/ 除法运算
% 求模运算
++ 累加
-- 累减

常用的逻辑操作符:

 <  小于
<= 小于等于
> 大于
>= 大于等于
== 等于
!= 不等于

12 C库函数

常用的三角函数:

double acos (double x);
double asin (double x);
double atan (double x);
double atan2 (double x, double y);
double cos (double x);
double sin (double x);
double tan (double x);
double cosh (double x);
double sinh (double x);
double tanh (double x);

常用的数学函数:

double sqrt (double x);
double pow(double x, double y);
double exp (double x);
double log (double x);
double log10 (double x);
double fabs (double x);
double ceil (double x);
double floor (double x);

一些常用的标准输入输出函数:

FILE *fopen(char *filename, char *mode);
int fclose(FILE *fp);
int printf(char *format,...);
int fscanf(FILE *fp, char *format,...);
int fscanf(FILE *fp, char *format,...);

更多的内容可参阅C语言教程。


更多CFD资料可微信扫描下方二维码关注微信公众号。

Fluent UDF【4】:C语言的更多相关文章

  1. Fluent UDF【2】:学习途径

    要怎样做才能做到无畏惧编写任何UDF程序?估计很多与UDF打交道的人都会问到这个问题. 面对UDF文档中那众多的宏描述,小伙伴们是不是感觉到茫然无措,不知从何入手.有时候读别人写好的程序感觉并不难,然 ...

  2. Fluent UDF【1】:简介

    前面基本完成了动网格专题的发布,不过还是有一些内容并没有更新进去,比如说in-cylinder.接触检测.2.5D网格重构等.不过这些都是小技巧,写起来挺麻烦,以后有时间再通过案例视频的方式讲解好了. ...

  3. Fluent UDF【8】:编译型UDF

    UDF除了可以以解释的方式外,其还可以以编译的方式被Fluent加载.解释型UDF只能使用部分C语言功能,而编译型UDF则可以全面使用C语言的所有功能. 1 编译型UDF介绍 编译型UDF的构建方式与 ...

  4. Fluent UDF【6】:预处理命令

    今天要讲的内容是关于C语言的预处理.搞清楚了这个,就可以分析UDF中的各种头文件源代码,从此写UDF不求人. 1 关于预处理 在UDF的各种头文件中(文件路径D:\Program Files\ANSY ...

  5. Fluent UDF【7】:解释型UDF

    UDF宏有两种方式可以被Fluent所接受:编译和解释.其中有一些宏既可以被解释也可以被编译,而一些宏则只能被解释.有一些场合只接受编译后的UDF(如动网格中的一些宏),而有些场合既可以接受编译的UD ...

  6. Fluent UDF【5】:第一个UDF

    这里以一个简单的初始化案例来描述UDF的使用过程. 0 Fluent中的Patch Fluent中提供了全域初始化以及局部Patch功能.对于整体区域的全局初始化可以采用starndard及hybri ...

  7. Fluent UDF【3】:环境配置

    windows操作系统下UDF的编译需要借助Visual Studio中的C编译器.因此若要想编译UDF,则必须事先配置好编译环境. Visual Studio Visual Stuido(后面简称V ...

  8. Serial Fluent UDF on Windows

    test test Table of Contents 1. Serial UDF on Windows OS 1 Serial UDF on Windows OS Note: Udf has to ...

  9. Fluent——UDF监测指定点的物理量

    Fluent版本:19.0 Fluent当中提供了监测某一点物理量随迭代次数或者随时间变化的功能,下面我们就介绍如何在UDF当中实现相同的功能,并且UDF更加灵活,通过UDF的方式我们在知道某点运动规 ...

随机推荐

  1. Effective前端(3)用CSS画一个三角形

    来源:https://zhuanlan.zhihu.com/p/26160325 三角形的场景很常见,打开一个页面可以看到各种各样的三角形: 由于div一般是四边形,要画个三角形并不是那么直观.你可以 ...

  2. StatefulSet和Deployment的区别

    “Deployment用于部署无状态服务,StatefulSet用来部署有状态服务”. 具体的,什么场景需要使用StatefulSet呢?官方给出的建议是,如果你部署的应用满足以下一个或多个部署需求, ...

  3. ipsec协议(转)

    from:http://lulu1101.blog.51cto.com/4455468/816875 ipsec协议 2012-03-25 23:40:28 标签:休闲 ipsec协议 职场 IPSe ...

  4. kafka负载均衡相关资料收集(二)

    [转]关于kafka producer 分区策略的思考 from:http://blog.csdn.net/ouyang111222/article/details/51086037 今天跑了一个简单 ...

  5. 转载:kafka c接口librdkafka介绍之二:生产者接口

    转载:from:http://www.verydemo.com/demo_c92_i210679.html 这个程序虽然我调试过,也分析过,但是没有记录笔记,发现下边这篇文章分析直接透彻,拿来借用,聊 ...

  6. 【虚拟化系列】VMware vSphere 5.1 网络管理

       网络是VMware vSphere 5.1的基础,所有虚拟机都需要网络来进行通信.如果将所有的虚拟机都看成是物理机,则在网络拓扑上,需要网卡和交换机等不同的网络连接设备和方式.而在虚拟化中,这些 ...

  7. sudo: add-apt-repository: command not found

    错误来啦:sudo: add-apt-repository:command not found      网上解决办法是直接安装工具包 命令:sudo apt-get install python-s ...

  8. 为什么说,长跑和爬山能锻炼意志?因为要不停的run,run,run......

    长跑和爬山教会我们的是无论做什么都要坚持,教会我们的是生活的态度. 如果不能体会到这一点,那你长跑的意义就是纯粹的锻炼身体. 中国教育的最大败笔就是教会了人学习,却没教会人思考.

  9. css浮动中避免包含元素高度为0的4种解决方法

    问题:当子元素中使用了float时,如果其父元素不指定高度,其高度将为0 解决:清除(闭合)浮动元素,使其父div高度自适应 方法一:额外标签+clear:both     (W3C推荐方法,兼容性较 ...

  10. Python字符串与二进制串的相互转换

    python基础知识之字符编码与转换 - 机壳啦 - 博客园https://www.cnblogs.com/home979/p/7838244.html Python 字符串与二进制串的相互转换 - ...