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資料可微信掃描下方二維碼關注微信公眾號。