完成基本功能。
This commit is contained in:
362
test_storage_optimization.py
Normal file
362
test_storage_optimization.py
Normal file
@@ -0,0 +1,362 @@
|
||||
# 多能互补系统储能容量优化计算程序测试用例
|
||||
|
||||
# 该文件包含单元测试和验证测试,确保程序在各种场景下的正确性。
|
||||
|
||||
# 作者: iFlow CLI
|
||||
# 创建日期: 2025-12-25
|
||||
|
||||
import unittest
|
||||
import numpy as np
|
||||
from storage_optimization import (
|
||||
optimize_storage_capacity,
|
||||
validate_inputs,
|
||||
calculate_energy_balance,
|
||||
check_constraints,
|
||||
SystemParameters
|
||||
)
|
||||
|
||||
|
||||
class TestStorageOptimization(unittest.TestCase):
|
||||
"""储能优化程序测试类"""
|
||||
|
||||
def setUp(self):
|
||||
"""测试前的准备工作"""
|
||||
# 基础测试数据
|
||||
self.solar_output = [0.0] * 6 + [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0] + [0.0] * 6
|
||||
self.wind_output = [2.0, 3.0, 4.0, 3.0, 2.0, 1.0] * 4
|
||||
self.thermal_output = [5.0] * 24
|
||||
self.load_demand = [3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 18.0,
|
||||
16.0, 14.0, 12.0, 10.0, 8.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 2.0]
|
||||
self.params = SystemParameters(
|
||||
max_curtailment_wind=0.1,
|
||||
max_curtailment_solar=0.1,
|
||||
max_grid_ratio=0.2,
|
||||
storage_efficiency=0.9,
|
||||
discharge_rate=1.0,
|
||||
charge_rate=1.0
|
||||
)
|
||||
|
||||
def test_validate_inputs_valid_data(self):
|
||||
"""测试有效输入数据的验证"""
|
||||
# 应该不抛出异常
|
||||
validate_inputs(self.solar_output, self.wind_output, self.thermal_output,
|
||||
self.load_demand, self.params)
|
||||
|
||||
def test_validate_inputs_invalid_length(self):
|
||||
"""测试无效长度的输入数据"""
|
||||
with self.assertRaises(ValueError):
|
||||
validate_inputs([1.0] * 23, self.wind_output, self.thermal_output,
|
||||
self.load_demand, self.params)
|
||||
|
||||
def test_validate_inputs_negative_values(self):
|
||||
"""测试包含负值的输入数据"""
|
||||
with self.assertRaises(ValueError):
|
||||
validate_inputs([-1.0] + self.solar_output[1:], self.wind_output,
|
||||
self.thermal_output, self.load_demand, self.params)
|
||||
|
||||
def test_validate_inputs_invalid_parameters(self):
|
||||
"""测试无效的参数设置"""
|
||||
invalid_params = SystemParameters(max_curtailment_wind=1.5) # 超出范围
|
||||
with self.assertRaises(ValueError):
|
||||
validate_inputs(self.solar_output, self.wind_output, self.thermal_output,
|
||||
self.load_demand, invalid_params)
|
||||
|
||||
def test_calculate_energy_balance_basic(self):
|
||||
"""测试基本电能平衡计算"""
|
||||
result = calculate_energy_balance(
|
||||
self.solar_output, self.wind_output, self.thermal_output,
|
||||
self.load_demand, self.params, 10.0
|
||||
)
|
||||
|
||||
# 检查返回结果包含所有必要的键
|
||||
expected_keys = ['storage_profile', 'charge_profile', 'discharge_profile',
|
||||
'curtailed_wind', 'curtailed_solar', 'grid_feed_in']
|
||||
for key in expected_keys:
|
||||
self.assertIn(key, result)
|
||||
self.assertEqual(len(result[key]), 24)
|
||||
|
||||
# 检查储能状态不为负
|
||||
self.assertTrue(all(soc >= 0 for soc in result['storage_profile']))
|
||||
|
||||
def test_check_constraints(self):
|
||||
"""测试约束条件检查"""
|
||||
# 先计算平衡结果
|
||||
balance_result = calculate_energy_balance(
|
||||
self.solar_output, self.wind_output, self.thermal_output,
|
||||
self.load_demand, self.params, 10.0
|
||||
)
|
||||
|
||||
# 检查约束
|
||||
constraint_results = check_constraints(
|
||||
self.solar_output, self.wind_output, self.thermal_output, balance_result, self.params
|
||||
)
|
||||
|
||||
# 检查返回结果
|
||||
expected_keys = ['total_curtailment_wind_ratio', 'total_curtailment_solar_ratio',
|
||||
'total_grid_feed_in_ratio']
|
||||
for key in expected_keys:
|
||||
self.assertIn(key, constraint_results)
|
||||
self.assertGreaterEqual(constraint_results[key], 0)
|
||||
self.assertLessEqual(constraint_results[key], 1.0)
|
||||
|
||||
def test_optimize_storage_capacity_basic(self):
|
||||
"""测试基本储能容量优化"""
|
||||
result = optimize_storage_capacity(
|
||||
self.solar_output, self.wind_output, self.thermal_output,
|
||||
self.load_demand, self.params
|
||||
)
|
||||
|
||||
# 检查返回结果结构
|
||||
expected_keys = [
|
||||
'required_storage_capacity', 'storage_profile', 'charge_profile',
|
||||
'discharge_profile', 'curtailed_wind', 'curtailed_solar',
|
||||
'grid_feed_in', 'total_curtailment_wind_ratio',
|
||||
'total_curtailment_solar_ratio', 'total_grid_feed_in_ratio',
|
||||
'energy_balance_check'
|
||||
]
|
||||
for key in expected_keys:
|
||||
self.assertIn(key, result)
|
||||
|
||||
# 检查数值合理性
|
||||
self.assertGreaterEqual(result['required_storage_capacity'], 0)
|
||||
self.assertTrue(result['energy_balance_check'])
|
||||
|
||||
def test_zero_curtailment_scenario(self):
|
||||
"""测试零弃风弃光场景"""
|
||||
zero_curtail_params = SystemParameters(
|
||||
max_curtailment_wind=0.0,
|
||||
max_curtailment_solar=0.0,
|
||||
max_grid_ratio=0.2,
|
||||
storage_efficiency=0.9
|
||||
)
|
||||
|
||||
result = optimize_storage_capacity(
|
||||
self.solar_output, self.wind_output, self.thermal_output,
|
||||
self.load_demand, zero_curtail_params
|
||||
)
|
||||
|
||||
# 检查弃风弃光率是否为0
|
||||
self.assertEqual(result['total_curtailment_wind_ratio'], 0.0)
|
||||
self.assertEqual(result['total_curtailment_solar_ratio'], 0.0)
|
||||
|
||||
def test_high_grid_ratio_scenario(self):
|
||||
"""测试高上网电量比例场景"""
|
||||
high_grid_params = SystemParameters(
|
||||
max_curtailment_wind=0.1,
|
||||
max_curtailment_solar=0.1,
|
||||
max_grid_ratio=0.5, # 高上网电量比例
|
||||
storage_efficiency=0.9
|
||||
)
|
||||
|
||||
result = optimize_storage_capacity(
|
||||
self.solar_output, self.wind_output, self.thermal_output,
|
||||
self.load_demand, high_grid_params
|
||||
)
|
||||
|
||||
# 检查上网电量比例是否在约束范围内
|
||||
self.assertLessEqual(result['total_grid_feed_in_ratio'], 0.5)
|
||||
|
||||
def test_energy_balance_verification(self):
|
||||
"""测试能量平衡验证"""
|
||||
result = optimize_storage_capacity(
|
||||
self.solar_output, self.wind_output, self.thermal_output,
|
||||
self.load_demand, self.params
|
||||
)
|
||||
|
||||
# 手动验证能量平衡(使用新的计算方法)
|
||||
total_generation = sum(self.thermal_output) + sum(self.wind_output) + sum(self.solar_output)
|
||||
total_consumption = sum(self.load_demand)
|
||||
total_curtailed = sum(result['curtailed_wind']) + sum(result['curtailed_solar'])
|
||||
total_grid = sum(result['grid_feed_in'])
|
||||
total_charge = sum(result['charge_profile'])
|
||||
total_discharge = sum(result['discharge_profile'])
|
||||
|
||||
# 新的能量平衡计算:考虑储能效率
|
||||
energy_from_storage = total_discharge / self.params.storage_efficiency
|
||||
energy_to_storage = total_charge * self.params.storage_efficiency
|
||||
energy_balance = total_generation + energy_from_storage - total_consumption - energy_to_storage - total_curtailed - total_grid
|
||||
|
||||
# 能量平衡误差应该在合理范围内(考虑储能效率损失)
|
||||
tolerance = max(10.0, total_generation * 0.15)
|
||||
self.assertLessEqual(abs(energy_balance), tolerance)
|
||||
|
||||
def test_extreme_high_load_scenario(self):
|
||||
"""测试极高负荷场景"""
|
||||
high_load = [50.0] * 24 # 极高负荷
|
||||
|
||||
result = optimize_storage_capacity(
|
||||
self.solar_output, self.wind_output, self.thermal_output,
|
||||
high_load, self.params
|
||||
)
|
||||
|
||||
# 应该返回一个结果,即使系统可能不平衡
|
||||
self.assertIsNotNone(result)
|
||||
self.assertGreater(result['required_storage_capacity'], 0)
|
||||
|
||||
def test_extreme_low_load_scenario(self):
|
||||
"""测试极低负荷场景"""
|
||||
low_load = [0.1] * 24 # 极低负荷
|
||||
|
||||
result = optimize_storage_capacity(
|
||||
self.solar_output, self.wind_output, self.thermal_output,
|
||||
low_load, self.params
|
||||
)
|
||||
|
||||
# 应该返回一个结果,可能有大量弃风弃光
|
||||
self.assertIsNotNone(result)
|
||||
self.assertGreaterEqual(result['total_curtailment_wind_ratio'], 0)
|
||||
self.assertGreaterEqual(result['total_curtailment_solar_ratio'], 0)
|
||||
|
||||
|
||||
class TestKnownScenarios(unittest.TestCase):
|
||||
"""已知场景测试类"""
|
||||
|
||||
def test_perfect_balance_scenario(self):
|
||||
"""测试完美平衡场景"""
|
||||
# 设计一个完美平衡的场景
|
||||
solar = [2.0] * 6 + [4.0] * 6 + [2.0] * 6 + [0.0] * 6 # 48 MW
|
||||
wind = [3.0] * 12 + [1.0] * 12 # 48 MW
|
||||
thermal = [6.0] * 24 # 144 MW (增加了1 MW每小时)
|
||||
load = [10.0] * 24 # 恒定负荷 240 MW
|
||||
# 总发电量: 48 + 48 + 144 = 240 MW,与负荷平衡
|
||||
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.1,
|
||||
max_curtailment_solar=0.1,
|
||||
max_grid_ratio=0.2,
|
||||
storage_efficiency=0.9
|
||||
)
|
||||
|
||||
result = optimize_storage_capacity(solar, wind, thermal, load, params)
|
||||
|
||||
# 验证结果
|
||||
self.assertTrue(result['energy_balance_check'])
|
||||
self.assertLessEqual(result['total_curtailment_wind_ratio'], params.max_curtailment_wind)
|
||||
self.assertLessEqual(result['total_curtailment_solar_ratio'], params.max_curtailment_solar)
|
||||
self.assertLessEqual(result['total_grid_feed_in_ratio'], params.max_grid_ratio)
|
||||
|
||||
def test_no_renewable_scenario(self):
|
||||
"""测试无可再生能源场景"""
|
||||
solar = [0.0] * 24
|
||||
wind = [0.0] * 24
|
||||
thermal = [10.0] * 24
|
||||
load = [8.0] * 24
|
||||
|
||||
params = SystemParameters(
|
||||
max_curtailment_wind=0.1,
|
||||
max_curtailment_solar=0.1,
|
||||
max_grid_ratio=0.2,
|
||||
storage_efficiency=0.9
|
||||
)
|
||||
|
||||
result = optimize_storage_capacity(solar, wind, thermal, load, params)
|
||||
|
||||
# 验证结果
|
||||
self.assertTrue(result['energy_balance_check'])
|
||||
self.assertEqual(result['total_curtailment_wind_ratio'], 0.0)
|
||||
self.assertEqual(result['total_curtailment_solar_ratio'], 0.0)
|
||||
self.assertGreaterEqual(result['total_grid_feed_in_ratio'], 0)
|
||||
|
||||
|
||||
def run_performance_test():
|
||||
"""运行性能测试"""
|
||||
print("\n=== 性能测试 ===")
|
||||
|
||||
# 生成随机测试数据
|
||||
np.random.seed(42)
|
||||
solar = np.random.exponential(3, 24).tolist()
|
||||
wind = np.random.exponential(2, 24).tolist()
|
||||
thermal = np.random.uniform(3, 8, 24).tolist()
|
||||
load = np.random.uniform(5, 15, 24).tolist()
|
||||
|
||||
params = SystemParameters()
|
||||
|
||||
import time
|
||||
start_time = time.time()
|
||||
|
||||
result = optimize_storage_capacity(solar, wind, thermal, load, params)
|
||||
|
||||
end_time = time.time()
|
||||
execution_time = end_time - start_time
|
||||
|
||||
print(f"执行时间: {execution_time:.4f} 秒")
|
||||
print(f"所需储能容量: {result['required_storage_capacity']:.2f} MWh")
|
||||
print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}")
|
||||
|
||||
|
||||
class TestYearlyData(unittest.TestCase):
|
||||
"""8760小时数据测试类"""
|
||||
|
||||
def setUp(self):
|
||||
"""测试前的准备工作"""
|
||||
# 生成简化的8760小时测试数据(每小时的重复模式)
|
||||
daily_pattern = [3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 18.0,
|
||||
16.0, 14.0, 12.0, 10.0, 8.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 2.0]
|
||||
self.yearly_load = daily_pattern * 365 # 24 * 365 = 8760
|
||||
|
||||
# 简化的发电数据
|
||||
daily_solar = [0.0] * 6 + [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0] + [0.0] * 6
|
||||
daily_wind = [2.0, 3.0, 4.0, 3.0, 2.0, 1.0] * 4
|
||||
daily_thermal = [5.0] * 24
|
||||
|
||||
self.yearly_solar = daily_solar * 365
|
||||
self.yearly_wind = daily_wind * 365
|
||||
self.yearly_thermal = daily_thermal * 365
|
||||
|
||||
self.params = SystemParameters(
|
||||
max_curtailment_wind=0.1,
|
||||
max_curtailment_solar=0.1,
|
||||
max_grid_ratio=0.2,
|
||||
storage_efficiency=0.9,
|
||||
discharge_rate=1.0,
|
||||
charge_rate=1.0
|
||||
)
|
||||
|
||||
def test_yearly_data_validation(self):
|
||||
"""测试8760小时数据验证"""
|
||||
# 验证数据长度
|
||||
self.assertEqual(len(self.yearly_solar), 8760)
|
||||
self.assertEqual(len(self.yearly_wind), 8760)
|
||||
self.assertEqual(len(self.yearly_thermal), 8760)
|
||||
self.assertEqual(len(self.yearly_load), 8760)
|
||||
|
||||
# 验证不会抛出异常
|
||||
validate_inputs(self.yearly_solar, self.yearly_wind, self.yearly_thermal,
|
||||
self.yearly_load, self.params)
|
||||
|
||||
def test_yearly_basic_optimization(self):
|
||||
"""测试8760小时基本优化"""
|
||||
# 使用较小的迭代次数以加快测试
|
||||
result = optimize_storage_capacity(
|
||||
self.yearly_solar, self.yearly_wind, self.yearly_thermal,
|
||||
self.yearly_load, self.params, max_iterations=50
|
||||
)
|
||||
|
||||
# 检查返回结果结构
|
||||
expected_keys = [
|
||||
'required_storage_capacity', 'storage_profile', 'charge_profile',
|
||||
'discharge_profile', 'curtailed_wind', 'curtailed_solar',
|
||||
'grid_feed_in', 'total_curtailment_wind_ratio',
|
||||
'total_curtailment_solar_ratio', 'total_grid_feed_in_ratio',
|
||||
'energy_balance_check'
|
||||
]
|
||||
for key in expected_keys:
|
||||
self.assertIn(key, result)
|
||||
|
||||
# 检查数据长度
|
||||
self.assertEqual(len(result['storage_profile']), 8760)
|
||||
self.assertEqual(len(result['charge_profile']), 8760)
|
||||
self.assertEqual(len(result['discharge_profile']), 8760)
|
||||
|
||||
# 检查数值合理性
|
||||
self.assertGreaterEqual(result['required_storage_capacity'], 0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("运行多能互补系统储能容量优化程序测试...")
|
||||
|
||||
# 运行单元测试
|
||||
unittest.main(argv=[''], exit=False, verbosity=2)
|
||||
|
||||
# 运行性能测试
|
||||
run_performance_test()
|
||||
Reference in New Issue
Block a user