许可优化
产品
解决方案
服务支持
关于
软件库
当前位置:服务支持 >  软件文章 >  Fluent-Matlab协同仿真:数据交互,无缝对接

Fluent-Matlab协同仿真:数据交互,无缝对接

阅读数 4
点赞 0
article_banner

在进行计算过程中fluent将数据传递给Matlab 处理,处理结束后matlab再将数据回传给fluent继续迭代,以此循环。此处fluent瞬态迭代,在每一个时间步迭代完成后使用UDF 进行数据交换,Matlab采用.m文件的方式接收、处理和发送数据,通讯方式采用的是UDP。

  1. fluent端
#include "udf.h"
#include <stdio.h>
#include <winsock2.h>
#include <winsock.h>
#pragma comment(lib,"ws2_32.lib")
int i = 0;
double data = 12.5;//传输数据 可以是多个数据 采用数组的方式
double fluentUDP(double temp1)   //每次传输调用一次
{
//1.初始化,使用socket()函数获取一个socket文件描述符
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    SOCKET sockfd = socket(AF_INET, SOCK_DGRAM, 0);
//2.绑定本地的相关信息,如果不绑定,则系统会随机分配一个端口号
    struct sockaddr_in local_addr = {0};
    local_addr.sin_family = AF_INET;//使用IPv4地址
    local_addr.sin_addr.s_addr = inet_addr("xx.xxx.xxx.xxx");//本机IP地址
    local_addr.sin_port = htons(8590);//端口
    bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr));//将套接字和IP、端口绑定
//3.发送数据到指定的ip和端口,'xx.xxx.xxx.xxx'表示目的ip地址,2589表示目的端口号 
    struct sockaddr_in sock_addr = {0};
    sock_addr.sin_family = AF_INET;                         // 设置地址族为IPv4
    sock_addr.sin_port = htons(4901);			// 设置地址的端口号信息
    sock_addr.sin_addr.s_addr = inet_addr("xx.xxx.xxx.xxx");// 设置IP地址
//4.等待接收对方发送的数据 阻塞型
    double recvbuf,sendbuf;
    sendbuf = temp1;
    struct sockaddr_in recv_addr;
    int nSize=sizeof(recv_addr);
    sendto(sockfd, (char *)&sendbuf, sizeof(sendbuf), 0, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
    Message("sendbuf=%f\n",sendbuf);
    recvfrom(sockfd, (char *)&recvbuf, sizeof(recvbuf), 0,(struct sockaddr*)&recv_addr,&nSize);
    Message("recvbuf=%f\n",recvbuf);
    closesocket(sockfd);
    WSACleanup();//停止Winsock
    return recvbuf;
}

DEFINE_EXECUTE_AT_END(data_processing)
{
    #if RP_HOST
        i = i + 1;
        data = data + 12.5;
	double recvbuf;
	Message("Times=%d\n",i);
	recvbuf = fluentUDP(data);//fluent先将data发送给Matlab 然后阻塞等待接受处理好后的数据,可以是一个数或者数组
    #endif
}

2. Matlab端

由于udp通讯提供的库函数只能传输char数据类型,而数据交换为double数据类型,因此需要做数据类型转换。double为8字节的双精度数据,char为单字节字符,可将double拆分为8个单字节的uint8数据类型,不会超过char的数据范围,依次传输,对方接收后再将8个uint8组合转换为double,以此进行数据传输。

C语言采用指针操作即可进行数据类型转换。而MATLAB采用sim命令调用simulink的Byte Packing 模块将double转换为8个uint8(udp_pack.slx文件);调用Byte Unpacking 将8个uint8准换为double数据(udp_unpack.slx文件)。(可能比较麻烦)

%使用前需要先确定接收到数据的个数,修改 number_of_double
%按照数组的形式传输多个数据
%先关闭之前可能存在的UDP
clc;clear
delete(instrfindall);
%地址信息绑定
ip = 'xx.xxx.xxx.xxx';
local_port = 4901;
remote_port = 8590;
number_of_double = 1;%接收到数据的个数 这个是在simulink模块里面使用
%配置udp,打开连接
count = 0;
u = udp(ip,'RemotePort',remote_port,'LocalPort',local_port);
fopen(u);
while(1)
    %循环查询是否接收到数据
    bytes = u.BytesAvailable;
    if bytes > 0
        %接受数据部分
        count = count + 1
        receive = fread(u);
        matlab_receive_uint8 = uint8(receive)';
        simout_unpack = sim('udp_unpack');%调用simulink模块,将uint8组合为double数据类型
        matlab_receive_double = simout_unpack.matlab_receive_double.Data
        %处理数据部分
        disp('成功接收数据,开始处理')
        matlab_send_double = matlab_receive_double + 12.5;%可另外写一个function函数进行数据处理然后发送到fluent
        disp('成功处理数据,发送数据中...');
        %发送数据部分
        simout_pack = sim('udp_pack');%调用simulink模块,将double拆分为uint8数据类型
        matlab_send_uint8 = simout_pack.matlab_send_uint8.Data;
    	fwrite(u,matlab_send_uint8);
        disp('数据已发送完成');
    	disp('***********************');
    end
end
fclose(u);
delete(u);
clear u;
图1 udp_pack.slx
图2 udp_unpack.slx


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删
相关文章
QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空