【浅水模型MATLAB】尝试复刻SCI论文中的溃坝流算例

【浅水模型MATLAB】尝试复刻SCI论文中的溃坝流算例

  • 前言
  • 问题描述
  • 控制方程及数值方法
    • 浅水方程及其数值计算方法
    • 边界条件的实现
  • 代码框架与关键代码
  • 模拟结果

更新于2024年9月17日

前言

这篇博客算是学习浅水方程,并利用MATLAB复刻Liang (2004)1中溃坝流算例的一个记录。
二维溃坝流(Dam Break)问题是浅水模型经典的一个测试算例,它测试了模型对急变流的模拟效果、以及对干-湿边界处理方法的有效性。相比于之前的模拟算例,本算例中需要重点处理的问题是:

  1. 模型的内边界的处理;
  2. 干-湿边界的处理。

本博客将着重解决第一个问题,而先不考虑第二个问题,即设置的模拟算例不含干-湿边界的处理。此外,本算例中涉及的控制方程与数值方法已经在《【浅水模型MATLAB】尝试完成一个数值模拟竞赛题》中介绍;不清楚的朋友可参考该博客内容。

如果你习惯用别的代码,也想做类似的建模尝试,十分欢迎一起交流!(最近有点想转python代码了,希望感兴趣的同志来一起交流)
如果各位朋友发现了文章或代码中的错误,亦或是改进之处,请不吝赐教,欢迎大家留言,一起改进模型!本博客文章将持续更新,上面也会标注提出改进建议的同志们。(不过,本人最近在忙活毕业论文,可能更新不及时)

同时,想要完整代码的朋友请联系我,我可无偿提供脚本文件。

希望同大家一起进步!

问题描述

本算例的计算区域为一个200m×200m的矩形平底水槽,水槽的四周都是垂直的固体壁面。如下图所示,计算域被分成x<100m和x>100m的左右两个部分;左侧初始水深为10m,右侧初始水深为5m。左右两个区域被两道平行于y方向的壁面阻隔,仅在95m<y<170m的区域联通。在模拟开始时,左侧水体会突然通过x=100m,95m<y<170m的区域向着右侧下泄,形成溃坝流。此外,模型中的所有壁面都是光滑的。
在这里插入图片描述

控制方程及数值方法

浅水方程及其数值计算方法

二维浅水方程的形式及其具体求解内容详见Liang的论文2和博客《【浅水模型MATLAB】尝试完成一个数值模拟竞赛题》。模型采用Godunov型有限体积法,通过一系列的处理,方程也保证了静水状态时压力与底坡源项的平衡。
此外,模型中的水力变量都定义在网格的中心位置。网格边界处的通量采用HLL求解器获得。

边界条件的实现

计算域的外边界均为无通量的free-slip闭合边界,边界处的法向速度和通量均被定义为0。在求解过程中,可将边界处的水力参数设置为其临近网格相同的物理量的值。
对于模型在x=100m处的内边界,模型需要定义其对应边界的通量为零。具体处理方式如下图所示。在对内边界左侧的相邻网格进行线性重构通量计算时,需要通过一个辅助计算的虚网格,该虚网格有着和左侧相邻网格i相同的水力变量值。同理,在对内边界右侧的相邻网格进行线性重构通量计算时,也需要通过一个辅助计算的虚网格,该虚网格有着和右侧 相邻网格i相同的水力变量值。由于本模型采用了Minmod的限制器,所以此种处理会使得内边界对应的左侧变量UL =Ui,而使右侧变量UR =Ui+1
在这里插入图片描述

代码框架与关键代码

我的模型代码主要分为参数设置、网格构建、初始化、主循环和其余函数等五个部分。

  1. 设置物理参数、网格参数、时间参数等。代码如下所示:
grav = 9.81;            % Gravitational acceleration
rho = 1000;             % Density
CFL = 0.5;              % Courant Number

Lx = 200;             	% Length of the domain
Ly = 200;              	% Width of the domain
zb0 = 0.0;              % Bottom elevation
n = 0.00;               % Manning coefficient
h_dry = 0.02;           % wet-dry threshold value

dx = 1;                 % Grid spacing
dy = 1;                 % Grid spacing
dt = 0.05;               % Time spacing at the first step
dtmax = 0.1;            % allowed max time step (s)
tend = 10.0;            % End of the simulation time
plot_int = 0.5;      	% Time interval to next plot

我设置网格为边长1m的正方形,底高程为zb0=0.0。最大允许的Courant数设置为0.5,初始时间步为0.05s,之后的每一个时间步通过CFL条件计算得到。

  1. 网格构建:网格有两个要素需要定义,一是网格的四个节点(Xp和Yp),二是网格的中心点(Xc和Yc);网格中心点也即水力物理量定义的位置。代码略。
  2. 初始化:设置底高程zb=0,计算zb的梯度zbx和zby;设置左右区域的初始水位,之后再设置流速u、v为零。
  3. 主循环:(1)计算网格边界处的水位、水深、流速值;(2)设置内边界条件;(3)计算通量项FL、FR、GL和GR;(4)利用HLL求解通量F和G;(5)计算源项S;(6)计算新一个时间步的eta、h、u和v。除了上述步骤(2)和(3)其余计算过程与博客《【浅水模型MATLAB】尝试完成一个数值模拟竞赛题》中代码基本一致;涉及的关键代码如下:
while(t<tend)
    % estimate the dt
    dtx = dx./(abs(u)+sqrt(grav*h) + 1E-8);
    dty = dy./(abs(v)+sqrt(grav*h) + 1E-8);
    dt1 = min(min(dtx,[],"all"), min(dty,[],"all"));
    dt = min(dtmax, CFL*dt1);
    clear dt1 dtx dty
    
    etan = eta;     hn = h;
    un = u;         vn = v;
    % 2rd-order Runge-Kutta Method
    for k = 1:2
        % 1. reconstruct the flow data
        % 1.1 x-direction reconstruction (Natural closed boundary)
        % 求解网格边界处的水位exL和exR,流速uxL、uxR、vxL和vxR;
        % ...
        % 1.2 y-direction reconstruction (Natural closed boundary)
        % 求解网格边界处的水位eyL和eyR,流速uyL、uyR、vyL和vyR;
        % ...

        % 2. inner boundary conditions
        ff = find((yc<=95) + (yc>=170));
        % 2.1 left cells
        de = minmod((eta(:,Nx/2)-eta(:,Nx/2))/dx, ...
                    (eta(:,Nx/2)-eta(:,Nx/2-1))/dx);
        du = minmod((u(:,Nx/2)-u(:,Nx/2))/dx, ...
                    (u(:,Nx/2)-u(:,Nx/2-1))/dx);
        dv = minmod((v(:,Nx/2)-v(:,Nx/2))/dx, ...
                    (v(:,Nx/2)-v(:,Nx/2-1))/dx);
        exR(ff,Nx/2) = eta(ff,Nx/2) - 0.5*dx*de(ff);
        exL(ff,Nx/2+1) = eta(ff,Nx/2) + 0.5*dx*de(ff);
        clear de du dv
        % 2.2 right cells
        de = minmod((eta(:,Nx/2+2)-eta(:,Nx/2+1))/dx, ...
                    (eta(:,Nx/2+1)-eta(:,Nx/2+1))/dx);
        du = minmod((u(:,Nx/2+2)-u(:,Nx/2+1))/dx, ...
                    (u(:,Nx/2+1)-u(:,Nx/2+1))/dx);
        dv = minmod((v(:,Nx/2+2)-v(:,Nx/2+1))/dx, ...
                    (v(:,Nx/2+1)-v(:,Nx/2+1))/dx);
        exR(ff,Nx/2+1) = eta(ff,Nx/2+1) - 0.5*dx*de(ff);
        exL(ff,Nx/2+2) = eta(ff,Nx/2+1) + 0.5*dx*de(ff);
        clear ff de du dv
        
        % 3. flux terms (F and G)
        F1L = hxL.*uxL;
        F2L = hxL.*uxL.*uxL + 0.5*grav*(exL.*exL - ...
              exL.*(zbp(1:end-1,:)+zbp(2:end,:)));
        F3L = hxL.*uxL.*vxL;
        F1R = hxR.*uxR;
        F2R = hxR.*uxR.*uxR + 0.5*grav*(exR.*exR - ...
              exR.*(zbp(1:end-1,:)+zbp(2:end,:)));
        F3R = hxR.*uxR.*vxR;

        G1L = hyL.*vyL;
        G2L = hyL.*uyL.*vyL;
        G3L = hyL.*vyL.*vyL + 0.5*grav*(eyL.*eyL - ...
              eyL.*(zbp(:,1:end-1)+zbp(:,2:end)));
        G1R = hyR.*vyR;
        G2R = hyR.*uyR.*vyR;
        G3R = hyR.*vyR.*vyR + 0.5*grav*(eyR.*eyR - ...
              eyR.*(zbp(:,1:end-1)+zbp(:,2:end)));

        % 4. calculate the flux by HLL
        [sxL sxR] = WaveSpeed(hxL, hxR, uxL, uxR);
        F1 = HLLSolver(F1L, F1R, sxL,sxR, exL,exR);
        F2 = HLLSolver(F2L, F2R, sxL,sxR, hxL.*uxL,hxR.*uxR);
        F3 = HLLSolver(F3L, F3R, sxL,sxR, hxL.*vxL,hxR.*vxR);
        [syL syR] = WaveSpeed(hyL, hyR, vyL, vyR);
        G1 = HLLSolver(G1L, G1R, syL,syR, eyL,eyR);
        G2 = HLLSolver(G2L, G2R, syL,syR, hyL.*uyL,hyR.*uyR);
        G3 = HLLSolver(G3L, G3R, syL,syR, hyL.*vyL,hyR.*vyR);
        clear sxL sxR syL syR F1L F1R F2L F2R F3L F3R G1L G1R G2L G2R G3L G3R
        % 4.1. west boundary
        % ...
        % 4.2. east boundary
        % ...
        % 4.3. south boundary
        % ...
        % 4.4. north boundary
        % ...
        % 4.5. inner boundary
        ff = find((yc<=95) + (yc>=170));
        F1(ff,Nx/2+1) = 0;  F3(ff,Nx/2+1) = 0;
        F2_L(ff,1) = 0.5*grav*(exL(ff,Nx/2+1).^2 - ...
                     exL(ff,Nx/2+1).*(zbp(ff+1,Nx/2+1)+zbp(ff,Nx/2+1)));
        F2_R(ff,1) = 0.5*grav*(exR(ff,Nx/2+1).^2 - ...
                   	 exR(ff,Nx/2+1).*(zbp(ff+1,Nx/2+1)+zbp(ff,Nx/2+1)));
        clear ff exL exR eyL eyR hxL hxR hyL hyR uxL uxR uyL uyR vxL vxR vyL vyR
        % 5. source terms
        % 计算S的三个分量S1、S2和S3
        % ...

        % 6. time stepping
        % 6.1 solve eta
        % ...
        % 6.2 solve h*u
        % ...
        %     for inner boundary
        ff = find((yc<=95) + (yc>=170));
        hu(ff,Nx/2) = h(ff,Nx/2).*u(ff,Nx/2)  ...
                    - dt/dx*(F2_L(ff) - F2(ff,Nx/2)) ...
                    - dt/dy*(G2(ff+1,Nx/2)-G2(ff,Nx/2)) + dt*S2(ff,Nx/2);
        hu(ff,Nx/2+1) = h(ff,Nx/2+1).*u(ff,Nx/2+1)  ...
                      - dt/dx*(F2(ff,Nx/2+2) - F2_R(ff)) ...
                      - dt/dy*(G2(ff+1,Nx/2+1)-G2(ff,Nx/2+1)) + dt*S2(ff,Nx/2+1);
        clear ff F2_L F2_R
        % 6.3 solve h*v
        % ...
        % ...
    end
    
    % 计算得到本时间步的h、u和v
    
    % 7. plot
    % ...
    end
end
  1. 其余子函数:包括minmod限制器、HLL求解器等。代码略。

模拟结果

1.水位结果
在这里插入图片描述
2.流速结果(颜色表示合速度的大小,箭头表示速度方向)
在这里插入图片描述
3. 三维水面图
在这里插入图片描述


  1. Liang, Q., Borthwick, A.G.L. and Stelling, G. (2004), Simulation of dam- and dyke-break hydrodynamics on dynamically adaptive quadtree grids. Int. J. Numer. Meth. Fluids, 46: 127-162. ↩︎

  2. Liang Q , Marche F .Numerical resolution of well-balanced shallow water equations with complex source terms[J].Advances in Water Resources, 2009, 32(6):873-884. ↩︎

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Gitee丝滑版本:成功在新电脑添加新文件

git 关键步骤 1.首先在新电脑建一个文件夹&#xff0c;然后打开这个文件夹里面右键打开OPEN BASH GIT HERE。 2.然后输入git init&#xff0c;会在文件夹生成一个git.文件&#xff0c;接着把复制的get clone命令克隆过去就可以下载了&#xff0c;如果遇到403问题&#xff0c…

循环神经网络RNN+长短期记忆网络LSTM 学习记录

循环神经网络&#xff08;RNN) RNN的的基础单元是一个循环单元&#xff0c;前部序列的信息经处理后&#xff0c;作为输入信息传递到后部序列 x为输入向量&#xff0c;y为输出向量&#xff0c;a为上一隐藏层的a与x通过激活函数得到的值&#xff0c;简言之&#xff0c;每一层神…

从头开始学MyBatis—02基于xml和注解分别实现的增删改查

首先介绍此次使用的数据库结构&#xff0c;然后引出注意事项。 通过基于xml和基于注解的方式分别实现了增删改查&#xff0c;还有获取参数值、返回值的不同类型对比&#xff0c;帮助大家一次性掌握两种代码编写能力。 目录 数据库 数据库表 实体类 对应的实体类如下&#x…

Java项目: 基于SpringBoot+mybatis+maven洗衣店订单管理系统(含源码+数据库+开题报告+任务书+毕业论文)

一、项目简介 本项目是一套基于SpringBootmybatismaven洗衣店订单管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作…

List<Map<String, Object>>汇总统计排序

开发环境&#xff1a;jdk 1.8 需求一&#xff1a; 1、统计每个小时(升序)不同事件的产品产量 2、统计不同事件&#xff08;OK 、NG&#xff09;的总产量 public static void main(String[] args) {//数据源List<Map<String, Object>> list new ArrayList<Map…

根据 IP 地址进行 VPN 分流(详细,亲测,通用)

根据 IP 地址进行 VPN 分流&#xff08;详细&#xff0c;亲测&#xff0c;通用&#xff09; 背景 不在学校的时候需要使用实验室的服务器&#xff0c;但是实验室的服务器只能在校园网内访问&#xff0c;因此在校外就需要使用学校的 VPN&#xff0c;但是打开 VPN 以后会默认将…

js 3个事件监听器 EventListeners

起因&#xff0c; 目的: 我有2个显示器。 某视频网站&#xff0c;我想一边播放视频&#xff0c;一边搞其他。但是&#xff0c;当我把鼠标移动到浏览器外面&#xff0c;点击一下别处&#xff0c; 视频就会自动暂停. 这个叫做 事件监听&#xff01; blur, 在元素或窗口失去焦点…

JSON对接发送短信验证码怎么获取状态报告

现在很多网站的用户注册都会加一个短信验证功能&#xff0c;也就是需要用户填写手机号&#xff0c;然后点击“获取短信验证码”&#xff0c;将收到的短信验证码输入验证通过后方能进行下一步完成注册&#xff0c;现在短信验证码被广泛应用于网站用户注册&#xff0c;还被广泛应…

linux 安装histomicstk

一直安装失败&#xff0c;源码编译也未成功 最后使用这个成功了 pip install histomicstk --find-links https://girder.github.io/large_image_wheels

零基础如何学会Appium自动化测试?

前言 appium是一款移动自动化测试工具&#xff0c;经常被用于实现UI自动化测试&#xff0c;其可支持安卓和IOS两大平台&#xff0c;还支持多种编程&#xff0c;因而得到了广泛的应用。此处便是立足于安卓平台&#xff0c;借助appium工具&#xff0c;使用python语言实现简单的自…

王者荣耀改重复名(java源码)

王者荣耀改重复名 项目简介 “王者荣耀改重复名”是一个基于 Spring Boot 的应用程序&#xff0c;用于生成王者荣耀游戏中的唯一名称。通过简单的接口和前端页面&#xff0c;用户可以输入旧名称并获得一个新的、不重复的名称。 功能特点 生成新名称&#xff1a;提供一个接口…

[mysql]mysql排序和分页

#排序和分页本身是两块内容,因为都比较简单,我们就把它分到通一个内容里. #1排序: SELECT * FROM employees #我们会发现,我们没有做排序操作,但是最后出来的107条结果还是会按顺序发出,而且是每次都一样.这我们就有一个疑惑了,现在我们的数据库是根据什么来排序的,在我们没有进…

【机器学习】--- 自然语言推理(NLI)

引言 随着自然语言处理&#xff08;NLP&#xff09;的迅速发展&#xff0c;**自然语言推理&#xff08;Natural Language Inference, NLI&#xff09;**已成为一项重要的研究任务。它的目标是判断两个文本片段之间的逻辑关系。这一任务广泛应用于机器阅读理解、问答系统、对话…

二叉搜索树(Java实现)

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 关注博主带你了解更多数据结构知识 目录 1.概念 2.实现二叉搜索树 定义节点 查找元素 插入元素 删除元素 1.概念 二叉搜索树又称二叉排序树,或者它是一棵空树,或者是具有…

数字IC设计\FPGA 职位经典笔试面试整理--语法篇 Verilog System Verilog(部分)

注&#xff1a; 资料都是基于网上一些博客分享和自己学习整理而成的 Verilog 1. 数据类型 Verilog一共有19种数据类型 基础四种数据类型&#xff1a;reg型&#xff0c;wire型&#xff0c;integer型&#xff0c;parameter型 reg型   reg类型是寄存器数据类型的关键字。寄存…

镀金引线---

一、沉金和镀金 沉金和镀金都是常见的PCB金手指处理方式&#xff0c;它们各有优劣势&#xff0c;选择哪种方式取决于具体的应用需求和预算。 沉金&#xff08;ENIG&#xff09;是一种常用的金手指处理方式&#xff0c;它通过在金手指表面沉积一层金层来提高接触性能和耐腐蚀性…

【C++】模拟实现vector

在上篇中我们已经了解过的vector各种接口的功能使用&#xff0c;接下来我们就试着模拟实现一下吧&#xff01; 注意&#xff1a;我们在此实现的和C标准库中实现的有所不同&#xff0c;其目的主要是帮助大家大概理解底层原理。 我们模拟vector容器的大致框架是&#xff1a; t…

[SIGGRAPH-24] CharacterGen

[pdf | code | proj] LRM能否用于3D数字人重建&#xff1f;问题在于&#xff1a;1&#xff09;缺少3D数字人数据&#xff1b;2&#xff09;重建任意姿态的3D数字人不利于后续绑定和驱动。构建3D数字人数据集&#xff1a;在VRoidHub上采集数据&#xff0c;得到13746个风格化角色…

图片编辑软件,这4款免费又好用!

在这个视觉为王的时代&#xff0c;一张精心编辑的图片往往能瞬间吸引眼球&#xff0c;无论是社交媒体分享、博客配图还是商业宣传&#xff0c;都离不开强大的图片编辑工具。但高昂的软件费用常常让人望而却步。别担心&#xff0c;今天我们就来揭秘4款不仅免费还超级好用的图片编…

OpenAI 刚刚推出 o1 大模型!!突破LLM极限

北京时间 9 月 13 日午夜&#xff0c;OpenAI 正式发布了一系列全新的 AI 大模型&#xff0c;专门用于应对复杂问题。 这一新模型的出现代表了一个重要突破&#xff0c;其具备的复杂推理能力远远超过了以往用于科学、代码和数学等领域的通用模型&#xff0c;能够解决比之前更难的…