今天阅读了一本说明书,《gdbOF: A Debugging Tool for OpenFOAM》
受himryangzz视频启发去读相关内容,在此对himryangzz表示感谢
希望本篇文章能为需要gdb调试of的人节约时间
文章前言说of确实做的很不错,但调试者需要对of类的结构有较好的理解
gdbOF正是为了解决该问题而存在的,内置的一些宏可以让of调试更容易,一些数据结构类看起来更透明简单
总而言之,文章介绍说gdbOF内置的这些宏很实用
那我们看看王婆卖的什么瓜
#- Optimised, debug, profiling:
# WM_COMPILE_OPTION = Opt | Debug | Prof
export WM_COMPILE_OPTION=Opt
也可这样设置为debug模式和opt模式
alias of_version_debug='source /opt/openfoam_version/etc/bashrc WM_COMPILE_OPTION=Debug'
alias of_version='source /opt/openfoam_version/etc/bashrc'
installgdbOF.sh在运行时会检查是否在debug状态
可能有小伙伴发现自己的debug模式会报错,找不到一些链接库这样,这是由于apt install导致的,需要改为编译安装,类似cmake加-g也可
讲了下用gdb怎么更好的把结果输出出来
例如书中提及的第一个指令,
$(gdb) p *v@v_size
稍微改一下就是压力场所有的数值
*p.v_@p.size_:[400]
[0]:7.1360554926197225e-08
[1]:0.9046069230595515128
[2]:9.613495251485993206
[3]:9.624492714877064921
[4]:9.936190016356530057
写到这里已经可以让很多做of的人期待书内后面的内容了
书里说如果我们需要快速的提取我们想要的信息,那么就需要我们对openfoam的继承树很了解
那么就拿p下手,了解下相关继承树
gdb打印出来这样
p:{..}
Foam:DimensionedField<double,Foam:VolMesh>(base):
typeName
debug:0
timeIndex:3
field0Ptr 0x0
fieldPrevIterPtr:0x0
boundaryField_
这东西不能多看,看多了精神容易出问题
我们之前博客也提过p是volScalarFiel类,构造方法是这样的
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const Mesh& mesh
)
:
Internal(io, mesh, dimless, false),
timeIndex_(this->time().timeIndex()),
field0Ptr_(nullptr),
fieldPrevIterPtr_(nullptr),
boundaryField_(mesh.boundary())
{
readFields();
// Check compatibility between field and mesh
if (this->size() != GeoMesh::size(this->mesh()))
{
FatalIOErrorInFunction(this->readStream(typeName))
<< " number of field elements = " << this->size()
<< " number of mesh elements = " << GeoMesh::size(this->mesh())
<< exit(FatalIOError);
}
readOldTimeIfPresent();
if (debug)
{
InfoInFunction
<< "Finishing read-construction of" << endl << this->info() << endl;
}
能看到初始化了很多东西,下面展开看下初始化了什么
Internal(io, mesh, dimless, false),
timeIndex_(this->time().timeIndex()),
field0Ptr_(nullptr),
fieldPrevIterPtr_(nullptr),
boundaryField_(mesh.boundary())
这次你再看gdb打印那些烂东西,咱对比一下
对劲了对劲了,
非常对劲!
咱们再说说
$(gdb) p *v@v_size
要展示什么数据,是内部面的压力场的数据,为什么这么说
因为我用gdb中打开p的地址,指向的是内部场
那这么看我们可以畅所欲为的抽取所有数据了,
其实本来就可以的,但是gdbOF好就好在为你指明了要抽取哪些
比如说边界面数据书内的提示是
$(gdb) p *(vSF.boundaryField_.ptrs_.v_[0].v_)@(vSF.boundaryField_.ptrs_.v_[0].size_)
书内解释说vSF是volScalarField的缩写,那p刚好符合要求,输入即可看到边界场的值
比如说我们打开这个boundary,
FoamFile
{
version 2.0;
format ascii;
class polyBoundaryMesh;
location "constant/polyMesh";
object boundary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
3
(
movingWall
{
type wall;
inGroups List<word> 1(wall);
nFaces 20;
startFace 760;
}
fixedWalls
{
type wall;
inGroups List<word> 1(wall);
nFaces 60;
startFace 780;
}
frontAndBack
{
type empty;
inGroups List<word> 1(empty);
nFaces 800;
startFace 840;
}
)
有3个patch那么UList就应该是三维,Ulist[2]是frontAndBack,因为是empty,按理说就应该是没有数据
*(p.boundaryField_.ptrs_.v_[2]).v_@(p.boundaryField_.ptrs_.v_[2]).size_=0
确实是如此
继续回头看书上内容,读到这里已经非常惊喜了
这得省多少劲
但也不必过于乐观,目前这个测试案例比较简单,具体调试时候不一定碰到什么问题
书上继续说以上都是甜头,接下来我们内置集成的一些宏更有用,比如说ppatchesvalueslimits,pinternalvalueslimits.,ppatchlist等
书上也提及了一个问题,就是of有时候代码跳转不过去,确实是有这个问题的,书上说,碰见这样的你就一步步走吧
这里gdbOF也提供了便利,step, next and finish这些宏也内置好了
书中提及,在of中矩阵的显示是个难题,gdb采用了c风格的代码显示,遍历显示倒是好写,但性能太差,of这种大矩阵没法用
这点gdbOF利用python做出了改进,分别介绍了pfvmatrixfull和pfvmatrixsparse的伪代码。
这里额外说一句啊,其实很赞同matlab的矩阵表达方式的,非常快,而且向量化编程写法可以让速度提升一大截,以后看看有没有机会把matlab 植入到of中
看他们伪代码的意思貌似是收集一部分数据自己进行LU分解,之前我也读过一些论文说ofLU分解效率不大行的,可能gdbOF给出了python版本的解决方案
** Structure of gdbOF Command pfvmatrixsparse.**
1. Get parameters
2. Get upper and lower arrays with gdb
3. Redirect data to aux file
4. Format aux files: gdb format → python format
5. Call python script to assemble the matrix
(a) Read aux files
(b) Do lduAddressing for sparse matrix
(c) Generate sparse file header
6. Format aux files: python format → gdb format
7. Show in output or/and save file in octave format adding the header to the body
这里简述一下库中其他程序功能
pfindCell用于找位置,在此基础上pinternalvalueslimits抽取场值以及中心节点数据,pfvmatrix用于观察为该单元组装的方程式,psurfacevalues范围周围一圈的面值
翻译不一定准确,最好还是从源码上看
gdbOF内还有调试图形界面,可能是最近推出来的,但个人还是建议使用gdb配合他们的宏,他们的宏确实是能减少好多使用时间
如果这图形界面做的和paraFoam似的,我宁可用matlab或python做后处理
第四章做了案例演示,gdbOF这个成果他们发表在了论文上,案例演示内容和论文基本一样
我感觉这样的案例演示恰恰是of缺少的,像matlab或fluent人家帮助文档都有案例演示,就连c++都有,of的数据结构这么复杂,每个类的创建或者函数的使用稍微配一个案例,简单说说即可,
你看查matlab帮助文档的有几个关心matlab函数重载啥样,有例子照虎画猫不更简单吗
但是很可惜,开源有利有弊,但绝不讨好任何人,
of门槛一下就上去了
案例中很常用pfvmatrixfull这个命令,可以着重去看下
pfindcell的具体使用方法如下:
(gdb)p findce11 0.05 0.45 0.05
RESULTS:
Nearest cell centroid cell number:400
Containing point cell number (-1=out):400
psurfacevalues的具体使用方法如下:
(gdb) psurfacevalues phir 400
internal Face:
$5 = 0
internal Face:
$6 = -0.0045
internal Face:
$7 = 0
empty Face
empty Face
boundary Face:
$8 = 0.0045
附录A展示了LDU分解的伪代码
for k : sizeDiag
A[k][k] = diag[k]
end for
for k : sizeAddr
i = lowerAddr[k]
j = upperAddr[k]
A[i][j] = upper[k]
A[j][i] = lower[k]
end for
附录B说明了volField (volScalarField, volVectorField or volTensorField),与对应的surfaceField区别
前者的内部区域场存储在体网格中心,后者存储在体网格交界面
比如说看下面这个伪代码,intFieldValue以及patchFieldValue的获取方式值得借鉴
l = myVolField.internalField.size_
i = 0
while(i<l)
intFieldValue = myVolField.internalField.v_[i]
//do something
i++
l = myVolField.boundaryField.ptrs_.size_
while(i<l)
patch = myVolField.boundaryField.ptrs_.v_[i]
l2 = patch.size_
j = 0
while(j<l2)
patchFieldValue = patch.v_[j]
//do something
j++
i++
附录C介绍了在面网格上的数据如何查询
大概意思是找到和查询面最近的点,然后用体的值估计,因为体的值和面的值相关
伪代码如下所示:(这里对patch面分别做了处理)
cellIndex = mesh.searchCellIndex(point)
for f : nFaces
fieldFaceValue = false
if isInternalFace(f)
if owner[f]==cellIndex || neighbour[f]==cellIndex
fieldFaceValue = field.internalField[f]
else
if owner[f]==cellIndex
patchIndex = whichPatch(f)
f_local = whichFace(f,patchIndex)
fieldFaceValue = field.boundaryField[patchIndex][f_local]
if(fieldFaceValue)
//do something with fieldFaceValue
end for
附录D是gdbOF命令行查询表,不一一展示了,有兴趣的查文档
有一说一,这些宏确实能提高开发效率
这要是能集成在code或vim插件里就更好了,
如果我这边做好了会在博客里分享下,
后续如果对ofgdb宏有更多自己的看法也会分享
本周塞尔维亚天王诺瓦克德约科维奇世界第一共计378周,超过格拉夫的377周,名副其实的世界第一,???
2023-02-27 21:08:22 星期一,写到这里记录一下当前时刻
每当处于逆境时,自己会选择看一些德约集锦或是穿上德约衣服球鞋拿着德约球拍奔赴球场
从2012年开始,粉了十年
论文致谢一定会有德约科维奇名字
逆境之王诺瓦克德约科维奇,在此表示祝贺
一起探索openfoam也是相当有趣的一件事,非常欢迎私信讨论
指正的价值要比打赏更重要,下面是个人联系方式,希望能结交到志同道合的朋友

几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
我怀念ipython的一件事是它有一个?为特定功能挖掘文档的运算符。我知道ruby有一个类似的命令行工具,但是我在irb中调用它非常不方便。ruby/irb有类似的东西吗? 最佳答案 Pry是IPython的Ruby版本,它支持?命令来查找有关方法的文档,但语法略有不同:pry(main)>?File.dirnameFrom:file.cinRubyCore(CMethod):Numberoflines:6visibility:publicsignature:dirname()Returnsallcomponentsofthef
写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c
TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是
我经常使用嵌套数据结构,很多时候我必须从控制台手动分析它们。问题是它们全部打印在一行中。是否有一种简单的方法可以根据{,[,],}和逗号重新构造数据结构的显示,使其看起来像Ruby的pretty_print输出? 最佳答案 :%s/\([{,]\)/\1\r/gggVG=:setft=ruby呜呜呜 关于ruby-如何将Vim中的"expand"文本转换成一种易于阅读的方式?,我们在StackOverflow上找到一个类似的问题: https://stacko
TCP是面向连接的协议,连接的建立和释放是每一次面向连接的通信中必不可少的过程。TCP连接的管理就是使连接的建立和释放都能正常地进行。三次握手TCP连接的建立—三次握手建立TCP连接①若主机A中运行了一个客户进程,当它需要主机B的服务时,就发起TCP连接请求,并在所发送的分段中用SYN=1表示连接请求,并产生一个随机发送序号x,如果连接成功,A将以x作为其发送序号的初始值:seq=x。主机B收到A的连接请求报文,就完成了第一次握手。客户端发送SYN=1表示连接请求客户端发送一个随机发送序号x,如果连接成功,A将以x作为其发送序号的初始值:seq=x②主机B如果同意建立连接,则向主机A发送确认报
软件特点部署后能通过浏览器查看线上日志。支持Linux、Windows服务器。采用随机读取的方式,支持大文件的读取。支持实时打印新增的日志(类终端)。支持日志搜索。使用手册基本页面配置路径配置日志所在的目录,配置后按回车键生效,下拉框选择日志名称。选择日志后点击生效,即可加载日志。windows路径E:\java\project\log-view\logslinux路径/usr/local/XX历史模式历史模式下,不会读取新增的日志。针对历史文件可以分页读取,配置分页大小、跳转。历史模式下,支持根据关键词搜索。目前搜索引擎使用的是jdk自带类库,搜索速度相对较低,优点是比较简单。2G日志全文搜
我正在使用Watir进行自动化,它会创建一封我需要检查的电子邮件。有人指出电子邮件gem是执行此操作的最简单方法。我添加了以下代码,并且能够从我的收件箱中收到第一封电子邮件。require'mail'require'openssl'Mail.defaultsdoretriever_method:pop3,:address=>"email.someemail.com",:port=>995,:user_name=>'domain/username',:password=>'pwd',:enable_ssl=>trueendputsMail.first我是这个论坛的新手,有以下问题:如何获