I. 简介
在大多数当地(至少在发达国家),人们从国家电网取得动力。这些动力来自不同的发电厂,如核电站或水电站。但在许多其他与世隔绝的当地,如岛屿(例如法国的韦桑岛),施行新的小型电网来满意岛上居民的电力需求更为恰当。树立一个新的电网比用海底电缆将岛屿连接到国家电网更具有本钱效益。
一个小岛的电力需求明显不是整个地区的需求,所以核电站能够从一开端就被扔掉,塘坝也是如此。通常能够归结为几个可再生动力生产基地和一台柴油发电机,以确保稳定的动力生产(主要是在太阳落山,风中止吹的时候)。
但是,在拿起你的锤子和螺丝刀之前,你有必要准确地知道你的微型电网的尺度。电网的电力需求是多少?,咱们能够估计到多少太阳和风资源?,咱们应该建造多少光伏和风车?,咱们的电池应该多大?,等等。所有这些问题都要经过优化:有多种本钱需求优化,但主要是常规本钱和环境本钱,即二氧化碳排放。
不难看出,这便是一个多方针的优化问题,其间的变量仅仅是每个设备的巨细(每个动力生产基地供给多少电力)。
因而,本项意图意图是给出一个端到端的程序,以优化电网规格的需求。输入应该是负荷(在一年中,每小时的电力需求是多少),以及一些约束条件(不超越3个风车,不超越一英亩的光伏,你的名字)。这个程序的输出主要是经过优化的多个本钱函数的值,最重要的是,每个发电厂设施的巨细。
II. 快速启动
首要在你的机器上用git 克隆这个库房,然后下载以下软件包,假如它们在你的环境中已经存在或没有。
II.A. 软件包
- numpy Python的根本科学库,内置数学函数和简略的数组处理。
- time 仅用于打印核算时刻。
- platypus 多方针优化库和它的库
- matplotlib.pyplot 用于绘制图形。
- pandas用于操作数据帧,这是一个Python方针,当咱们操作大型数据集时,会很方便。
II.B. 代码履行
为了确保一切作业正常,在你最喜欢的编译器(Pyzo, Spyder, …)中翻开main.py
并履行该文件。你应该看到弹出的图像。它们显现了优化进程的成果。
然后,假如你想更进一步,用你自己的数据运转优化器,咱们更鼓励你修正optimizerTest()
函数里边的参数。你应该在代码中寻觅这些变量,并相应地修正它们。
fixedParameters =
{
"gridComponents": {
.
.
.
"strategy" : "LF"
}
constraints =
{
"diesel": {
"upperBound": 2000,
.
.
. "lowerBound": 0
}
III. 架构
以下是咱们项意图架构。它被细分为多个包和模块,都有一个主要功用,便是协助终究用户正确规划微电网的使命。
-
README.md
-
.gitignore
-
main.py
-
优化器
-
optimizer.py
-
optimizerV2.py
-
模仿器
-
调度
- dispatchingLoop.py
- dispatchingStrategy.py
-
费用
-
美元
-
dollarCost.py
-
电池
- auxilliaryCostFunctions.py
- batteryCost.py
-
光伏
- auxilliaryCostFunctions.py
- pvCostAlt.py
- pvCost.py
-
柴油
- auxilliaryCostFunctions.py
- dgCostAlt.py
- dgCost.py
-
风车
- windCost.py
-
-
碳排放
- carbonCost.py
-
-
-
IV. 模仿器
模仿器是一个简化的软件包,在给定电网各组成部分的尺度后,可得出微电网的各种本钱。例如。
项意图寿数是25年。我知道这个当地一整年的负荷状况。假如我有一个5千瓦时的电池,2个各2千瓦的风力涡轮机,价值3千瓦的光伏和3千瓦的柴油发电机(dg),需求多少钱(和⛽)?
dollarCost.py
和carbonCost.py
的函数核算了整个项意图全球本钱和全球二氧化碳排放量。这些是优化器旨在最小化本钱函数。
IV.A. 调度
在一年中,依据太阳辐照度或风速,你或许会替换敞开和关闭柴油发电机,甚至在电池中贮存能量以满意未来需求。例如,在夏日,有一个更高的太阳辐照,超越了白日的电力需求。因而,因为光伏和电池的存在,一部分能量能够直接耗费,而剩下的能量能够贮存在电池中。电池将在晚上太阳落山后放电。
在调度方面,咱们能够采取两种不同的调度战略。循环充电和负载跟随。
负载如下 | 循环充电 |
---|---|
当可再生动力不足以为电网供给满意的能量时,咱们或许想翻开dg。假如咱们遵从负载跟踪战略,咱们首要查看电池中是否有满意的能量来完成动力供应。假如没有,咱们就以精确地满意负载的速度敞开数据中心。 | 这个事例与前一个事例完全相同,但这次咱们不是以较低的速度翻开DG,而是以既能满意负载又能为电池充满电的速度翻开。 |
不管咱们选择哪种战略,调度算法都会在每个时刻段核算电池中贮存的能量,以及在每个时刻段核算dg的功用功率。它直接影响到燃料的耗费量以及电池的寿数,例如。
IV.B. 费用
IV.B.1. 电池
电池的本钱是用以下公式核算的。
总本钱 = 出本钱钱+(替换本钱-残值本钱)+运营本钱
其间 :
- 出本钱钱根本上是指电池的价格。
- 替换本钱是电池的价格乘以你在整个项意图生命周期内应该替换的次数,其间 :
- 残值本钱是指在项目结束时,考虑到电池的剩下寿数,你能够希望出售电池的价格。
- 运营本钱是你为你的劳动力操作和保护电池而付出的价格。
电池本钱依赖于上述的调度。事实上,调度严重影响了电池的吞吐量(有多少能量流经电池),然后影响了电池的寿数,从而影响了替换的数量,终究影响本钱。
IV.B.2. 柴油发电机
柴油发电机的本钱是用以下公式核算的。
总本钱 = 本钱本钱 + (替换本钱 - 残值本钱) + 运转和保护本钱 + 燃料本钱
其间 :
- 本钱本钱是柴油发电机的初始购买价格。
- 替换本钱是指在发电机运用寿数结束时替换发电机的本钱。
- 运转和保护本钱是每年运转和保护发电机的本钱。
- 残值本钱是指在项目结束时,考虑到柴油发电机的剩下寿数,你能够预期出售的价格。
- 燃料本钱是依据柴油的市场价格核算出的燃料耗费价格。
就像电池一样,柴油发电机的本钱受到调度的严重影响。事实上,依据战略和调度成果,咱们不能以相同的作业小时数来核算柴油发电机的本钱,比如说。假如作业小时数不一样,寿数也不一样,因而替换的数量也不一样。替换次数越多,费用越高。
IV.B.3. 光伏电池板
光伏的本钱是用以下公式核算的:
总本钱 = 本钱本钱+(替换本钱-残值本钱)+运营和保护本钱
其间 :
- 本钱本钱是光伏的初始购买价格。
- 替换本钱是指在光伏电池寿数结束时替换的本钱。
- 运营和保护本钱是每年运营和保护光伏的本钱。
- 残值本钱是指在项目结束时,考虑到光伏发电的剩下寿数,你能够希望出售的价格。
IV.B.4. 风力涡轮机
风力涡轮机的本钱是用以下公式核算的:
总本钱 = 本钱本钱 + (重置本钱 - 残值本钱) + 运转和保护本钱
其间 :
- 本钱本钱是风轮机的初始购买价格。
- 替换本钱是指在风轮机运用寿数结束时替换风轮机的本钱。
- 运转和保护本钱是每年运转和保护风轮机的本钱。
- 残值本钱是指在项目结束时,考虑到风轮机的剩下寿数,你能够希望以什么价格出售它们。
总本钱
综上所述的4个本钱函数,咱们能够核算出项意图总本钱,以美元计。这将是优化器企图最小化的第一个本钱函数。
二氧化碳排放量 ♻️
costCarbon.py
模块的输入与dollarsCost.py
模块的输入相同。costCarbon.emissionCO2()
函数的输出将是整个项目生命周期的均匀二氧化碳排放量(kgCO2e/h)。
输出的值(kgCO2e/h)取决于:
- 发电机的巨细
- 电池的贮存才能
- 光伏的额外功率
- 正在运用的调度战略
该函数中运用的固定参数是:
- 每升柴油耗费的二氧化碳排放量=2.65 kgCO2e/L
- 柴油发电机的上游系数=1.2(上游系数考虑到了柴油发电机的整个生命周期的碳脚印)
- 电池每个制造才能的二氧化碳排放量=0.72公斤二氧化碳/千瓦时
- 光伏的二氧化碳排放脚印=6gCO2e/kWh
碳本钱函数将是咱们的优化器旨在最小化的第二个函数。
V. 优化器
优化器是基于预先存在的python模块。给定一组要最小化的本钱函数,优化器返回每个组件的尺度,以便在均匀时刻内最小化本钱函数。例如:
我想使本钱和二氧化碳排放量最小化。我的光伏发电和风力发电机的数量有限,我的燃油机不能大于x,但我的电池没有约束。优化器将返回每个组件的功率规格,以使本钱和碳排放最小化。
咱们运用了用户友爱的plapytus模块,不需求许多参数,它是这个项目里完美的 “黑匣子”。
我运用的详细算法是NSGA-II算法。它是一种非支配排序的遗传算法。咱们测验用不同的种群规模来比较这个算法的成果。成果图表展示了由优化变量产生的可行处理方案的集合(两个轴是要最小化的两个方针函数)。如图所示,咱们能够确定帕累托前沿,以显现2个方针函数之间的或许权衡。
V.A. 本钱函数
要最小化的两个本钱函数是在模仿器中完成的 “美元本钱 “和 “碳排放本钱”。这些函数被作为参数传递给优化器。
V.B. 边界和参数
优化器迭代的参数是电池最大存储容量,发电机最大输出功率和太阳能安装功率。简略地说:每次迭代后,优化器都会稍微改动这三个值,看看它对 “美元本钱 “和 “碳本钱 “有什么影响,以便找到能够一起使两个函数最小化的三个值。该最优值被称为帕雷托最优值。
但是,因为咱们没有无限的资源,咱们不得不为三个变量中的每一个添加下限和上限(咱们不能有负值也不能有无限的值)。
最后,这里是问题定义的样子。
problem = Problem(3, 2)
problem.types[:] = [Real(constraints["battery"]["lowerBound"], constraints["battery"]["upperBound"]), Real(constraints["diesel"]["lowerBound"], constraints["diesel"]["upperBound"]), Real(constraints["photovoltaic"]["lowerBound"], constraints["photovoltaic"]["upperBound"])]
problem.function = costFunction # 该函数返回[美元本钱,碳本钱]。
algorithm = NSGAII(problem) # NSGAII是用于处理优化问题的求解器
algorithm.run(1)
VI. 展望
VI.A. 功率
不幸的是,整个优化进程是核算昂贵的。事实上,在plytapus优化器的每次迭代之后,程序有必要核算调度战略的成果(整个进程中dg和电池存储的功率输出),然后在多个长的列表中迭代,以核算各种本钱(”美元本钱 “和 “碳本钱”)。
在这种装备下,关于一个1年的模仿和一个25年的项目,优化器运转一次,核算和显现成果需求较长时刻。
一个处理方案是运用谷歌的资源来运转优化器(更多信息请见谷歌合作网站)。
VI.B. 只用一个求解器
咱们只运用了plytapus供给的NSGAII求解器,而该库供给了许多其他求解器。咱们应该测验不同的求解器来比较它们的功率。
VI.C. 用户界面
这个项意图一个或许的扩展是编写一个友爱的用户界面,由Python运转的本地服务器(例如Django或Flask)供给网页。更切当地说,能够有一个用html、css和js编码的网页,用户能够在那里输入和设置他的模仿参数。这些参数能够被发送到运转Python代码的本地服务器,然后在网页上动态地出现优化的成果。
VII. 道谢
咱们的作业经常得到咱们的老师@CentraleSuplec的审查和指导。Nabil Sadou和Pierre Haessig。
VIII. 许可证
本项目是依据CentraleSuplec许可证的条款授权的。
只需有说到贡献者或这个资源库,就答应复制和修正。
IX. 贡献者
- Yun Bin Choh–Student @ CentraleSuplec-lukecyb8687
- Paula Rayol–Student @ CentraleSuplec-paularayol
- Bastien Velitchkine–Student @ CentraleSuplec-Bassvelitchkine
{
grid Components: {
"电池": {
"initialStorage":介于0和1之间的浮点数,电池初始储能占其最大容量的百分比。
"maxInputPow":浮点数,关于1kWh的电池,电池的最大充电功率,单位是千瓦。实践值将通过乘以最大存储容量而得到。
"maxOutputPow": 浮点数,1kWh电池的最大放电功率,单位是kW。实践值将通过乘以最大存储容量而得到。
"SOC_min": 浮点数,电池中能够贮存的最小能量,占最大贮存容量的百分比。
"maxThroughput":浮点数,咱们用最大存储量乘以该数字,得到电池在其寿数期间能够流入和流出的最大能量(千瓦时)。
"lifetime":int,电池的额外寿数,单位是小时。这是咱们在没有超越最大吞吐量的状况下有必要替换它的时刻。
"capitalCost": float, 一个1kWh电池的本钱,单位是美元。
"replacementCost": 浮点数,替换1kWh电池的本钱,单位为美元。
"运转本钱":起浮值,每小时运转和保护电池的本钱($)。
},
"柴油": {
"fuelCost": 起浮的,1升燃料的本钱($)。
"fuelCostGrad": float, 有一条燃料曲线,模仿了柴油机的功用功率和它每千瓦的升油耗费之间的关系。这个参数是模型曲线的斜率。
"fuelCostIntercept": 起浮,有一条燃料曲线,模仿了dg的功用功率和它每千瓦的升油耗费之间的关系。这个参数是模型曲线的截点。
"寿数": int, dg的额外寿数,以小时为单位。
"本钱本钱":起浮,dg的本钱,单位是美元。
"替换本钱":浮点数,替换dg的本钱,单位是美元。
"运营本钱":起浮,每小时的运营和保护本钱。
},
"光伏": {
"寿数": int, 通道的额外寿数(小时)。
"capitalCost": float, 通道的本钱,单位是美元。
"replacementCost": float, 替换一个通道的本钱,单位是美元。
"运转本钱":起浮,每小时运转和保护通道的本钱(美元)。
"powerTimeVector": numpy数组,通道在每个时刻步长的功率输出(千瓦)。
}
},
timeStep: float,产生负载的模仿时刻步长,单位是小时。
loadVector: numpy数组,电网的电力需求(千瓦)。
projectDuration: int, 整个项意图持续时刻,以小时为单位(如25 * 365 * 24)。
discountRate: float, 折扣率。
战略:"LF "或 "CC",分别表示"负载跟踪 " 或 "循环充电"
constraints{
"柴油"
{
"upperBound": float,发电机最大功率(千瓦)值的上限。
"lowerBound": float, 发电机最大功率(千瓦)值的下限。
},
"电池"
{
"upperBound": float,电池最大贮存容量(千瓦时)的上限。
"lowerBound": float, 电池最大贮存容量的下限(千瓦时)。
},
"光伏"
{
"upperBound": float, pv 最大功率 (千瓦) 值的上限。
"lowerBound": float, pv 最大功率 (千瓦) 值的上下限。
},
}
OUTPUT:
{
"参数"
{
"电池":起浮值,电池存储容量(千瓦时)。
"柴油":起浮值,发电机最大功率(千瓦)。
"光伏":起浮值,光伏的最大功率(千瓦)
},
"本钱"
{
"美元":起浮,项意图本钱,单位是美元。
"碳":起浮,项目产生的碳排放量(公斤)。
}
}
}