吾生有涯 学海无涯
析模有界 知识无界

STAR CCM+二次开发|07 User Code编程

内容纲要

本文为STAR CCM+二次开发系列的最后一篇文章。

User Code 是用户自己用编译语言(例如 C,C++或 Fortran)编写的函数,用来和 Simcenter STAR-CCM+动态链接,实现标准界面无法完成的一些需求(比如自定义边界,自定义初始化等)。

下面我们通过将入口边界设置为层流充分发展边界这样一个简单的例子来介绍User Code的基本使用方法。

注: 

1. 本文内容收集自网络,有少量内容因软件版本不同而进行了修改

2. 原文地址:https://www.cnblogs.com/liusuanyatong/p/122882458.html

3. 原文作者:硫酸亚铜

1 问题描述

管道模型如下:

截面直径0.2 m。

物性参数:

  • 密度:1 kg/m³
  • 粘度:0.002 N·s/㎡

管道层流入口充分发展满足下面的关系:

其中:Um表示入口的平均速度,r0表示管径

2 编写User Code

User Code的编写步骤如下:

2.1 头文件

新建一个头文件,命名为uclib.h,内容如下:

#ifndef UCLIB_H
#define UCLIB_H
#ifdef DOUBLE_PRECISION
typedef double Real;
#else
typedef float Real;
#endif
typedef double CoordReal;

#ifdef __cplusplus
extern "C" {
#endif
#if defined(WIN32) || defined(_WINDOWS) || defined(_WINNT)
# define USERFUNCTION_EXPORT __declspec(dllexport)
# define USERFUNCTION_IMPORT __declspec(dllimport)
#else
# define USERFUNCTION_EXPORT
# define USERFUNCTION_IMPORT
#endif

extern void USERFUNCTION_IMPORT ucarg(void *, char *, char *, int);
extern void USERFUNCTION_IMPORT ucfunc(void *, char *, char *);
extern void USERFUNCTION_IMPORT ucfunction(void *, char *, char *, int, ...);

void USERFUNCTION_EXPORT uclib();
#ifdef __cplusplus
}
#endif
#endif

注:上面头文件的名称和格式都是固定的,照着写就行了,不要改动。

参阅STAR CCM+文档:主页 → 用户界面 → 使用用户程序 → 用户函数接口引用 → 类型定义。

2.2 源代码

编写 User Code 的源码,新建一个.c 或者.cpp 文件都可以,这里新建一个 demo.cpp 文件。

内容如下:

#include 
#include "uclib.h"

const Real R = 0.1;

void USERFUNCTION_EXPORT ParabolicVelocity(Real *result, int size, CoordReal (*centroid)[3])
{
CoordReal origin[3]{};
Real r;
for (int i = 0; i != size; ++i)
{
r = sqrt((centroid[i][0] - origin[0]) * (centroid[i][0] - origin[0]) +
(centroid[i][1] - origin[1]) * (centroid[i][1] - origin[1]) +
(centroid[i][2] - origin[2]) * (centroid[i][2] - origin[2]));
result[i] = 2 * (1 - (r / R) * (r / R));
}
}

void USERFUNCTION_EXPORT uclib()
{
/*Register user functions here*/
ucfunc(ParabolicVelocity, "BoundaryProfile", "Parabolic velocity");
ucarg(ParabolicVelocity, "Face", "centroid", sizeof(CoordReal[3]));
}

2.3 源代码说明

上面的源码主要分为三个部分。

1、头文件

#include 
#include "uclib.h"

这部分是头文件,注意uclib.h这个头文件必须要包含,其他的都是c语言或者c++的头文件了。

2、主体函数

主体函数可写为:

void ParabolicVelocity(Real *result, int size, CoordReal (*centroid)[3])
{
CoordReal origin[3]{};
Real r;
for (int i = 0; i != size; ++i)
{
r = sqrt((centroid[i][0] - origin[0]) * (centroid[i][0] - origin[0]) +
(centroid[i][1] - origin[1]) * (centroid[i][1] - origin[1]) +
(centroid[i][2] - origin[2]) * (centroid[i][2] - origin[2]));
result[i] = 2 * (1 - (r / R) * (r / R));
}
}

主体函数的格式是固定的,其格式为:

#include "uclib.h"
void name(result, int size, args ...)
{
//用户自定义函数内容
}

其中:

  • name表示函数名,名称可以随便,只要符合c或者c++的命名规则即可。
  • 返回值。对于返回值是标量(比如温度、压力和合速度)的时候,result写为Real *result,这里可以将result理解为一个数组。对于返回值是矢量(比如速度的三个分量)的时候,result就写为real (*result)[3],这里可以将result理解为一个二维数组,(*result)[0]、(*result)[1]、(*result)[2]分别是一个一维数组,存储不同的量,比如速度三个分量就分别放在三个一维数组当中。
  • 第二个参数size是前面result的维数,对应的单元(面单元,体单元)的数量,比如以本例来说,入口面有4263个面单元,那么这里的size就等于4263,那么这里的Real *result就相当于Real result[4263]
  • args...表示不定参数,表示后面跟的参数可能不止一个,类似printf,下图将固定格式和对应例子结合说明一下。

本例中args表示一个参数,当然后面还可以有更多的参数,比如:

就跟着两个参数。args声明参数的方法和对应方式参考下表

这么声明的方法,基本上和上面的result参数理解类似,比如本例我们需要获取入口面单元的坐标信息,因为前面有size参数,在本例中这个size参数等于4263,那么这里的CoordReal (*centroid)[3]就相当于CoordReal centroid[4263][3]

4263表示单元数目,后面的3表示x,y,z的索引,那么centroid[0][0]就表示第一个单元的x坐标,centroid[0][1]就表示第一个单元的y坐标,centroid[0][2]就表示第一个单元的z坐标,所以centroid[xxx][0]就表示第xxx个单元的x坐标,centroid[xxx][1]就表示第xxx个单元的y坐标,centroid[xxx][2]就表示第xxx个单元的z坐标,其他类似的理解。

当然用户自定义函数可以不止一个,有多少个就写多少即可:

void  userFunction_1(result,int size,args...)
{

}

void userFunction_2(result,int size,args...)
{

}

void userFunction_3(result,int size,args...)
{

}


void userFunction_n(result,int size,args...)
{

}


4、注册函数

如前面示例部分的代码:

void  uclib()
{
/*Register user functions here*/
ucfunc(ParabolicVelocity, "BoundaryProfile", "Parabolic velocity");
ucarg(ParabolicVelocity, "Face", "centroid", sizeof(CoordReal[3]));
}

为注册函数。

注册函数的格式是固定的:

#include "uclib.h"
void uclib()
{

}

每个用户自定义函数都需要注册,每个用户自定义函数传入的不定参数也需要注册。

注册用户的自定义函数的函数格式为:

ucfunc(void *func, char *type, char *name);

其中:

  • func 是用户自定义函数的函数名,比如本例中我们的函数名为 ParabolicVelocity
  • type 必须是"BoundaryProfile"、"RegionProfile"、"ScalarFieldFunction"、"VectorFieldFunction"这四种当中的一种,比如本例中我们是设置边界条件,故选择 BoundaryProfile。
  • name则表示为在STAR-CCM+中模型树的Tools->User Code->libuser.dll显示名称和调用时选取的名称,比如本例中我们设置的是边界条件,那么在模型树和边界条件设置的名称就应该是这里的name,见下图

注意:有多少个用户自定义函数就需要写多少个这样的变量注册用户自定义函数的函数

注册用户自定义函数传入的不定参数的函数格式为

ucarg(void *func, char *type, char *variable, int size);

其中:

  • func 参数含义与上面 ucfunc 函数中 func 参数的含义是一致的
  • type参数必须是"Cell"、"Face"、"Vertex"这三种当中的一种,Cell表示获取体单元的属性,Face表示获取面单元的属性,Vertex表示获取点的属性。比如本例中我们是设置边界条件,故选择Face
  • variable参数必须是STAR-CCM+中可用的变量,比如温度(Temperature)、中心(Centroid)等等
  • 最后一个参数size的写法是固定的,但是注意一下这里的size和前面用户自定义函数传入的那个size参数是不一样的,这里的size需要传入变量数组的一个元素所需的字节数,采用sizeof来计算,比如本例中sizeof(CoordReal[3]),其他的类似sizeof(Real)、sizeof(int[2])等等,注意一下用户自定义函数当中的不定参数传入了多少个参数就需要写多少个这样的变量注册函数,比如本例不定参数只传入了1个参数,所以我们就需要注册1个。

总结一下上面注册函数的内容,由于本例当中我们只编写了1个用户自定义函数,不定参数只传入了1个参数,所以写为下面的形式

void  uclib()
{
/*Register user functions here*/
ucfunc(ParabolicVelocity, "BoundaryProfile", "Parabolic velocity");
ucarg(ParabolicVelocity, "Face", "centroid", sizeof(CoordReal[3]));
}

如果多个用户自定函数和不定参数传入多个参数的情况就参照Simcenter STAR-CCM+ User Guide当中的写法

3 编译User Code

接下来就是编译User Code

  • 首先到STAR CCM+的安装路径下搜索文件UserFunctions.lib,如本机路径为:C:Program FilesSiemens18.02.008-R8STAR-CCM+18.02.008-R8starlibwin64clang11.1vc14.2-r8libUserFunctions.lib。把路径记下来,后面要用
  • 从开始菜单的VS安装路径中找到x64 Native Tools Command Prompt for VS 2022,点击鼠标右键,选择以管理员身份运行启动命令行对话框
  • 利用cd命令cd /d "C:UsersAdministratorDesktopMAPDLUserCode"进入到User Code源代码所在的目录(如本案例存储在C:UsersAdministratorDesktopMAPDLUserCode文件夹中),如下图所示
  • 输入命令cl /MD /EHsc /DDOUBLE_PRECISION /D_WINDOWS -c *.cpp

注:若STAR CCM+不是双精度版本,则不需要添加/DDOUBLE_PRECISION

  • 输入命令link -dll /out:libuser.dll *.obj "C:Program FilesSiemens18.02.008-R8STAR-CCM+18.02.008-R8starlibwin64clang11.1vc14.2-r8libUserFunctions.lib"

编译成功后在当前路径下会生成一个名为libuser.dll的文件。

上面命令汇总一下:

cl /MD /EHsc /DDOUBLE_PRECISION /D_WINDOWS -c *.cpp 

link -dll /out:libuser.dll *.obj "C:Program FilesSiemens18.02.008-R8STAR-CCM+18.02.008-R8starlibwin64clang11.1vc14.2-r8libUserFunctions.lib"

4 使用User Code

  • 启动STAR-CCM+,新建一个项目,展开模型树的Tools,找到User Code,然后加载User Code。
  • 在边界中使用User Code
  • 计算完成后速度分布云图

  • 入口速度分布

从上面的结果可以看出User Code的设置满足我们的需求。

模型、网格、User Code源码、STAR-CCM+结果文件链接:

https://pan.baidu.com/s/1Y__MU4sQoVIUg_fo3KIsKA

提取码: fqrd


(完)

本篇文章来源于微信公众号: CFD之道

赞(1) 打赏
版权声明:未经允许,请勿随意用于商业用途。
文章名称:《STAR CCM+二次开发|07 User Code编程》
文章链接:https://www.topcfd.cn/35255/
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。
分享到

说两句 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者吧

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫

微信扫一扫

登录

找回密码

注册