singleton
(剖面等值线)
在三维有限元后处理软件中,客户常常会要求这样一个功能:查看三维实体的剖面等值线。例如,在高温炼炉的温度场分析中,工程师常常会关心炉内腔至炉外壁的温度变化趋势;在水坝应力分析中,设计师常常会关心断面上的局部破坏位置…..
具体来讲就是指,用户在后处理结果时,常需要一个参数输入框,用户通过输入框输入指定的平面参数,程序自动用该平面切割当前实体模型,绘制出断面上相关物理场(位移、应力等)的等值线。
针对此问题,一般软件设计时,首先会想到要建立一个平面等值线类,该类负责存储剖面的网格数据、等值线数据,以及的等值线计算、绘制等等功能。那么,初步的等值线类就设计出来了,如下:
class CContour2D
{
public:
CContour2D();
virtual ~CContour2D();
void Init();
void Calculate();
void Draw();
……
void Destory();
public:
vector<_P> m_vP; //节点向量
vector<_E> m_vE; //单元向量
public:
……
};
(单元向量中只需要能保存三角形单元和四边形单元即可,因为计算实体剖面的同时,可直接将剖面离散为三角形和四边形的网格,并算出节点的物理值。)
随后,添加剖面等值线绘制输入框,根据用户需要自动生成剖面等值线类的对象,绘制等值线。
但是这样就产生一个问题:任意时刻只需要绘制一个剖面图,即查看一个新的断面的时候,上一断面的等值线图自然消除。即,在任一时刻只需要等值线类的一个对象存在,多了就浪费存储空间。如何解决该问题呢?
singleton模式即可解决该问题,查看《设计模式:可复用的面向对象软件的基础》,singleton模式介绍如下:
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。(Ensure a class has only one instance, and provide a global point of access to it. )
结构:
(Problem:Application needs one, and only one, instance of an object. Additionally, lazy initialization and global access are necessary. )
适用性:
1. 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
2. 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
保证一个类仅有一个实例,并提供一个全局访问点访问它,该模式正好迎刃而解我们之前提出的问题。于是,构造全局函数如下:
CContour2D& Con2D()
{
Static CContour2D _Cf;
Return _Cf;
};
那么,调用时只需要执行Con2D()命令即可获得剖面等值线对象的全局访问点。例如: Con2D().Init(初始参数);这样,就轻松避免了容易产生多个不必要对象的问题。
到此,有经验的程序员立刻会想到,等值线实例一旦生成就不可能销毁了,但是何时执行Destory();函数呢?因为在有限元分析的过程中,分析师可能会在分析完一个工程后,又继续计算下一个工程,或者在分析过程中根本就没有使用该功能。这时候如果盲目销毁,必然会导致程序出错。好的解决方法是,在有限元域类Domain析构函数中调用Con2D(). Destory();函数,这样就保证了一个工程最多只可能存在一个剖面等值线实例。关闭工程时,由等值线实例开辟的多余空间随即销毁。
将上述解决方案应用在本人曾开发的某后处理软件中,图片如下:
(DamContour软件)某重力坝剖面等值线
评论