实时显示OpenSees模型节点位移

上次偶然发现OpenSees的recorder命令可以向TCP端口发送数据,并采用Python进行了监听,这次干脆直接获取模型的位移并将其图形实时的绘制出来。由于recorder的TCP传输不会影响OpenSees的计算效率,因此可以得到下图所示的效果:

实时显示OpenSees模型节点位移

实时显示OpenSees模型节点位移

由于TCP端口的监听是一个循环,因此必须要调用Python的子进程或者子线程模块进行监听。子进程和子线程最大的区别就是变量共享问题,子进程为独立的进程,因此存在自己的变量空间,需要考虑进程之间的通信,而子线程则是和主线程共享同一个变量空间,因此只需要设定一个全局变量就可以使得子线程的数据传输过来。另外要说明一下的是Python由于一些设计原因,使用子线程并不能实现并发,如果想要实现多核心运算,最好还是使用子进程技术。

下面绘制一下实时模型显示的流程:

实时显示OpenSees模型节点位移

在正式开始绘制之前,需要在OpenSees模型中增加下面的语句:

上面语句将recorder记录得到的504号节点三个自由度的信息发送至127.0.0.1:8099端口,更多详细信息见:使用TCP接收OpenSees的Recorder数据

首先定义全局变量和端口监听函数:

注意上面定义了两个全局变量,Data全局变量在每次接受数据之后会刷新并清空,因此不适合作为绘图时再次调用的变量,绘图时候会从TotalData里面读取数据。

下面定义OpenSees的子程序部分,用来在开启TCP监听之后直接调用OpenSees执行FILENAME:

这里直接使用了简单的check_output调用了opensees命令执行FILENAME。需要注意的是,我先前已经将OpenSees程序所在的文件夹添加到系统环境变量的PATH中去了,因此直接使用opensees就可以开启opensees分析了。后面调用Matplotlib进行绘图,这里采用的基本和之前的监控CPU差不多的形式,但是为了更加美观,我稍微调整了一下图像的刷新方式,图像的坐标轴会随着数据集的变化而变化:

首先说emitter这个生成器,这个生成器用作图像的frames,Matplotlib的frames可以使用迭代器和生成器作为参数,Matplotlib会依次从中获取frame传给图像更新函数。由于这里采用了生成器,因此图像是不会循环的,另外就是生成器会返回一个元组,用来表示新产生的数据,数据的来源就是TotalData的数据了。而updata这个图像更新函数,在每个interval都会调用这个函数,这个函数有一个参数就是当前的frame,当前的frame就是来自于frames的迭代器或者生成器的返回值。

在update函数中,实时的检测数据集的边缘是不是达到了坐标轴的边缘,如果到了,则从新更新坐标轴,并刷新图像。下面启动子线程和子程序并绘图:

这样就可以直接绘制出上面的动态图了,但是需要注意的就是我在启动OpenSees子程序的时候,使用time.sleep(3)让程序暂停了三秒钟,这是因为OpenSees自身还需要对tcl语言进行解析和执行,因此不暂停程序,则刚开始绘图函数无法从TotalData中获取数据,主程序会直接报错退出。除此之外,程序在运行过程中尽量在本机实现,联机测试可能会出现丢包现象,这个问题在上次已经讨论过了,就不在讨论了。

点击下载本文源代码:点击下载

本文隐藏内容 登陆 后才可以浏览

2条评论

  1. 华坤   •  

    请教下,怎么这么强?

  2. 我欲乘风   •  

    小天才

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注


Are you human? Click the Banana...