CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > ANSYS > FLUENT > Fluent UDF and Scheme Programming

UDF parallelization issue

Register Blogs Members List Search Today's Posts Mark Forums Read

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   November 18, 2024, 23:52
Default UDF parallelization issue
  #1
New Member
 
ttg
Join Date: Jul 2022
Posts: 2
Rep Power: 0
Tony G is on a distinguished road
Dear all
My code runs well in serial mode, while after parallelization, the solver freeze after clicking on calculation.
Here are the codes:
#include "udf.h"
#include <stdio.h>
#include <winsock2.h>
#include <winsock.h>
#pragma comment(lib,"ws2_32.lib")

// Fluent sends this array
double send_data[4] = {500.0, 500.0, 500.0, 500.0};
double recvbuf[4] = {0.0}; // Make recvbuf global

double fluentUDP1(double senddata[]) // Send array
{

Message("fluentUDP called with send_data = [%f, %f, %f, %f]\n",
senddata[0], senddata[1], senddata[2], senddata[3]);

// Initialize Winsock
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
{
Message("WSAStartup failed.\n");
return -1;
}
Message("WSAStartup successful.\n");

// Create socket
SOCKET sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == INVALID_SOCKET)
{
Message("Socket creation failed. Error code: %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
Message("Socket created successfully.\n");

// Bind to a local port (ensure it's not in use)
struct sockaddr_in local_addr;
memset(&local_addr, 0, sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
local_addr.sin_port = htons(8111); //

if (bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)) == SOCKET_ERROR)
{
Message("Bind failed with error code: %d\n", WSAGetLastError());//数值正常时可忽略报错,调试使用
closesocket(sockfd);
WSACleanup();
return -1;
}
Message("Bind successful on 127.0.0.1:%d.\n", ntohs(local_addr.sin_port));

// Set up the remote address (MATLAB's listening port)
struct sockaddr_in sock_addr;
memset(&sock_addr, 0, sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons(4911); // MATLAB's LocalPort
sock_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

// Set receive timeout
int timeout = 60000; // milliseconds
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout)) == SOCKET_ERROR)
{
Message("Failed to set socket receive timeout. Error code: %d\n", WSAGetLastError());
closesocket(sockfd);
WSACleanup();
return -1;
}
Message("Receive timeout set to %d ms.\n", timeout);

// Send data to MATLAB

int dataSize = sizeof(double) * 4; // Size of data to send/receive

if (sendto(sockfd, (char *)senddata, dataSize, 0,
(struct sockaddr*)&sock_addr, sizeof(sock_addr)) == SOCKET_ERROR)
{
Message("sendto failed. Error code: %d\n", WSAGetLastError());
closesocket(sockfd);
WSACleanup();
return -1;
}
Message("senddata sent to MATLAB.\n");

// Receive data from MATLAB
if (recvfrom(sockfd, (char *)recvbuf, dataSize, 0, NULL, NULL) == SOCKET_ERROR)
{
Message("recvfrom failed. Error code: %d\n", WSAGetLastError());
closesocket(sockfd);
WSACleanup();
return -1;
}
Message("recvbuf = [%f, %f, %f, %f] received from MATLAB.\n",
recvbuf[0], recvbuf[1], recvbuf[2], recvbuf[3]);

// Clean up
closesocket(sockfd);
WSACleanup();
Message("fluentUDP completed successfully.\n");

}

DEFINE_EXECUTE_AT_END(get_array_from_fluent)
{
const char *report_names[4] = {"h1", "h2", "h3", "h4"};
int nrOfvalues;
real *values;
int *ids;
int index;
int rv;
#if RP_HOST
for (int i = 0; i < 4; i++)
{

const char *report_name = report_names[i];
/* First call to get number of values */
rv = Get_Report_Definition_Values(report_name, 1, &nrOfvalues, NULL, NULL, NULL);
if (rv == 0 && nrOfvalues > 0)
{
/* Allocate memory */
values = (real*) malloc(sizeof(real) * nrOfvalues);
ids = (int*) malloc(sizeof(int) * nrOfvalues);
if (values == NULL || ids == NULL)
{
Message("Memory allocation failed.\n");
if (values) free(values);
if (ids) free(ids);
return;
}
/* Second call to get values */
rv = Get_Report_Definition_Values(report_name, 1, NULL, values, ids, &index);
if (rv != 0)
{
Message("Error retrieving report '%s'. rv = %d\n", report_name, rv);
free(values);
free(ids);
return;
}
send_data[i] = values[0]; // Assuming we want the first value
Message("send_data[%d] = %f from report '%s'.\n", i, send_data[i], report_name);
free(values);
free(ids);
}
else
{
// Handle error
Message("Failed to retrieve report '%s'. rv = %d\n", report_name, rv);
}
}

fluentUDP1(send_data); // Call the function to send and receive data
#endif

host_to_node_real(recvbuf,4);//received a fatal signal (SEGMENTATION VIOLATION) if removed

}
/
DEFINE_PROFILE(set_heat_flux1, thread, position)
{
host_to_node_real_1(recvbuf[0]);
#if RP_NODE

face_t f;


begin_f_loop(f, thread)
{
F_PROFILE(f, thread, position) = recvbuf[0];
}
end_f_loop(f, thread)
#endif


}

DEFINE_PROFILE(set_heat_flux2, thread, position)
{
host_to_node_real_1(recvbuf[1]);
#if RP_NODE

face_t f;



begin_f_loop(f, thread)
{
F_PROFILE(f, thread, position) = recvbuf[1];
}
end_f_loop(f, thread)
#endif


}

DEFINE_PROFILE(set_heat_flux3, thread, position)
{
host_to_node_real_1(recvbuf[2]);
#if RP_NODE

face_t f;


begin_f_loop(f, thread)
{
F_PROFILE(f, thread, position) = recvbuf[2];
}
end_f_loop(f, thread)
#endif


}

DEFINE_PROFILE(set_heat_flux4, thread, position)
{
host_to_node_real_1(recvbuf[3]);
#if RP_NODE

face_t f;


begin_f_loop(f, thread)
{
F_PROFILE(f, thread, position) = recvbuf[3];
}
end_f_loop(f, thread)
#endif


}
If host_to_node_real(recvbuf,4) is removed, the ncortex received a fatal signal (SEGMENTATION VIOLATION).
Any suggestion would be helpful
Tony G is offline   Reply With Quote

Old   November 15, 2025, 02:23
Default
  #2
New Member
 
ttg
Join Date: Jul 2022
Posts: 2
Rep Power: 0
Tony G is on a distinguished road
solved. ignore the chinese notes.

#include "udf.h" // Fluent UDF必须的头文件
#include "para.h" // 并行计算UDF必须的头文件
#include <stdio.h> // 标准输入输出库
/*中间可用版本*/
/* ================================================== ================= */
/* 1. 编译时隔离:只为主控进程(Host)包含和链接Windows Sockets库 */
#if RP_HOST
#include <winsock2.h>
#include <winsock.h>
#pragma comment(lib, "ws2_32.lib") // 告诉链接器需要ws2_32.lib库
#endif
/* ================================================== ================= */


// 全局变量,所有进程都需要它们来存储数据
double send_data[2] = {300.0, 300.0};
double recvbuf[1] = {300.0};


#include "udf.h"
#include "para.h"
#include <stdio.h>
#include "storage.h" /* <-- 为使用 C_STORAGE_R(..SV_T) 宏而必须包含的头文件 */

/* ================================================== ================= */
/* 1. UDP通信函数*/
#if RP_HOST
void Host_UDP_Communication(double senddata[])
{
Message("\nHost: UDP Communication -> Preparing to send data.\n");

WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
Message("Error: WSAStartup failed in UDF.\n");
return;
}

SOCKET sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == INVALID_SOCKET) {
Message("Error: Socket creation failed. Code: %d\n", WSAGetLastError());
WSACleanup();
return;
}

struct sockaddr_in local_addr;
memset(&local_addr, 0, sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
local_addr.sin_port = htons(8111);

if (bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)) == SOCKET_ERROR) {
Message("Warning: Bind failed with error code: %d.\n", WSAGetLastError());
closesocket(sockfd);
WSACleanup();
return;
}

struct sockaddr_in sock_addr;
memset(&sock_addr, 0, sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons(4911);
sock_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

int timeout = 60000;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));

int dataSize_send = sizeof(double) * 2;
int dataSize_recv = sizeof(double) * 1;

// 发送数据
if (sendto(sockfd, (char *)senddata, dataSize_send, 0, (struct sockaddr*)&sock_addr, sizeof(sock_addr)) == SOCKET_ERROR) {
Message("Error: sendto failed. Code: %d\n", WSAGetLastError());
closesocket(sockfd);
WSACleanup();
return;
}

/* --- DEBUG 功能:在发送成功后,立刻打印将要发送的值 --- */
Message("Host: Data sent to MATLAB: tout_avg = %f, tmax_solid = %f\n", senddata[0], senddata[1]);
/* --- End of DEBUG --- */

// 接收数据
if (recvfrom(sockfd, (char *)recvbuf, dataSize_recv, 0, NULL, NULL) == SOCKET_ERROR) {
Message("Error: recvfrom failed. Code: %d. (Is MATLAB running and sending data back?)\n", WSAGetLastError());
closesocket(sockfd);
WSACleanup();
return;
}
Message("Host: Data received from MATLAB. New inlet T = %f\n", recvbuf[0]);

// 清理资源
closesocket(sockfd);
WSACleanup();
}
#endif
/* ================================================== ======================= */
/* 2. 主执行宏:采用最底层的消息传递宏,彻底解决类型不兼容问题 */
DEFINE_EXECUTE_AT_END(get_array_and_communicate)
{
static double recvbuf_static[1] = {300.0};
int TAG_UDF_DATA = 101; // 定义一个唯一的消息标签

#if !RP_HOST /* === 阶段1:所有计算任务只在计算节点上执行 === */

int outlet_face_zone_id = 24;
int solid_cell_zone_id = 103;

Domain *domain = Get_Domain(1);
Thread *outlet_thread = Lookup_Thread(domain, outlet_face_zone_id);
Thread *solid_thread = Lookup_Thread(domain, solid_cell_zone_id);

real local_tout_sum = 0.0;
int local_tout_count = 0;
real local_tmax_val = -1.0e20;
face_t f;
cell_t c;

if (outlet_thread != NULL) { begin_f_loop(f, outlet_thread) { local_tout_sum += F_T(f, outlet_thread); local_tout_count++; } end_f_loop(f, outlet_thread) }
if (solid_thread != NULL) { begin_c_loop(c, solid_thread) { real temp_solid = C_STORAGE_R(c, solid_thread, SV_T); if (temp_solid > local_tmax_val) { local_tmax_val = temp_solid; } } end_c_loop(c, solid_thread) }

real global_tout_sum = PRF_GRSUM1(local_tout_sum);
int global_tout_count = PRF_GISUM1(local_tout_count);
real global_tmax_val = PRF_GRHIGH1(local_tmax_val);

if (I_AM_NODE_ZERO_P)
{
double node0_send_data[2] = {300.0, 300.0};
if (global_tout_count > 0) { node0_send_data[0] = global_tout_sum / global_tout_count; }
if (global_tmax_val > -1.0e19) { node0_send_data[1] = global_tmax_val; }

Message0("Node 0: Sending to host: tout_avg=%f, tmax_solid=%f\n", node0_send_data[0], node0_send_data[1]);

/* --- 最终关键修正 1:使用底层消息发送宏 --- */
PRF_CSEND_DOUBLE(node_host, node0_send_data, 2, TAG_UDF_DATA);
}
#endif

#if RP_HOST
double host_received_data[2];
/* --- 最终关键修正 2:使用底层消息接收宏 --- */
PRF_CRECV_DOUBLE(node_zero, host_received_data, 2, TAG_UDF_DATA);

Message("Host: Received from Node 0: tout_avg=%f, tmax_solid=%f\n", host_received_data[0], host_received_data[1]);
Host_UDP_Communication(host_received_data);
#endif

PRF_GSYNC();
host_to_node_double(recvbuf_static, 1);
}
/* ================================================== ======================= */

/* ================================================== ======================= */
/* 3. 定义边界条件 Profile (保持不变) */
DEFINE_PROFILE(inlet_t, t, i)
{
static double recvbuf_static[1] = {300.0};
face_t f;
begin_f_loop(f, t)
{
F_PROFILE(f, t, i) = recvbuf_static[0];
}
end_f_loop(f, t)
}
/* ================================================== ======================= */
Tony G is offline   Reply With Quote

Reply

Tags
fluent, parallelization, udf

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
reaction UDF hooking issue !!! shafi_10 FLUENT 0 May 14, 2023 06:29
UDF Parabolic 2D Velocity Profile Issue chrislyn FLUENT 2 December 11, 2018 13:11
UDF issue Oula FLUENT 2 November 28, 2018 10:11
WILLING TO PAY/ FREELANCER REQUIRED / small UDF coding force loads over body / 6DOF acasas CFD Freelancers 1 January 23, 2015 08:26
Vibromixed 2d UDF loading issue carteblanche Main CFD Forum 0 May 23, 2011 15:42


All times are GMT -4. The time now is 23:38.