基于DeepCFD模型和CNN/U-Net模型的流场预测

news2024/9/20 14:39:17

1.遇到问题

计算流体力学(Computational fluid dynamics, CFD)通过对Navier-Stokes方程(简称N-S方程)的精确求解,能够精准获取流体在不同状态下的物理量分布详情,这些物理量包括但不限于密度、压力及速度等关键参数。以下图为例,展示了圆柱体周边二维非均匀稳定层流通道流动的模拟结果。

在某些复杂的应用场景中,如机翼优化和流体与结构相互作用方面,需要使用千万级甚至上亿的网格对问题进行建模,导致CFD的计算量非常巨大。因此,目前亟需发展出一种相比于传统CFD方法更高效,且可以保持计算精度的方法。

因此,使用数据驱动的机器学习方法,使用一小部分资源来生成这些模拟的精确近似是非常有吸引的。这些近似解决方案以低错误率为代价加速结果的潜力可以更有效地开发依赖 CFD 研究的产品。问题来了,提出DeepCFD网络模型,该如何设计网络模型来解决流体力学中流场的问题呢?数据集应该如何构造呢?

2.前情提要

1)流场问题

二维不可压缩流体的 Navier-Stokes方程:

假设非均匀稳态流动条件:

输入:障碍物、边界条件

输出:流体的 x 方向速度、y 方向速度和流体压强 p

障碍物:

基本形状(圆形、正方形、前向三角形、后向三角形和菱形),如 primitive。

生成器生成障碍物形状为sample1 ~ 3的 2D 河道流量数据集的障碍物。

边界条件:

如下图所示:

顺流方向的域尺寸为260 mm,垂直于流动方向的域尺寸为120 mm。

网格元素的数量根据所使用的形状而变化,但是对于大约 1 mm 的基本单元大小,平均单元数大约为30000。

边界条件保持固定,入口(左壁)的恒定径向速度为0.1 米/秒,出口(右壁)的梯度为零,顶部/底部和障碍物壁的边界条件无滑 ,层流动态粘度设置为 1 * 10^-4 m^2/s,中心差分方案(CDS)用于动量方程对流项和扩散项的离散化。

2)数据集

数据集使用原作者利用OpenFOAM计算的CFD算例,共981组,分为两个文件(dataX.pkl, dataY.pkl),两个文件大小都是152 MB,形状均为[981, 3, 172, 79]。dataX.pkl包括三种输入:障碍物的SDF、计算域边界的SDF和流动区域的标签;dataY.pkl包括三种输出:流体的x方向速度、y方向速度和流体压强。数据获取使用的计算网格为172×79。

数据集地址:Data_DeepCFD_数据集-飞桨AI Studio星河社区

或https://www.dropbox.com/s/kg0uxjnbhv390jv/Data_DeepCFD.7z?dl=0

数据效果图如下:

3)深度学习模型

Net网络CV领域中图像分割的算法,其主要特点是输入和输出的尺寸是一样的。

典型的U-Net网络如下图所示:

由于其网络结构“U”型而得名,是由卷积、下采样、上采样和拼接操作组成的编码器—解码器对称网络。

网络左半部分是输入路径,右半部分是输出路径。

3.解决方案

1)网络结构

网络结构:编译器-解码器,如下图:

a图是具有SDF和流动区域多类别标记的输入通道。b图是下采样卷积操作从输入中创建流几何的潜在表示。c图是上采样反卷积将LGR显示出特定的变量。

2)DeepCFD模型

DeepCFD U-Net网络:模仿U-Net网络,由卷积、下采样、上采样和拼接操作组成。

其中,实验中4种变形模型如下:

3)损失函数

其中,速度v是L2,压强是L1。

4)训练细节

最后选择是:kernel size = 5。

4.代码结构及参数说明

1)自定义代码结构

loss_func():定义了计算一个模型(model)和一组批次数据(batch)的损失的损失函数。

    def loss_func(model, batch):
        x, y = batch
        output = model(x)
        lossu = ((output[:,0,:,:] - y[:,0,:,:]) ** 
2).reshape((output.shape[0],1,output.shape[2],output.shape[3])) 
        lossv = ((output[:,1,:,:] - y[:,1,:,:]) ** 
2).reshape((output.shape[0],1,output.shape[2],output.shape[3])) 
        lossp = torch.abs((output[:,2,:,:] - 
y[:,2,:,:])).reshape((output.shape[0],1,output.shape[2],output.shape[3])) 
        loss = (lossu + lossv + lossp)/channels_weights
        return torch.sum(loss), output

split_tensors():将数据集(x,y)拆分成一定百分比的数据集和测试集

def split_tensors(*tensors, ratio):
    assert len(tensors) > 0
    split1, split2 = [], []
    count = len(tensors[0])。
    for tensor in tensors:
        assert len(tensor) == count
        split1.append(tensor[:int(len(tensor) * ratio)])
        split2.append(tensor[int(len(tensor) * ratio):])
    if len(tensors) == 1:        split1, split2 = split1[0], split2[0]
    return split1, split2

下方代码是一个用于在给定数据加载器上执行一个 epoch 的训练或者是验证的函数。

def epoch(scope, loader, on_batch=None, training=False):
    model = scope["model"]
    optimizer = scope["optimizer"]
    loss_func = scope["loss_func"]
    metrics_def = scope["metrics_def"]
    scope = copy.copy(scope)
    scope["loader"] = loader
    metrics_list = generate_metrics_list(metrics_def)
    total_loss = 0
    if training:
        model.train()
    else:
        model.eval()
    for tensors in loader:
        if "process_batch" in scope and scope["process_batch"] is not None:
            tensors = scope["process_batch"](tensors)
        if "device" in scope and scope["device"] is not None:
            tensors = [tensor.to(scope["device"]) for tensor in tensors]
        loss, output = loss_func(model, tensors)
        if training:
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
        total_loss += loss.item()
        scope["batch"] = tensors
        scope["loss"] = loss
        scope["output"] = output
        scope["batch_metrics"] = {}
        for name, metric in metrics_def.items():
            value = metric["on_batch"](scope)
            scope["batch_metrics"][name] = value
            metrics_list[name].append(value)
        if on_batch is not None:
            on_batch(scope)
    scope["metrics_list"] = metrics_list
    metrics = {}
    for name in metrics_def.keys():
        scope["list"] = scope["metrics_list"][name]
        metrics[name] = metrics_def[name]["on_epoch"](scope)
    return total_loss, metrics

2)参数说明

参数

推荐值

额外说明

batch_size

64

批次大小,默认64

train_test_ratio

0.7

训练集占数据集的比例,0.7即训练集70%测试集30%

learning_rate

0.001

学习率

weight_decay

0.005

AdamW专用,若修改优化算法需要修改train.py

epochs

1000

训练轮数

kernel_size

5

卷积核大小

filters

8, 16, 32, 32

卷积层channel数目

batch_norm

0

批量正则化,0为False,1为True

weight_norm

0

权重正则化,0为False,1为True

data_path

./data

数据集路径,视具体情况设置

save_path

./result

模型和训练记录的保存路径,视具体情况设置

model_name

DeepCFD_965.pdparams

具体加载的模型名称,后缀不能省略

3)部分训练日志如下:

Epoch #1

        Train Loss = 884808909.0

        Train Total MSE = 10197.3000353043

        Train Ux MSE = 3405.3426083044824

        Train Uy MSE = 4334.0962839376825

        Train p MSE = 2457.8616943359375

        Validation Loss = 53205074.5

        Validation Total MSE = 1027.7523040254237

        Validation Ux MSE = 419.7688029661017

        Validation Uy MSE = 543.9674920550848

        Validation p MSE = 64.01604872881356

Epoch #2

        Train Loss = 75408434.25

        Train Total MSE = 603.198411591199

        Train Ux MSE = 277.9321616481414

        Train Uy MSE = 303.4222437021684

        Train p MSE = 21.843986488987337

        Validation Loss = 17892356.5

        Validation Total MSE = 312.7194186970339

        Validation Ux MSE = 169.64230501853814

        Validation Uy MSE = 140.46789757680085

        Validation p MSE = 2.6092084981627384

5.实验对比

1)误差对比

2)计算效果对比

3)效果展示

1)ground-truth CFD (simpleFOAM) 和 DeepCFD 预测之间的比较,显示了速度分量和压力场,以及基于圆的形状 1 周围流动的绝对误差。

2)ground-truth CFD (simpleFOAM) 和 DeepCFD 预测的比较,显示了速度分量和压力场,以及围绕基于方形的形状2的流动绝对误差。

3)ground-truth CFD (simpleFOAM) 和 DeepCFD 预测的比较,显示了速度分量和压力场,以及基于菱形的形状 1 周围流动的绝对误差。

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

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

相关文章

Nginx从入门到入土(二): 学习内容与安装

Nginx学习内容 1.理解Nginx在实际项目中的应用场景 2.理解正向代理和反向代理 3.Nginx在Linux和Windows上的安装 4.Nginx的运行模型概念与日志管理 5.Nginx.config核心配置文件与配置HTTPS证书 6.基于Nginx解决跨域,实现防盗链,缓存,压…

windows C++ 并行编程-异步消息块(一)

代理库提供了多种消息块类型,使你能够以线程安全的方式在应用程序组件之间传播消息。 这些消息块类型通常与 concurrency::send、concurrency::asend、concurrency::receive 和 concurrency::try_receive 等各种消息传递例程配合使用。 本文包含以下各节&#xff1…

C#通过MXComponent与三菱PLC通信

1,MXComponent安装包与手册。 https://download.csdn.net/download/lingxiao16888/89767137 2,使用管理员权限打开MXComponent,并进行配置。 3,引用相应的类库。 //通信类库 ActUtlTypeLib.dll或者ActProgType.dll 注明&#x…

Excel常用函数大全

Excel常用函数介绍与示例应用 在Excel中,函数是进行数据处理和分析的强大工具。对于新手来说,掌握一些基本的函数使用方法能够大大提升工作效率。以下是一份通俗易懂、适合新手的Excel函数使用方法总结: 1. 求和函数(SUM&#x…

leetcode75-9 压缩字符串 双指针原地算

题目太复杂了 没做出来 计算过程大概是双指针处理数组, 其中两个知识点一个是length 字符数组直接加 不用加括号 还有就是数字转字符需要转换 数字转换成字符 不能直接转换! 需借助数字转字符串, 首先将数字转为字符串,…

C++---类与对象一

类的定义 class className{//成员字段//成员函数 };class定义类的关键字,className是自己决定的类名,{ } 为类的主体,花括号里是类的内容。类的内容大致分为类的成员属性(变量)和类的成员函数。注意定义类后面需要跟;…

SpringBoot - 基于 Java的超市进销存系统

专业团队,咨询就送开题报告,欢迎大家私信,留言,联系方式在文章底部 摘 要 随着信息化时代的到来,管理系统都趋向于智能化、系统化,超市进销存系统也不例外,但目前国内仍都使用人工管理&#xf…

【JUC】17-Synchronized锁升级

1. 锁分类 无锁->偏向锁->轻量级锁->重量级锁 synchronized属于重量级锁,monitor是基于底层os的mutex Lock实现了,挂起线程和恢复线程都需要内核态完成,都需要切换CPU状态来完成。 Monitor与对象以及线程如何关联?  1…

OV-DINO:统一开放词汇检测与语言感知选择性融合

文章目录 摘要1、引言2、相关工作3、方法3.1、概述3.2、统一数据集成3.3、语言感知选择性融合3.4、以检测为中心的预训练 4、实验4.1、预训练数据和评估指标4.2、实施细节4.3、主要结果4.4、消融研究4.5、定性结果 5 、讨论 摘要 开放词汇检测(Open-vocabulary Det…

滑动窗口(6)_找到字符串中所有字母异位词

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 滑动窗口(6)_找到字符串中所有字母异位词 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记,欢迎大家在评论区交流讨论&#x1f4…

《SmartX ELF 虚拟化核心功能集》发布,详解 80+ 功能特性和 6 例金融实践

《SmartX ELF 虚拟化核心功能集》电子书现已发布!本书详细介绍了 SmartX ELF 虚拟化及云平台核心功能,包含虚机服务、容器服务、网络服务、存储服务、运维管理、工具服务、数据保护等各个方面。 即刻下载电子书,了解如何利用基于 SmartX ELF …

助力电商升级,智象未来(HiDream.ai)开启未来商业新篇章

近日,智象未来(HiDream.ai)凭借其创新性的“秩象™大模型”,在业界掀起了一场跨行业的创意革命,对视觉设计、运营商服务、品牌营销以及文旅传媒等领域的创新发展产生了深远影响。致力于全球领先的多模态生成式人工智能…

neo4j节点关联路径的表示、节点的增删改查

目录 核心概念节点的增删改查(1)增(2)查(3)删(4)改 neo4j文档:https://neo4j.com/docs/ https://neo4j.com/docs/cypher-manual/current/introduction/ 核心概念 节点 ne…

【从计算机的发展角度理解编程语言】C、CPP、Java、Python,是偶然还是应时代的产物?

参考目录 前言什么是"computer"?计算机的大致发展历程计算机系统结构阶段(1946~1981)计算机网络和视窗阶段(1982~2007)复杂信息系统阶段(2008~today)人工智能阶段 越新的语言是越好的吗、越值得学习吗? 前言 最近读了 《Python语言程序设计基础》 这本书…

Linux运维篇-服务器简介

目录 前言服务器分类(按服务器的机箱结构来划分)台式服务器机架式服务器刀片式服务器 外观部件内部结构前面板前面板组件前面板接口说明前面板指示灯和按钮前面板指示灯/按钮说明 后面板后面板组件后面板接口说明后面板指示灯后面板指示灯说明 主板和 iB…

C#|.net core 基础 - 值传递 vs 引用传递

不知道你在开发过程中有没有遇到过这样的困惑:这个变量怎么值被改?这个值怎么没变? 今天就来和大家分享可能导致这个问题的根本原因值传递 vs 引用传递。 在此之前我们先回顾两组基本概念: 值类型** vs 引用类型** **值类型&a…

适合金融行业的银行级别FTP替代升级方案

在数字化办公日益普及的今天,金融领域对数据传输的需求日益增长,场景也变得更加多样化和复杂。这不仅包括内部协作,还涉及金融服务、外部合作以及跨境数据流动等方面。因此,金融行业对数据传输系统的要求越来越高,传统…

LeetCode 算法笔记-第 04 章 基础算法篇

1.枚举 采用枚举算法解题的一般思路如下: 确定枚举对象、枚举范围和判断条件,并判断条件设立的正确性。一一枚举可能的情况,并验证是否是问题的解。考虑提高枚举算法的效率。 我们可以从下面几个方面考虑提高算法的效率: 抓住…

孙怡带你深度学习(3)--损失函数

文章目录 损失函数一、L1Loss损失函数1. 定义2. 优缺点3. 应用 二、NLLLoss损失函数1. 定义与原理2. 优点与注意3. 应用 三、MSELoss损失函数1. 定义与原理2. 优点与注意3. 应用 四、BCELoss损失函数1. 定义与原理2. 优点与注意3. 应用 五、CrossEntropyLoss损失函数1. 定义与原…

『 Linux 』HTTP(一)

文章目录 域名URLURLEncode和URLDecodeHTTP的请求HTTP的响应请求与响应的获取简单的Web服务器 域名 任何客户端在需要访问一个服务端时都需要一个IP和端口号,而当一个浏览器去访问一个网页时通常更多使用的是域名而不是IP:port的方式, www.baidu.com这是百度的域名; 实际上当浏…