郝向軍,趙 軍,李勝文,侯采彤,李 祺
(1.國(guó)網(wǎng)山西省電力公司,山西 太原 030013;2.國(guó)網(wǎng)山西省電力公司電力科學(xué)研究院,山西 太原 030001;3.國(guó)網(wǎng)山西送變電工程有限公司,山西 太原 030001;4.國(guó)網(wǎng)山西省電力公司輸電檢修分公司,山西 太原 030001)
目前,配電系統(tǒng)的可靠性評(píng)估手段主要有解析法和模擬法,關(guān)于可靠性評(píng)估方法的論述,大多都是理論方法結(jié)合算例分析,而在實(shí)際工程應(yīng)用中,還需要另外一步工作,即可靠性評(píng)估軟件開(kāi)發(fā)。本文使用的軟件編譯平臺(tái)是VS(Visual Studio),VS 是一個(gè)相當(dāng)全面的開(kāi)發(fā)工具集,包括了整個(gè)軟件生命周期中所需要的大部分工具,整個(gè)軟件用C++進(jìn)行編譯。無(wú)論是什么樣的軟件開(kāi)發(fā),在編譯之前都要有一個(gè)整體的架構(gòu)觀,具體到本文介紹的可靠性評(píng)估軟件,在設(shè)計(jì)階段,規(guī)劃了3 個(gè)模塊,包括數(shù)據(jù)庫(kù)模塊、直流潮流模塊以及可靠性評(píng)估模塊。下面將依次介紹這3 個(gè)模塊的設(shè)計(jì)理念及其編譯、功能實(shí)現(xiàn)的過(guò)程。
在一個(gè)復(fù)雜直流配用電系統(tǒng)的可靠性評(píng)估過(guò)程中涉及大量的數(shù)據(jù)存取,而在主函數(shù)中去定義、輸入數(shù)據(jù),會(huì)使得函數(shù)主體冗雜,降低編程的可讀性,不利于后期程序的維護(hù),所以在進(jìn)行主函數(shù)的編譯之前,建立一個(gè)數(shù)據(jù)庫(kù)模塊,主要承擔(dān)數(shù)據(jù)的輸入、輸出功能,主函數(shù)部分需要的數(shù)據(jù)可以直接從數(shù)據(jù)庫(kù)模塊獲取,這樣就可以使得函數(shù)主體更加明確。
數(shù)據(jù)庫(kù)模塊的建立,考慮使用C++中類(lèi)的功能來(lái)實(shí)現(xiàn)。類(lèi)在本質(zhì)上也屬于數(shù)據(jù)類(lèi)型,只不過(guò)不是編譯器內(nèi)置的數(shù)據(jù)類(lèi)型,是用戶根據(jù)自己需要的功能,自定義的一種數(shù)據(jù)類(lèi)型。類(lèi)用于指定對(duì)象的形式,它包含了數(shù)據(jù)表示法和用于處理數(shù)據(jù)的方法。對(duì)于包含內(nèi)容較多的類(lèi),一般會(huì)考慮分文件編寫(xiě),即在頭文件中定義一個(gè)類(lèi),在類(lèi)中定義所需要的對(duì)象,具體的實(shí)現(xiàn)轉(zhuǎn)到相應(yīng)的源文件中進(jìn)行。分文件編寫(xiě)是為了讓類(lèi)中實(shí)現(xiàn)的功能可以更加清晰地展現(xiàn)出來(lái),既方便程序員檢查自己的程序,進(jìn)行修改和維護(hù),又可以使讀者更加直觀地理解編程的功能。本文所介紹的可靠性評(píng)估軟件,其數(shù)據(jù)庫(kù)模塊的類(lèi)里包含諸多函數(shù)作為對(duì)象,下面將依次介紹類(lèi)中的對(duì)象定義以及各個(gè)函數(shù)的功能、實(shí)現(xiàn)過(guò)程。
先在頭文件中定義一個(gè)類(lèi),在該類(lèi)的public 作用域下,定義幾個(gè)非函數(shù)型對(duì)象,分別是網(wǎng)絡(luò)中的設(shè)備個(gè)數(shù)、網(wǎng)絡(luò)中的節(jié)點(diǎn)數(shù),將這些數(shù)據(jù)作為原始數(shù)據(jù)進(jìn)行輸入。然后需要定義一些指針,指針的作用是維護(hù)數(shù)組,該軟件需要開(kāi)辟存儲(chǔ)故障率(包括設(shè)備故障率和線路故障率) 的數(shù)組、存儲(chǔ)平均故障持續(xù)時(shí)間的數(shù)組以及存儲(chǔ)年平均故障持續(xù)時(shí)間的數(shù)組,數(shù)據(jù)類(lèi)型為double 類(lèi)型,所以開(kāi)辟的數(shù)組也是double 類(lèi)型的數(shù)組,相應(yīng)地,維護(hù)數(shù)組的指針也是double 類(lèi)型的指針。
首先介紹類(lèi)中必不可少的構(gòu)造函數(shù)。該軟件需要用戶自己聲明有參構(gòu)造函數(shù),因?yàn)樾枰獙?duì)整型數(shù)據(jù)以及數(shù)組做初始化的操作。有參構(gòu)造中的參數(shù)即為網(wǎng)絡(luò)中的設(shè)備個(gè)數(shù)以及節(jié)點(diǎn)數(shù),將傳入的參數(shù)賦值給類(lèi)中定義的整型對(duì)象。1.1 節(jié)提到的幾個(gè)數(shù)組,需開(kāi)辟在堆區(qū),在堆區(qū)開(kāi)辟的空間由程序員手動(dòng)開(kāi)辟、手動(dòng)釋放,維護(hù)數(shù)據(jù)比較方便,而數(shù)組的長(zhǎng)度即為有參構(gòu)造中傳入的節(jié)點(diǎn)數(shù)。
下一個(gè)函數(shù)的功能是獲取文件中的原始數(shù)據(jù),這個(gè)文件一般由實(shí)際工程方提供,編程需要讀取該文件來(lái)獲得所需要的原始數(shù)據(jù),讀取的方法一般按行讀取,以空格為分隔符,把軟件編程所需要的原始數(shù)據(jù)讀取完畢,存放到由指針維護(hù)的對(duì)應(yīng)數(shù)組中即可。
C++運(yùn)行完畢后,在堆區(qū)開(kāi)辟的數(shù)組中的數(shù)據(jù)會(huì)被釋放掉,軟件計(jì)算得到的數(shù)據(jù)就會(huì)消失,所以需要在堆區(qū)數(shù)組釋放之前,將計(jì)算得到的數(shù)據(jù)由數(shù)組輸入文件中保存,該操作需要用到C++中的寫(xiě)文件函數(shù),無(wú)論是文字信息還是數(shù)字信息,都可以通過(guò)C++的輸出流函數(shù),由左移運(yùn)算符寫(xiě)入到文件中,這樣軟件計(jì)算得出的數(shù)據(jù)就可以永久地保存。
當(dāng)所需原始數(shù)據(jù)或是計(jì)算得到的各項(xiàng)指標(biāo)輸入到數(shù)組以后,還需要提供1 個(gè)可以查看數(shù)組中數(shù)據(jù)的函數(shù):使用while 語(yǔ)句生成1 個(gè)菜單,顯示用戶能夠查看的數(shù)據(jù)種類(lèi)并按順序進(jìn)行編號(hào),然后使用switch 語(yǔ)句,將對(duì)應(yīng)編號(hào)的數(shù)組進(jìn)行遍歷,供用戶查詢(xún),方便用戶查看輸入的原始數(shù)據(jù)是否正確,判斷是否需要修正代碼。
最后需要編譯析構(gòu)函數(shù),上文曾提及,在堆區(qū)開(kāi)辟的數(shù)組需要程序員手動(dòng)釋放,釋放的代碼就可以放在析構(gòu)函數(shù)中。
直流潮流模塊依然采用C++中類(lèi)與對(duì)象的功能進(jìn)行實(shí)現(xiàn)。首先要明確類(lèi)中的非函數(shù)型對(duì)象,在該模塊中需要定義整型數(shù)據(jù),如網(wǎng)絡(luò)中的節(jié)點(diǎn)數(shù)、支路數(shù)以及平衡節(jié)點(diǎn)的編號(hào),需要在堆區(qū)開(kāi)辟double 型和int 型的數(shù)組,其中屬于double 型的數(shù)組有存放各節(jié)點(diǎn)注入功率的數(shù)組、存放各條支路阻抗值的數(shù)組、存放各條支路潮流的數(shù)組,屬于int 型的數(shù)組有存放發(fā)生停電故障的節(jié)點(diǎn)編號(hào)的數(shù)組、存放支路編號(hào)的數(shù)組等。
在有參構(gòu)造函數(shù)中,需要傳入網(wǎng)絡(luò)中的節(jié)點(diǎn)數(shù)、支路數(shù)、平衡節(jié)點(diǎn)的編號(hào),來(lái)給類(lèi)中的非函數(shù)型對(duì)象賦初值,數(shù)組的開(kāi)辟仍然選擇在堆區(qū),用對(duì)應(yīng)數(shù)據(jù)類(lèi)型的指針進(jìn)行維護(hù),數(shù)組的長(zhǎng)度可以用網(wǎng)絡(luò)中的節(jié)點(diǎn)數(shù)、支路數(shù)等數(shù)據(jù)進(jìn)行定義。在構(gòu)造函數(shù)中將原始數(shù)據(jù)存放到對(duì)應(yīng)數(shù)組中,包括各個(gè)節(jié)點(diǎn)的注入功率、各條支路的阻抗值。
計(jì)算系統(tǒng)在正常運(yùn)行狀態(tài)下的潮流分布情況,需要在類(lèi)中定義一個(gè)函數(shù)。潮流計(jì)算函數(shù)涉及很多矩陣方面的計(jì)算,需要用到C++的矩陣庫(kù)Eigen。Eigen 是一個(gè)基于C++模板的線性代數(shù)庫(kù),其接口清晰、運(yùn)行穩(wěn)定且效率較高,直接將庫(kù)下載后放在項(xiàng)目目錄下,包含頭文件就能使用。計(jì)算系統(tǒng)的潮流分布,首先需要定義一個(gè)行數(shù)為系統(tǒng)的支路數(shù),列數(shù)為4 的矩陣,該矩陣第一、二列存放支路的首、末節(jié)點(diǎn)編號(hào),第三列存放各支路的電納值,第四列存放各節(jié)點(diǎn)的相角,其中前三列的數(shù)據(jù)可以直接輸入,第四列的數(shù)據(jù)需要經(jīng)過(guò)計(jì)算進(jìn)行賦值[1]。接下來(lái)生成系統(tǒng)的節(jié)點(diǎn)電納矩陣,該矩陣的賦值分為兩部分,第一部分為主對(duì)角線元素的賦值,位于主對(duì)角線上的元素,在數(shù)值上等于各個(gè)節(jié)點(diǎn)的自電納;第二部分為非對(duì)角元素的賦值,由于節(jié)點(diǎn)電納矩陣為對(duì)稱(chēng)稀疏矩陣,只對(duì)矩陣的上三角或是下三角部分賦值即可。該位置上的元素,在數(shù)值上等于節(jié)點(diǎn)之間的互電納[2]。這兩部分的賦值操作,使用for 循環(huán)語(yǔ)句,借助之前定義的支路信息矩陣便可實(shí)現(xiàn)。
接下來(lái)需要借助節(jié)點(diǎn)電納矩陣,求取各節(jié)點(diǎn)的相角,計(jì)算公式為
其中,P 為各節(jié)點(diǎn)注入功率的列向量,B0為節(jié)點(diǎn)電納矩陣;δ 為各節(jié)點(diǎn)相角的列向量[3]。
為求取各節(jié)點(diǎn)的相角,需要求取節(jié)點(diǎn)電納矩陣的逆矩陣。在Eigen 庫(kù)中,有專(zhuān)門(mén)求取逆矩陣的函數(shù)inverse(),求出的相角對(duì)應(yīng)存放入上文定義的支路信息矩陣中。最后一步就是計(jì)算各條支路的潮流分布,計(jì)算公式為
其中,i、j 表示首、末節(jié)點(diǎn)的編號(hào);P、x 是由首末節(jié)點(diǎn)確定的支路潮流、支路阻抗;δ 為各節(jié)點(diǎn)的相角[4]。
將支路信息矩陣中的相角信息和支路信息帶入式(2) 中,就可以依次求出各條支路的潮流分布。
利用枚舉法使系統(tǒng)中的線路依次斷開(kāi)一條,求對(duì)應(yīng)狀態(tài)下的系統(tǒng)潮流分布[5]。該部分編程的目的是確定節(jié)點(diǎn)的故障信息。先要尋找出系統(tǒng)中與其他部分只有1 條支路連通的特殊節(jié)點(diǎn),這些節(jié)點(diǎn)所在支路如果斷開(kāi),會(huì)導(dǎo)致節(jié)點(diǎn)電納矩陣降階,必須做特殊處理。然后利用for 循環(huán),遍歷支路信息矩陣的前兩列,只出現(xiàn)一次的節(jié)點(diǎn),即為特殊節(jié)點(diǎn),將該節(jié)點(diǎn)的編號(hào)以及所在支路編號(hào)存放進(jìn)相應(yīng)的數(shù)組中;出現(xiàn)多次的節(jié)點(diǎn),說(shuō)明所在支路不止1 條,斷開(kāi)1 條支路并不會(huì)導(dǎo)致節(jié)點(diǎn)電納矩陣降維,正常處理即可。正常節(jié)點(diǎn)所在支路斷路,需重新生成支路信息矩陣,其中斷路的支路,電納置為零,然后按正常狀態(tài)下系統(tǒng)潮流計(jì)算的步驟進(jìn)行即可;特殊節(jié)點(diǎn)所在支路斷路,也需重新生成支路信息矩陣,因節(jié)點(diǎn)電納矩陣要降一維,所以該支路信息矩陣也要減少1 行,將斷路支路的信息刪除,相應(yīng)地,存放各節(jié)點(diǎn)注入功率的列向量以及存放各支路相角的列向量,也要把對(duì)應(yīng)節(jié)點(diǎn)的信息刪除[6]。
編程中潮流計(jì)算的目的是為了確定節(jié)點(diǎn)故障信息,具體通過(guò)追蹤平衡節(jié)點(diǎn)發(fā)出的功率來(lái)實(shí)現(xiàn)。平衡節(jié)點(diǎn)本質(zhì)上是負(fù)荷節(jié)點(diǎn),不存在功率輸出,而在潮流計(jì)算過(guò)程中,通常需要平衡節(jié)點(diǎn)向系統(tǒng)中輸入功率,這一部分輸入功率就可以看作系統(tǒng)中缺乏的功率,這些功率輸入到哪些節(jié)點(diǎn),就說(shuō)明哪些節(jié)點(diǎn)會(huì)因?yàn)閷?shí)際功率供給不足而停電。
先要建立輔助矩陣存放各條支路的潮流信息,矩陣的階數(shù)和系統(tǒng)中的節(jié)點(diǎn)數(shù)保持一致,矩陣的行數(shù)代表支路的首節(jié)點(diǎn),列數(shù)代表支路的末節(jié)點(diǎn)。位于對(duì)角線上的元素,代表各個(gè)節(jié)點(diǎn)注入功率的絕對(duì)值,位于非對(duì)角線上的元素,代表各條支路之間的潮流分布,潮流的方向由正負(fù)號(hào)和首末節(jié)點(diǎn)來(lái)確定。然后借助該矩陣追蹤平衡節(jié)點(diǎn)發(fā)出的功率,對(duì)平衡節(jié)點(diǎn)所在列進(jìn)行遍歷,找出其中的負(fù)值,即為該平衡節(jié)點(diǎn)向其他節(jié)點(diǎn)輸出的功率,當(dāng)追蹤到平衡節(jié)點(diǎn)的功率輸入到某一個(gè)節(jié)點(diǎn)時(shí),要判斷該節(jié)點(diǎn)是否會(huì)停電,此時(shí)就要轉(zhuǎn)到該節(jié)點(diǎn)所在列,將該列中的正值遍歷出來(lái),這些正值即代表了其他節(jié)點(diǎn)向該節(jié)點(diǎn)輸入的功率,將遍歷到的數(shù)值相加,和自身的注入功率比較,如果該節(jié)點(diǎn)從其他負(fù)荷節(jié)點(diǎn)(平衡節(jié)點(diǎn)除外) 獲取的功率足夠支撐自身的消耗,該節(jié)點(diǎn)就不會(huì)停電,反之就會(huì)出現(xiàn)停電故障。判斷完該節(jié)點(diǎn)是否會(huì)停電后,重復(fù)上述步驟,繼續(xù)由該節(jié)點(diǎn)追蹤平衡節(jié)點(diǎn)發(fā)出的功率。由于平衡節(jié)點(diǎn)輸出的功率一般只能傳遞到附近的幾個(gè)節(jié)點(diǎn),所以該追蹤過(guò)程持續(xù)5 次,基本可以追蹤到所有的停電節(jié)點(diǎn)。
由直流潮流模塊的計(jì)算可以得知某條線路故障時(shí),對(duì)應(yīng)負(fù)荷的停電信息,計(jì)算這些負(fù)荷的可靠性指標(biāo)。首先,在對(duì)應(yīng)系統(tǒng)中的設(shè)備產(chǎn)生隨機(jī)數(shù),通過(guò)比較隨機(jī)數(shù)的大小來(lái)確定哪個(gè)設(shè)備最先發(fā)生故障[7],找出該設(shè)備所在支路,該支路發(fā)生故障時(shí),對(duì)應(yīng)負(fù)荷點(diǎn)的停電情況就可以通過(guò)直流潮流模塊確定,對(duì)發(fā)生故障的負(fù)荷點(diǎn)進(jìn)行可靠性指標(biāo)計(jì)算;然后重新生成隨機(jī)數(shù),進(jìn)行第二次的隨機(jī)數(shù)大小比較,確定第二個(gè)發(fā)生故障的設(shè)備;重復(fù)上述步驟,直到超出模擬時(shí)限為止[8]。將各節(jié)點(diǎn)的可靠性指標(biāo)累加并取平均值,即可得到各負(fù)荷點(diǎn)的可靠性指標(biāo),再根據(jù)設(shè)備在系統(tǒng)中的連接方式,選擇不同的公式,計(jì)算出整個(gè)系統(tǒng)的各項(xiàng)可靠性指標(biāo)。如果設(shè)備為串聯(lián)方式,可以采用式(3) ~式(5) 進(jìn)行計(jì)算;如果設(shè)備為并聯(lián)方式,可以采用式 (6) ~式 (8) 進(jìn)行計(jì)算。
其中,λ 為負(fù)荷點(diǎn)故障率,次/a;r 為負(fù)荷點(diǎn)每次故障平均停電持續(xù)時(shí)間,h/次;U 為負(fù)荷點(diǎn)的年平均停電時(shí)間,h/a。
直流潮流求解線性方程組的速度快,不存在收斂問(wèn)題,適用于需要大量計(jì)算或運(yùn)行條件不十分理想的場(chǎng)合。本文所介紹的軟件編程涉及大量的計(jì)算,而計(jì)算的目的是故障定位,因此不需要計(jì)算精確潮流,直流潮流正好可以滿足此次軟件設(shè)計(jì)的要求[9]。使用直流潮流計(jì)算出系統(tǒng)潮流后,創(chuàng)造性地使用追蹤平衡節(jié)點(diǎn)發(fā)出功率的方法,實(shí)現(xiàn)了系統(tǒng)的故障定位,提高了系統(tǒng)可靠性的計(jì)算效率。