雷金勇,李 鹏,于学军,张君泉,王成山
(1.南方电网科学研究院,广州 510080;2.天津大学智能电网教育部重点实验室,天津 300072;3.积成电子股份有限公司,济南 250100)
电力系统数字仿真发展至今,已有多种广泛应用于分布式发电系统及微网相关领域研究的数字仿真程序,包括Matlab/SimPowerSystems、DIgSILENT及PSCAD/EMTDC等[1,2],但这些国外的商业仿真计算工具的核心模型与算法等内容基本上不对用户开放,借助其实现相关的仿真计算可能并不困难,但如果需要进一步研究开发准确、高效的仿真算法则不大可能。因此,国内天津大学开发了具有自主知识产权的分布式发电微网系统暂态仿真程序TSDG(transient simulator of distributed generation systems and micro-grid),它不仅能够为分布式发电及微网系统的规划、设计、运行、实验及科学研究提供坚实的理论基础与依据,同时也能够提高我国在电力系统仿真软件开发、设计与应用领域的核心技术竞争力[3,4]。
分布式发电微网系统暂态仿真程序的设计开发是一项复杂的系统工程,其中最重要的是需要应对多种功能需求的变化,具体包括:①元件模型方面,与传统电力系统成熟可靠的元件模型相比,分布式发电系统元件不但种类繁多,而且很多分布式电源的模型尚在不断完善与发展之中,这就要求TSDG能够应对分布式发电微网系统模型增加和变化的要求;②系统算法方面,分布式发电微网系统各动态过程的时间常数差异较大,整个系统是一个典型的强刚性系统,电力电子开关器件动作时序的不确定性以及分布式电源和控制系统引入的大量非线性环节对程序的计算精度和数值稳定性提出了较高要求,需要采用高效准确灵活的解算方法,但仿真算法总是在不断改进中,而且随着分布式发电微网系统的发展,对TSDG的功能需求也会发生变化,这就要求TSDG能够应对暂态仿真算法和功能需求变化的要求;③用户接口方面,输入和输出数据形式的多样化,多种仿真程序的交互混合仿真等已经成为一种趋势,这就要求TSDG能够应对未来用户接口变化的要求。
传统的面向过程程序设计是面向功能的,通常使用函数或过程来实现所需要的功能,这种方式不利于大中型软件的开发与维护。面向对象的程序设计方法通过创建对象来简化程序设计过程,允许抽象化、模块化的分层结构,具有多态性、继承性和封装性的特点。面向对象设计原则在基于面向对象方法的软件系统的开发过程中起着重要的指导作用,它是各种设计模式背后的基本思想原则,遵守设计原则能够提高软件的可维护性和可复用性。
面向对象设计OOD(object oriented design)的核心思想主要包括:①针对接口编程,而不是针对实现编程,极大地减少了子系统之间的相互依赖关系;②优先使用对象组合,而不是类继承,使得设计更加灵活;③封装变化点,降低了对系统的整体影响。在此基础上可以得出几条具体的设计原则[5~7]:开放封闭原则、里氏代换原则、依赖倒置原则、接口隔离原则等,采用这些设计原则可提高软件系统的可维护性和可复用性。
作为面向对象设计的实现手段,设计模式是指软件开发过程中对重复出现问题的可重用性解决方案[8]。设计模式总结了面向对象软件开发中的设计经验,描述了软件开发过程中不断重复出现的问题及该问题的解决方案,目的就是使软件开发者可以更加简单方便地复用成功的设计和体系结构。
设计模式依据其目的可分为创建型、结构型、行为型三种[9]。创建型模式抽象了实例化过程,使一个系统独立于创建、组合和表示构成这个系统的对象,包括抽象工厂模式等;结构型模式处理类与对象的组合,从而获得更大的结构,包括组合模式等;行为型模式描述类与对象之间的交互以及职责分配,涉及算法和对象之间责任的划分,它不仅描述了对象或类的模式,还描述了它们之间的通信模式,包括观察者模式等。虽然不同设计模式的设计思想有所不同,但它们并非是孤立的,而是常常组合在一起,共同完成系统的设计。
设计模式展示了面向对象思想中封装、继承和多态等特性的使用,正确地理解与使用设计模式,有助于快速开发出可维护和可复用的系统。虽然设计模式有许多优点,但是仍然需要程序设计者深入理解设计模式背后的面向对象思想,才能够更好地去使用它们,真正地发挥它们的优势,同时设计者应该避免滥用所带来的软件结构的复杂和冗余,不能为了使用设计模式而使用。
分布式发电微网系统暂态仿真程序框架如图1所示,主要由4部分组成。
(1)系统数据,包括系统参数和仿真结果两部分,前者应提供仿真步长、仿真时间、输出采样间隔等参数,以及元件的基本信息、拓扑连接关系、元件基本参数、数据输出控制参数四部分,后者包括系统要求输出的仿真结果,如电压、电流及控制系统输出等信息。
(2)元件模型,它主要包括分布式电源、网络元件、电力电子变流装置、控制器等模型。
(3)系统解算,它主要是对分布式发电微网系统暂态仿真算法的实现,从系统层面看,它包括电气系统与控制系统的交替求解,电气系统解算侧重于含电力电子设备的以伏安关系描述电气网络的求解,控制系统解算则侧重于强非线性的以输入输出关系描述的控制器及分布式电源模型的精确求解。
(4)用户接口,可以根据不同的数据格式提供灵活和可扩展的数据处理和输出显示功能。
图1 分布式发电微网系统暂态仿真程序框架Fig.1 Framework of TSDG
在TSDG的开发实现过程中,建立元件模型方面,一般采用创建型模式来管理种类繁多的分布式发电微网系统元件模型;在系统算法实现方面,行为型模式提供了多种灵活的算法选择;在用户接口设计方面,结构型模式对多样的接口进行了抽象统一,避免了接口的不一致性。
TSDG基于面向对象设计思想,广泛采用了设计模式理论,限于篇幅,文中仅以其中四种设计模式的应用举例进行说明,分别是工厂方法模式、适配器模式、策略模式和单例模式。在TSDG的构建过程中,利用工厂方法模式提高元件建模的灵活性,利用适配器模式实现稀疏算法库的复用,利用策略模式减少程序模块间的耦合,利用单例模式优化和共享资源访问。
工厂方法模式的意图是定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到其子类。在工厂方法模式中,核心的抽象工厂类不会负责所有产品的创建,仅负责给出具体工厂类必须实现的接口,具体产品的创建由具体工厂类去实现。因此,系统在加入新的产品时就不需要修改抽象工厂类和具体工厂类,只需要增加与新产品相应的具体工厂类即可。工厂类与产品类往往具有平行的对等结构,它们之间一一对应。
与传统电力系统成熟稳定的元件模型相比,分布式发电微网系统不但元件模型种类繁多,而且很多分布式电源的模型尚在不断完善与发展之中。随着分布式发电微网系统研究的深入,需要不断地对元件模型库进行增加或者修改。传统的软件开发方法需要修改原有的创建具体元件类的实现部分,使得实例的创建不灵活,而且由于其在开放扩展的同时也开放了其他无关元件模型的修改,违背了开放-封闭原则。工厂方法模式则是定义一个用于创建对象的接口,让子类决定需要实例化的类,所以工厂方法模式可较好地解决这个问题。
图2给出了基于工厂方法模式的元件对象创建实现方法,主要包括四个部分,分别为抽象工厂,具体工厂,抽象产品和具体产品。抽象工厂类AbstractFactory定义了创建各种元件对象行为的接口,通过该接口可以实现具体产品;Transformer Factory类、BranchRLCFactory类和DiodeFactory类等为具体工厂,在具体工厂中,工厂方法CreateElement对具体元件的创建进行了定义与实现,返回一个ElectricalSystem类型的对象实例。ElectricalElement类是工厂模式所创建产品的基类。由于具体工厂返回的是抽象产品的实例,从而屏蔽了接口的不同实现所造成的用户逻辑对具体类访问所造成的差异。在具体的应用中,增加或者修改元件库模型时,软件开发人员只需要而且只允许增加或修改相应元件模型的具体工厂和具体产品,无法修改其他元件模型,不但遵守了开放-封闭原则,又保持了封装元件对象创建过程的优点。
图2 基于工厂方法模式的元件对象创建实现Fig.2 Implementation of element object creation based on factory method pattern
在TSDG中,除了元件对象模型的创建之外,算例参数输入和仿真结果输出也采用了工厂方法模式。TSDG兼容两种算例参数和输出结果的存储形式:Mysql数据库和自定义数据文件。这两种形式的数据具有相同的行为,包括数据的存储、查询、修改等,但是两者的结构和访问方式完全不同,前者需使用数据库接口,后者需使用文件流接口,在接口实现上存在较大差异。TSDG采用工厂方法模式定义了统一的抽象接口集,包括数据库连接(文件打开)、数据存储、查询、修改等一系列行为,并在该抽象接口集的基础上实现了用于Mysql数据库和自定义数据文件格式的具体实现。在具体的应用中,无需指定数据形式的子类,只需创建父类即可得到一系列该父类所管理的数据形式实现,使上层应用独立于数据形式的变化。
工厂方法模式通常可以看作是创建对象(实例化)的替代品,任何需要生成对象的场景都可以使用,但是要在复杂度与便捷之间权衡,另外在需要灵活的、可扩展的框架时,也可以考虑采用该模式。
工厂方法模式具有如下优点:1)良好的封装性,代码结构清晰;2)很强的可扩展性;3)降低了程序的耦合性。
适配器模式的意图是将一个类的接口转换成客户希望的另外一个接口,使得接口不兼容的多个类可以一起工作。
软件开发过程中总是希望复用一些现成的类,已存在类的功能可能符合系统的设计要求,但是它们的接口却和当前的系统不匹配造成不能复用。一般的做法是逐个修改这些类的接口,这也是一件很繁琐的工作。适配器模式能够从软件结构的设计上解决这个问题。适配器模式可以提供一个接口,直接将现有的模块加入到新的仿真软件中去,加快软件开发进度。
TSDG需要高效可靠的稀疏算法库,从软件工程的角度来看,自主重新开发一套稀疏算法库是不现实的,降低了软件代码重用和开发效率,通常的做法是尽可能利用现有成熟的稀疏算法库。开源免费的Sparse库[10]能够实现对线性稀疏方程组的求解,具有较强的实用性,但其接口却和TSDG不一致。因此在TSDG的实现过程中采用适配器模式将Sparse库的接口转换为适合TSDG的接口,实现了Sparse库的复用,这不但大大加快了程序的开发进度,增加了仿真软件的通用性和可维护性,也为以后采用其他更为高效的第三方稀疏算法库[11~14]替换Sparse库提供了便捷,提高了程序的可维护性。
图3给出了基于适配器模式的稀疏算法库实现,Target类定义了TSDG所用的接口,Sparse Lib类是已经存在的稀疏算法库,可以是Sparse库,也可以是其他第三方稀疏算法库,该库实现了稀疏算法的相关功能,但是其接口与TSDG不匹配,利用Sparse类将Sparse Lib和Target接口进行匹配。通过使用适配器模式,在基本不改变原有代码的基础上,通过Sparse类调用Sparse Lib中的相应接口来实现稀疏算法的功能,实现了原先并不兼容的Sparse Lib类的复用。
图3 基于适配器模式的稀疏算法实现Fig.3 Implementation of sparse algorithm based on adapter pattern
适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况,优点是提高了类的可复用性。但是适配器模式的主要场景是扩展应用,所以在开发阶段不要考虑适配器模式,在该阶段通常采用外观模式。
策略模式是一种对象行为型模式,它定义了一系列的算法,并将它们分别封装成类,让它们之间可以相互替换,使得算法可以独立于客户而变化,非常适用于具有算法分支选择情况的实例。
针对不同的应用场合,分布式发电微网系统暂态仿真的要求也不尽相同,需要在仿真精度和速度上有所侧重,使得暂态仿真程序通常含有多种算法。如果将多种算法以行为方式和数据状态静态地封装在一起,不仅使解算类变得庞大复杂,也不利于算法类的修改和替换。考虑到这些具体的算法类具有同样的接口,仅是在方法的具体实现上存在差异,因此TSDG采用策略模式将电气系统数据和算法分离,并将各个算法逐个封装,使各个算法之间可以相互切换,实现算法与算法之间、算法和数据之间的解耦。
图4给出了基于策略模式的电气系统算法实现,Sim Algorithm为抽象类,提供了各种算法的统一接口,所有具体算法都从该接口派生,Context类使用这个接口来调用具体的电气系统解算算法,而Trapezoid、Backward Euler和Mixed类实现了具体的算法,分别是梯形积分法,后向欧拉法和梯形法和后向欧拉法的混合算法。使用策略模式后,TSDG将大部分算法统一在同一框架下,只需针对接口Electrical Algorithm进行开发,通过算法与数据的分离机制,提高了算法复用程度,便于算法的移植,可用于其他电力系统仿真程序的开发。在具体的应用中,由于具体的算法类都是从接口Electrical Algorithm派生的,根据多态机制,只要修改变类名就可以完成电气系统解算算法的更换,无需大量代码的更改。显然,通过使用策略模式大大提高了程序的灵活性。
图4 基于策略模式的电气系统算法实现Fig.4 Implementation of electrical system algorithm based on strategy pattern
策略模式通常应用于以下场景:①多个类的区别仅为表现行为不同,运用策略模式在运行时动态地选择具体行为;②需要在不同情况下使用不同的算法;③对客户隐藏具体算法的实现细节,彼此完全独立对于策略模式来说,主要有如下优点:①避免程序中使用多重条件转移语句,提高了系统灵活性和扩展能力;②提供了一种替代继承的方法,比继承更灵活;③增加对象内聚性、降低程序耦合性。
但是需要强调的是,虽然策略模式非常有效,但不应该滥用,因为数据和算法的分离引发的相互调用会影响程序的执行性能。
单例模式的意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点。对一些类来说,只有一个实例是很重要的。单例模式让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。单例模式比较简单,经常用于对系统资源的控制,有时也会作为一种通信媒介,在不建立直接关联的条件下让不相关的两个程序进行通信,尤其是多线程。
仿真程序通常需要具备同时仿真多个系统的能力,系统解算器是独立于系统存在的,对于多个系统来说,如果每个系统都实例化一个解算器,这就造成资源的浪费,所以TSDG中系统解算器采用了单例模式,由解算器类自己负责实例化,并且保证实例唯一,单个的解算器可以同时对多个系统进行解算。
在分布式发电系统暂态仿真软件中,将整个暂态仿真系统定义为一个SimSystem类,该类是分布式发电系统暂态仿真中的主类,负责软件中各个类的协调,因此,其实例应该是唯一的,为了保证只有一个SimSystem的实例存在,TSDG使用了单例模式。
图5 基于单例模式的系统解算器实现Fig.5 Implementation of system solver based on singleton pattern
图5给出了基于单例模式的系统解算器实现,SimSystem类是TSDG中的主类,实现系统仿真功能,在具体的应用中,SimSystem类定义一个GetInstance静态方法,以及一个静态属性,类型为SimSystem类的实例。GetInstance方法创建了SimSystem的唯一实例,可以严格地控制客户对其的访问。
单例模式使得整个软件运行过程中都只有一个实例,减少了内存和系统的开销,并且可以在系统设置一个全局的访问点,优化和共享资源访问,但是单例模式没有接口,很难扩展,违背了开放原则。
分布式发电微网系统暂态过程的研究需要相应仿真计算工具的支持。分布式发电微网系统暂态仿真程序TSDG的开发不仅是对传统电力系统电磁暂态仿真程序应用范围的拓展,同时也引入了很多新技术实现复杂非线性系统的准确、快速仿真。基于现代软件架构和标准C++程序设计语言开发的TSDG更好地支持了面向对象思想与设计模式,这是基于Fortran语言开发的EMTP等程序所不能比拟的。与传统电力系统仿真程序的开发不同,当前已具有许多成熟的开源的算法库,程序开发人员可以充分利用这些基础条件,减少软件开发的工作量,并更专注于专业软件本身的开发,此时需要清晰明确的程序接口。同时,对于分布式发电微网系统稳定性仿真与潮流计算等其他功能的仿真计算程序,而这些程序从仿真计算功能到基础计算资源的需求与TSDG是非常接近的,在一些情况下,TSDG甚至可能需要与稳定性仿真或潮流计算程序交换数据与信息,这都使得暂态仿真程序的架构设计尤为重要。此时,面向对象设计模式为上述问题的解决提供了有效的方法。
本文以工厂方法模式、适配器模式、策略模式和单例模式为例描述了面向对象设计模式在分布式发电微网系统暂态仿真程序TSDG中的应用。TSDG的开发实现基于面向对象的设计思想,广泛采用设计模式理论,实现了模块间的低耦合和模块内部的高内聚,提高了程序的可维护性和可复用性,能够应对功能需求的变化。TSDG中多种设计模式的应用和集成方法具有一定的通用性,可作为其他电力系统仿真软件开发的参考。
[1] Brooks N,Baldwin T,Brinson T,et al.Analysis of fuel cell based power systems using EMTDC electrical power simulator[C]∥The 36th Southeastern Symposium on System Theory.Atlanta,USA:2004.
[2] 郭力,王成山(Guo Li,Wang Chengshan).含多种分布式电源的微网动态仿真(Dynamical simulation on microgrid with different types of distributed generations)[J].电力系统自动化(Automation of Electric Power Systems),2009,33(2):82-86.
[3] 李鹏(Li Peng).分布式发电供能微网系统暂态仿真方法研究(Research on the Transient Simulation Methodology of Micro-grid Powered by Distributed Energy Resources)[D].天津:天津大学电气与自动化工程学院(Tianjin:School of Electrical Engineering and Automation,Tianjin University),2010.
[4] 王成山,李鹏,王立伟(Wang Chengshan,Li Peng,Wang Liwei).配电系统电磁暂态仿真算法分析(A-nalysis of electromagnetic transients simulation algorithm for distribution systems)[J].电力系统及其自动化学报(Proceedings of the CSU-EPSA),2008,20(6):1-5.
[5] Bob T.Some object-oriented design principles[EB/OL].http://userpages.umbc.edu/~tarr/dp/lectures/OOPrinciples.pdf,2010.
[6] Martin R C.Design principles and design patterns[EB/OL].http://www.objectmentor.com,2000.
[7] Prieto-Diaz R.Status report:Software reusability[J].IEEE Software,1993,10(3):61-66.
[8] Di Felice P.Reusability of mathematical software:A contribution[J].IEEE Trans on Software Engineering,1993,19(8):835-843.
[9] Zhou E Z.Object-oriented programming,C++and power system simulation[J].IEEE Trans on Power Systems,1996,11(1):206-215.
[10]Kundert K S.Sparse 1.3-A sparse linear equation solver[EB/OL].http://www.netlib.org/sparse/,1986.
[11]Demmel J W,Gilbert J R,Li X S.Super LU users'guide[EB/OL].http://crd.lbl.gov/~xiaoye/Super LU/,2009.
[12]Intel Corporation.Intel math kernal library for windows OS users'guide[EB/OL].http://www.intel.com/software/products/,2009.
[13]Tim D.SuiteSparse/UMFPACK[EB/OL].http://www.cise.ufl.edu/research/sparse/umfpack/,2011.
[14]Tim D.SuiteSparse/KLU[EB/OL].http://www.cise.ufl.edu/research/sparse/klu/,2011.