【fluent udf】定义源项宏时,在迭代计算过程中UDM变量变inf、NAN、发散时如何解决?

news2024/11/13 11:53:24

一、问题背景

最近做的一个fluent仿真算例里用到源项宏,源项宏里用UDM定义了树脂固化度场。

在迭代计算的过程中,UDM的取值发散成了无穷大inf(第一次计算取值是NAN),如下图所示。
在这里插入图片描述
由于每一次迭代计算过程中,需要用到以前的数据进行累加,所以某一步计算结果是inf,后面所有结果都会是无穷大。

本文介绍一种方法,在改动导致inf错误的代码的同时,可以不用从头开始计算(前提是已经迭代计算的流动时间占总时间的极小比例)。

二、解决办法

2.1 检查是否有UDF数据结构定义在了HOST节点中

以下是出错的源码,可以看到我原来将面网格数据结构定义在了host节点中,这样很容易出错。

因为host节点不存储任何网格数据,强行计算就可能会导致除以0而发散的悲剧。

notes:以下的代码只是profile宏,对于包括头文件的代码以及定义全局变量bou_temp 的代码被省略(实际存在)。

DEFINE_PROFILE(Inlet_Temp, t, i)
{
    real time = CURRENT_TIME;
    face_t f;
    if(time<=7200)
    {
        bou_temp = 300 + 0.025*time;
    }
    else if(time>7200 && time<=18000)
    {
        bou_temp = 480;
    }
    else if(time>18000 && time<=28800)
    {
        bou_temp = 480 - (time-18000)/60;
    }
    else 
        bou_temp = 300;


    begin_f_loop(f, t)
    {
        if (PRINCIPAL_FACE_P(f, t))
        {
            F_PROFILE(f, t, i) = bou_temp;
        }
    }
    end_f_loop(f, t)
}

改成如下形式。

DEFINE_PROFILE(Inlet_Temp, t, i)
{
    #if !RP_HOST
    real time = CURRENT_TIME;
    face_t f;
    if(time<=7200)
    {
        bou_temp = 300 + 0.025*time;
    }
    else if(time>7200 && time<=18000)
    {
        bou_temp = 480;
    }
    else if(time>18000 && time<=28800)
    {
        bou_temp = 480 - (time-18000)/60;
    }
    else 
        bou_temp = 300;


    begin_f_loop(f, t)
    {
        if (PRINCIPAL_FACE_P(f, t))
        {
            F_PROFILE(f, t, i) = bou_temp;
        }
    }
    end_f_loop(f, t)
    #endif
}

2.2 计算面积或体积权重平均物理量时分母是否偏小

小标题啥意思呢?

例如说一个实体中有3个网格单元,你需要计算这个实体的体积平均温度,公式如下。

在这里插入图片描述
但是你在写代码的过程中,可能将分子计算成了V1或V2或V3,而如果这个实体中计算节点足够多,你的实体足够大,单个V占整个总体积的比例越小,你的T_ave就会越趋于发散。

我就犯了如此大错,代码如下:

        #if !RP_HOST
        sheet_ct = Lookup_Thread(Get_Domain(1), sheet_id);

        begin_c_loop_int(c, sheet_ct)
        {
            curing_ratio_weighted_sum += C_VOLUME(c, sheet_ct) * C_UDMI(c, sheet_ct, 0);
            heat_weighted_sum += C_VOLUME(c, sheet_ct) * C_UDMI(c, sheet_ct, 3);
            volume_sum += C_VOLUME(c, sheet_ct);
        }
        end_c_loop_int(c, sheet_ct)

        curing_ratio_weighted_sum = PRF_GRSUM1(curing_ratio_weighted_sum);
        heat_weighted_sum = PRF_GRSUM1(heat_weighted_sum);
        curing_ratio_ave = curing_ratio_weighted_sum / volume_sum;
        heat_ave = heat_weighted_sum / volume_sum;
        End_iter_time = CURRENT_TIME;

        #endif

我没有将volume_sum用全局约简宏将所有计算节点上的总体积求和起来,因而就容易趋于发散。

代码改成下面的形式。

        #if !RP_HOST
        sheet_ct = Lookup_Thread(Get_Domain(1), sheet_id);

        begin_c_loop_int(c, sheet_ct)
        {
            curing_ratio_weighted_sum += C_VOLUME(c, sheet_ct) * C_UDMI(c, sheet_ct, 0);
            heat_weighted_sum += C_VOLUME(c, sheet_ct) * C_UDMI(c, sheet_ct, 3);
            volume_sum += C_VOLUME(c, sheet_ct);
        }
        end_c_loop_int(c, sheet_ct)

        curing_ratio_weighted_sum = PRF_GRSUM1(curing_ratio_weighted_sum);
        heat_weighted_sum = PRF_GRSUM1(heat_weighted_sum);
        volume_sum = PRF_GRSUM1(volume_sum);
        curing_ratio_ave = curing_ratio_weighted_sum / volume_sum;
        heat_ave = heat_weighted_sum / volume_sum;
        End_iter_time = CURRENT_TIME;

        #endif

三、如何无需从头开始计算就转inf为正常值

关于curing_ratio这个UDM变量,我在源项宏中对它的迭代计算公式是curing_ratio=curing_ratio+curing_ratio_rate*timestep,很显然如果curing_ratio有一步算出来是inf发散的,那么后面的所有迭代步就都是发散的。

因为已经变成inf(并且第二步就已经发散了),我不知道它迭代到当前步是什么值,所以最终就直接决定将其赋值为0,毕竟当前步和初始步之间的步数占总步数的千分之一还不到。

用什么赋值为0呢?

当然是帅气且灵活的DEFINE_ON_DEMAND宏啦,代码如下。

DEFINE_ON_DEMAND(init_UDM1)
{
    #if !RP_HOST
    Thread *sheet_ct;
    int sheet_id = sheet_zone_id;
    cell_t c;

    sheet_ct = Lookup_Thread(Get_Domain(1), sheet_id);

    begin_c_loop_int(c, sheet_ct)
    {
        C_UDMI(c, sheet_ct, 1) = 0.0;
    }
    end_c_loop_int(c, sheet_ct)
    #endif

    #if !RP_NODE
    Message("UDM1 is initialized successfully.\n");

    #endif
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/441015.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【嵌入式系统与入门】Day01 Arduino开发板

文章目录 1. Arduino概述1.1 是什么&#xff1f;1.2 分类1.3 组成1.4 电源 2. Arduino软件开发流程2.1 明确接口函数2.2 连接板子2.3 打开项目【或者自己编程序】2.4 选择板子类型2.5 选择通讯端口2.6 下载程序2.7. 编写程序代码——程序架构 3. 较常用的封装函数3.1 pinMode(p…

技术报告:Efficient and Effective Text Encoding for Chinese LLaMA AND Alpaca

技术报告&#xff1a;Efficient and Effective Text Encoding for Chinese LLaMA AND Alpaca IntroductionChinese LLaMAChinese AlpacaLora-Fine-tuning实验7Bpre- trainingInstruction-Tuning 13BPre-TrainingInstruct-Tuning Introduction 首先作者说了最近ChatGPT等模型在…

【SpringCloud】2、使用Nacos作为服务注册中心

1、项目搭建 首先&#xff0c;我们需要搭建一个 SpringCloud 微服务项目&#xff0c;后续的文章将基于此项目作为学习演示使用 1、创建 cloud-learn 目录&#xff0c;pom.xml 文件内容如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> &…

【数据统计】— 峰度、偏度、点估计、区间估计、矩估计、最小二乘估计

【数据统计】— 峰度、偏度、点估计、区间估计、矩估计、最小二乘估计 四分位差异众比率变异系数利用数据指标指导建模思路 形状变化数据分布形态峰度: 度量数据在中心聚集程度偏度 利用数据指标指导建模思路 参数估计点估计区间估计矩估计举例&#xff1a;黑白球&#xff08;矩…

修改键盘映射(注册表)Scancode Map

1.win R 打开 cmd命令框&#xff0c;输入regedit 2.赋值这个地址到蓝色框里&#xff1a; 计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout 3.右键 ->新建->二进制值&#xff0c;命名为 Scancode Map 4.现在来讲解怎么使用这个二进制表修…

LC串联谐振回路

理想LC串联谐振回路 下图是理想的LC串联谐振回路&#xff0c;不考虑L C的等效电阻。理想的LC回路没有任何损耗。 理想LC串联谐振的回路阻抗为&#xff1a; 令虚部为0&#xff0c;就可求出谐振角频率W0 可得谐振角频率&#xff1a; 可得谐振频率&#xff1a; 因为 所以电…

计算机网络之运输层

协议 协议就是计算机与计算机之间通信的“约定”&#xff0c;既为规则&#xff0c;只有遵循这个约定&#xff0c;双方就可以进行通信。 进程之间的通信 从通信和信息处理的角度来看&#xff0c;运输层向上面的应用层提供通信的服务&#xff0c;属于面向通信的最高层&#xf…

Redis哨兵(非集群 Rrdis 的高可用性 )

Redis哨兵(非集群 Rrdis 的高可用性 ) 1. 什么是哨兵 吹哨人巡查监控后台 master 主机是否故障,如果故障了根据投票数自动将某一个从库转换为新主库,继续对外服务 Redis哨兵在不使用Redis集群时为Redis提供高可用性 2. 作用 无人值守运维 3. 哨兵作为分布式系统 Redis S…

console.log(obj)不一定能的到obj当前的值

1.Log (anObject)的输出具有误导性; 只有在控制台中展开 > 时才能解析显示的对象的状态。它不是您在 console.log 对象时对象的状态。 相反&#xff0c;尝试 console.log (Object.keys ()) &#xff0c;或者甚至console.log(JSON.parse(JSON.stringify(obj))) &#xff0c;…

黑盒(功能)测试基本方法

1、黑盒测试的概念 1、什么是黑盒测试 &#xff08;1&#xff09;黑盒测试又称功能测试、数据驱动测试或基于规格说明书的测试&#xff0c;是一种从用户观点出发的测试。 &#xff08;2&#xff09;测试人员把被测程序当作一个黑盒子。 2、黑盒测试主要测试的错误类型有 &…

JVisualVM、Visual GC

JVisualVM JVisualVM Java VisualVM 是一款 JDK 自带免费的性能分析工具 public class JVisualVM {public static void main(String[] args) {Thread t1 new Thread(() -> {while (!Thread.currentThread().isInterrupted()) {}}, "JVisualVM测试子线程");t1.…

flinkcdc 动态的增加新的同步表到同一个作业中

背景 flinkcdc 2.0版本上线了一个新功能–支持动态加表这个是很有用的feature&#xff0c;本文介绍在开发中如何使用。 设想下假如你一个 CDC pipeline 监控了 4 张表&#xff0c;突然有天业务需求需要再加几张表&#xff0c;你肯定不想另起作业 (浪费资源)&#xff0c;那么这…

大数据——HDFS(分布式文件系统)

一&#xff0c;分布式系统概述 Hadoop的两大核心组件 HDFS&#xff08;Hadoop Distributed Filesystem&#xff09;&#xff1a;是一个易于扩展的分布式文件系统&#xff0c;运行在成百上千台低成本的机器上。HDFS具有高度容错能力&#xff0c;旨在部署在低成本机器上。HDFS主…

日撸 Java 三百行day34

文章目录 说明Day34 图的深度优先遍历1.思路2.代码3.总结1.在广度遍历中借助了队列2.在深度优先遍历借助了栈。 说明 闵老师的文章链接&#xff1a; 日撸 Java 三百行&#xff08;总述&#xff09;_minfanphd的博客-CSDN博客 自己也把手敲的代码放在了github上维护&#xff1a…

Android 开发之核心技术点——性能优化篇(带面试题)~

性能优化对于Android开发的重要性非常大。随着Android设备的不断升级&#xff0c;用户对应用的要求也越来越高&#xff0c;包括应用的运行速度、响应速度、流畅度等方面。如果应用的性能不能满足用户的需求&#xff0c;很可能会导致用户流失、差评以及应用被卸载等情况。 另外…

boot-admin整合flowable官方editor-app进行BPMN2.0建模

boot-admin整合flowable官方editor-app源码进行BPMN2.0建模 正所谓百家争鸣、见仁见智、众说纷纭、各有千秋&#xff01;在工作流bpmn2.0可视化建模工具实现的细分领域&#xff0c;网上扑面而来的是 bpmn.js 这个渲染工具包和web建模器&#xff0c;而笔者却认为使用flowable官…

2023零基础快速跟上人工智能第一梯队

写在前面&#xff1a;有关人工智能学什么&#xff0c;怎么学&#xff0c;什么路线等一系列问题。我决定整理一套可行的规划路线&#xff0c;希望帮助准备入门的朋友们少走些弯路。 下面我会推荐一个比较快速可行的学习模板&#xff0c;并附上我认为比较好的学习资料。 新手不建…

git使用规范文档

git使用规范文档 Git使用规范流程图 开发人员操作步骤&#xff1a; 第一步&#xff1a;clone代码 在你的本地代码库进行从远程仓库clone代码操作&#xff08;100%表示clone完成&#xff09; 进入项目文件&#xff0c;右键Git Bash Here 切换到你所进行开发的分支上 拉取该分…

JavaSE学习进阶day05_02 常见的数据结构和List接口

第三章 数据结构&#xff08;掌握&#xff09; 3.1 数据结构介绍 数据结构 : 数据用什么样的方式组合在一起。 科班出身的同学我想你对数据结构一点也不陌生&#xff0c;不知道你记不记得&#xff0c;当时学习数据结构的逻辑结构中的集合时&#xff0c;只是简单了解它&#…

hackathon 复盘:niche 海外软件工具正确的方法 6 个步骤

上周末&#xff0c;去参加了北京思否 hackathon&#xff0c;两天时间内从脑暴 & 挖掘软件 IDEA -> Demo 研发路演&#xff0c;这次经历让我难忘。这里我的看法是每个开发者圈友&#xff0c;都应该去参加一次 hackathon ~ 做 niche 软件正确的方法 这边先说结论&#xf…