Files
multi_energy_complementarity/test_storage_optimization.py

362 lines
14 KiB
Python
Raw Normal View History

2025-12-25 18:06:12 +08:00
# 多能互补系统储能容量优化计算程序测试用例
# 该文件包含单元测试和验证测试,确保程序在各种场景下的正确性。
# 作者: 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()