zoukankan      html  css  js  c++  java
  • Fluent UDF【4】:C语言

    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
    ",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
    ",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资料可微信扫描下方二维码关注微信公众号。

    微信扫码关注公众号

  • 相关阅读:
    (Java实现) 洛谷 P1106 删数问题
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
    (Java实现) 洛谷 P1553 数字反转(升级版)
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1106 删数问题
    目测ZIP的压缩率
  • 原文地址:https://www.cnblogs.com/LSCAX/p/7004275.html
Copyright © 2011-2022 走看看