Compare commits
16 Commits
d563905f28
...
b924f75add
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b924f75add | ||
|
|
c6168afd1d | ||
|
|
9352005db3 | ||
|
|
15d8f4881d | ||
|
|
751bdef245 | ||
|
|
05ac7a3388 | ||
|
|
f28e087cd2 | ||
|
|
a5b46529da | ||
|
|
2ec763b86a | ||
|
|
a42a8ec7f1 | ||
|
|
dd7265ff4f | ||
|
|
3f73a9be26 | ||
|
|
369430aa67 | ||
|
|
00d480edbb | ||
|
|
06680a6e33 | ||
|
|
6f2f851a6e |
31
Makefile
Normal file
31
Makefile
Normal file
@@ -0,0 +1,31 @@
|
||||
.PHONY: help clean build rebuild
|
||||
|
||||
# 默认目标
|
||||
help:
|
||||
@echo "海上风电场集电线路设计优化系统 - 构建脚本"
|
||||
@echo ""
|
||||
@echo "可用命令:"
|
||||
@echo " make build - 使用 .spec 文件生成单文件 exe 程序"
|
||||
@echo " make rebuild - 清理并重新构建"
|
||||
@echo " make clean - 清理构建生成的临时文件和缓存"
|
||||
@echo " make help - 显示此帮助信息"
|
||||
|
||||
# 生成单文件exe程序
|
||||
# 使用 --clean 清理 PyInstaller 缓存,-y 自动覆盖输出
|
||||
build:
|
||||
@echo "开始打包程序..."
|
||||
uv run pyinstaller --clean -y "海上风电场集电线路设计优化系统.spec"
|
||||
@echo "打包完成!"
|
||||
@echo "可执行文件位于: dist/海上风电场集电线路设计优化系统.exe"
|
||||
|
||||
# 清理构建生成的临时文件
|
||||
clean:
|
||||
@echo "正在清理临时文件..."
|
||||
@uv run python -c "import shutil, pathlib; [shutil.rmtree(p) for p in pathlib.Path('.').rglob('__pycache__')]; shutil.rmtree('build', ignore_errors=True); shutil.rmtree('dist', ignore_errors=True)"
|
||||
@echo "清理完成!"
|
||||
nice:
|
||||
uv run nicegui-pack --onefile --name "海上风电场集电线路设计优化系统" gui.py --onefile --windowed
|
||||
|
||||
|
||||
# 清理并重新构建
|
||||
rebuild: clean build
|
||||
151
README.md
151
README.md
@@ -1,116 +1,91 @@
|
||||
# 海上风电场集电系统设计工具
|
||||
# 海上风电场集电系统设计优化工具 (Wind Farm Collector System Optimizer)
|
||||
|
||||
一个用于设计和优化海上风电场集电系统的Python工具,支持多种布局算法和电缆优化方案。
|
||||
一个用于设计和优化海上风电场集电系统拓扑的综合工具。支持多种先进算法,能够根据风机坐标、功率以及海缆规格,自动生成投资成本最低、损耗最小的设计方案。
|
||||
|
||||
## 功能特性
|
||||
## 🌟 主要功能
|
||||
|
||||
- 🌊 多种风机布局生成(随机分布、规则网格)
|
||||
- 🔌 多种集电系统设计算法:
|
||||
- 最小生成树(MST)算法
|
||||
- K-means聚类算法
|
||||
- 容量扫描算法(Capacitated Sweep)
|
||||
- 旋转优化算法(Rotational Sweep)
|
||||
- 📊 多方案对比分析和可视化
|
||||
- 📋 自动导出DXF图纸和Excel报告
|
||||
- 🔧 智能电缆规格选择和成本优化
|
||||
- 🖥️ **原生桌面体验**:支持 Native 模式运行,提供类似本地应用的流畅体验(基于 NiceGUI & PyWebview)。
|
||||
- 🌊 **多种布局生成**:内置模拟数据生成器,支持规则网格和随机分布布局。
|
||||
- 🔌 **先进设计算法**:
|
||||
- **MST (Minimum Spanning Tree)**:无容量约束基准方案。
|
||||
- **Capacitated Sweep (Base)**:基础扇区扫描分组。
|
||||
- **Rotational Sweep**:全局最优起始角度旋转扫描优化。
|
||||
- **Esau-Williams**:经典启发式算法,在距离与容量间寻找最优平衡。
|
||||
- ⚙️ **灵活参数配置**:支持通过 Excel 自定义系统电压、功率因数及详细电缆规格。
|
||||
- 📊 **智能方案对比**:自动运行三大场景(标准方案、含可选电缆方案、限制最大截面方案)并对比结果。
|
||||
- 📁 **多格式导出**:
|
||||
- 自动生成 CAD 图纸 (`.dxf`),按电缆规格分层并着色。
|
||||
- 导出详细的 Excel 对比报告及单方案电缆清册。
|
||||
- 支持一键打包导出所有方案压缩包 (`.zip`)。
|
||||
|
||||
## 安装依赖
|
||||
## 🛠️ 安装依赖
|
||||
|
||||
本项目使用 `uv` 或 `pip` 管理环境。推荐安装依赖:
|
||||
|
||||
```bash
|
||||
pip install numpy pandas matplotlib scikit-learn scipy networkx
|
||||
pip install numpy pandas matplotlib scikit-learn scipy networkx ezdxf nicegui openpyxl pywebview
|
||||
```
|
||||
*注:`pywebview` 用于支持原生窗口模式。*
|
||||
|
||||
## 使用方法
|
||||
## 🚀 使用方法
|
||||
|
||||
### 基本用法
|
||||
### 1. 启动图形化界面 (推荐)
|
||||
|
||||
运行以下命令启动应用,程序将自动弹出独立窗口:
|
||||
|
||||
```bash
|
||||
python main.py
|
||||
python gui.py
|
||||
```
|
||||
|
||||
### 指定数据文件
|
||||
**GUI 特性:**
|
||||
- **模板导出**:点击界面上的 "导出 Excel 模板" 按钮可获取标准输入格式文件。
|
||||
- **参数概览**:上传文件后自动解析并显示系统参数及电缆规格。
|
||||
- **交互式分析**:点击结果表格中的行,可实时查看对应方案的拓扑图。
|
||||
|
||||
### 2. 命令行模式
|
||||
|
||||
```bash
|
||||
python main.py --excel wind_farm_coordinates.xlsx
|
||||
python main.py --excel your_data.xlsx
|
||||
```
|
||||
|
||||
### 覆盖默认簇数
|
||||
## 📝 输入数据规范 (Excel)
|
||||
|
||||
```bash
|
||||
python main.py --clusters 20
|
||||
```
|
||||
为了确保计算结果的准确性,输入 Excel 文件应包含以下 Sheet(推荐使用 GUI 导出模板):
|
||||
|
||||
## 算法说明
|
||||
### 1. Coordinates (坐标)
|
||||
| Type | ID | X | Y | Power | PlatformHeight |
|
||||
|------|----|---|---|-------|----------------|
|
||||
| Substation | Sub1 | 4000 | -800 | 0 | 0 |
|
||||
| Turbine | 1 | 0 | 0 | 8.0 | 25 |
|
||||
| ... | ... | ... | ... | ... | ... |
|
||||
|
||||
### 1. MST Method(最小生成树)
|
||||
- 使用最小生成树连接所有风机到海上变电站
|
||||
- 简单高效,适合初步设计
|
||||
### 2. Cables (电缆)
|
||||
**必须遵守以下规则:**
|
||||
- **单调递增性**:电缆必须按截面从小到大排列,且对应的额定载流量也必须严格递增。
|
||||
- **可选电缆规则**:
|
||||
- `Optional` 列标记为 'Y' 的电缆最多只能有一条。
|
||||
- 若存在可选电缆,它必须是列表中截面最大的一条。
|
||||
|
||||
### 2. K-means Clustering
|
||||
- 将风机分组到多个回路中
|
||||
- 平衡每回路的功率分配
|
||||
### 3. Parameters (参数) [可选]
|
||||
可自定义系统级参数,若不提供则使用默认值。
|
||||
|
||||
### 3. Capacitated Sweep(容量扫描)
|
||||
- 考虑电缆容量约束的智能分组
|
||||
- 支持多种电缆规格自动选择
|
||||
| Parameter | Value | 说明 |
|
||||
|-----------|-------|------|
|
||||
| Voltage (kV) | 66 | 系统电压,支持 `Voltage` 或 `System Voltage`。若 key 包含 `kV` 则自动 *1000。 |
|
||||
| Power Factor | 0.95 | 功率因数 (0-1)。 |
|
||||
|
||||
### 4. Rotational Sweep(旋转优化)
|
||||
- 在容量扫描基础上进行旋转优化
|
||||
- 进一步降低总成本和损耗
|
||||
## 📈 场景说明 (Scenarios)
|
||||
|
||||
## 输出文件
|
||||
1. **Scenario 1 (Standard)**:仅使用非可选(标准)电缆进行优化。
|
||||
2. **Scenario 2 (With Optional)**:包含标记为 'Y' 的大型电缆,适用于尝试增加单回路容量的场景。
|
||||
3. **Scenario 3 (No Max)**:排除最大截面电缆,测试在电缆供应受限时的最优拓扑。
|
||||
|
||||
1. **可视化图片**:`wind_farm_design_comparison.png`
|
||||
- 不同算法的设计方案对比图
|
||||
## 📂 输出文件说明
|
||||
|
||||
2. **CAD图纸**:`wind_farm_design.dxf`
|
||||
- 可导入CAD软件的详细设计图纸
|
||||
- **Excel 报告**:`[文件名]_result.xlsx` 包含所有方案的总览及详细连接清单。
|
||||
- **CAD 图纸**:`design_[方案名].dxf` 包含分层分色的拓扑图。
|
||||
- **全部方案**:`[文件名]_result.zip` 包含所有图纸及 Excel 报告。
|
||||
|
||||
3. **数据报告**:`wind_farm_design.xlsx`
|
||||
- 包含所有方案的详细技术参数和成本分析
|
||||
## ⚖️ 许可证
|
||||
|
||||
## 关键参数说明
|
||||
|
||||
可以在 `main.py` 中调整以下核心常量以适配不同项目:
|
||||
|
||||
```python
|
||||
VOLTAGE_LEVEL = 66000 # 集电系统电压 (V)
|
||||
POWER_FACTOR = 0.95 # 功率因数
|
||||
cost_multiplier = 5.0 # 海缆相对于陆缆的成本倍数
|
||||
```
|
||||
|
||||
## 电缆规格配置
|
||||
|
||||
项目支持多种电缆规格,可在 `generate_template.py` 中配置:
|
||||
|
||||
| 截面积(mm²) | 容量(MW) | 电阻(Ω/km) | 成本(元/m) |
|
||||
|-------------|----------|------------|------------|
|
||||
| 35 | 150 | 0.524 | 80 |
|
||||
| 70 | 215 | 0.268 | 120 |
|
||||
| 95 | 260 | 0.193 | 150 |
|
||||
| 120 | 295 | 0.153 | 180 |
|
||||
| 150 | 330 | 0.124 | 220 |
|
||||
| 185 | 370 | 0.0991 | 270 |
|
||||
| 240 | 425 | 0.0754 | 350 |
|
||||
| 300 | 500 | 0.0601 | 450 |
|
||||
| 400 | 580 | 0.0470 | 600 |
|
||||
|
||||
## 输出示例
|
||||
|
||||
```text
|
||||
===== 开始比较电缆方案 =====
|
||||
|
||||
--- All Cables (Base) ---
|
||||
[Base] Cost: ¥12,456,789.12 | Loss: 234.56 kW
|
||||
[Rotational] Cost: ¥12,234,567.89 | Loss: 223.45 kW
|
||||
|
||||
--- High Current (Base) ---
|
||||
[Base] Cost: ¥11,987,654.32 | Loss: 245.67 kW
|
||||
[Rotational] Cost: ¥11,876,543.21 | Loss: 234.56 kW
|
||||
|
||||
推荐方案: High Current (Rotational) (默认)
|
||||
```
|
||||
|
||||
## 许可证
|
||||
|
||||
本项目仅供学习和研究使用。
|
||||
本项目仅供工程学习、研究和初步设计评估使用。详细计算应以专业设计院规范为准。
|
||||
@@ -1,7 +1,7 @@
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
def create_template():
|
||||
def create_template(output_file='windfarm_template.xlsx'):
|
||||
# Create sample data similar to the internal generator
|
||||
data = []
|
||||
|
||||
@@ -50,12 +50,19 @@ def create_template():
|
||||
]
|
||||
df_cables = pd.DataFrame(cable_data)
|
||||
|
||||
# Create System Parameters data
|
||||
param_data = [
|
||||
{'Parameter': 'Voltage (kV) / 电压 (kV)', 'Value': 66},
|
||||
{'Parameter': 'Power Factor / 功率因数', 'Value': 0.95}
|
||||
]
|
||||
df_params = pd.DataFrame(param_data)
|
||||
|
||||
# Save to Excel
|
||||
output_file = 'coordinates.xlsx'
|
||||
with pd.ExcelWriter(output_file) as writer:
|
||||
df.to_excel(writer, sheet_name='Coordinates', index=False)
|
||||
df_cables.to_excel(writer, sheet_name='Cables', index=False)
|
||||
print(f"Created sample file: {output_file} with sheets 'Coordinates' and 'Cables'")
|
||||
df_params.to_excel(writer, sheet_name='Parameters', index=False)
|
||||
print(f"Created sample file: {output_file} with sheets 'Coordinates', 'Cables', and 'Parameters'")
|
||||
|
||||
if __name__ == "__main__":
|
||||
create_template()
|
||||
229
main.py
229
main.py
@@ -153,14 +153,85 @@ def load_data_from_excel(file_path):
|
||||
specs.append((section, capacity, resistance, cost, is_optional))
|
||||
|
||||
if specs:
|
||||
specs.sort(key=lambda x: x[1]) # 按载流量排序
|
||||
# --- 输入数据校验:单调性 ---
|
||||
for i in range(len(specs) - 1):
|
||||
curr_s = specs[i]
|
||||
next_s = specs[i + 1]
|
||||
|
||||
# 校验截面 (section)
|
||||
if curr_s[0] >= next_s[0]:
|
||||
raise ValueError(
|
||||
f"电缆数据校验失败:Excel中电缆顺序必须按截面从小到大排列。第{i+1}行({curr_s[0]}mm²) >= 第{i+2}行({next_s[0]}mm²)。"
|
||||
)
|
||||
|
||||
# 校验载流量 (capacity)
|
||||
if curr_s[1] >= next_s[1]:
|
||||
raise ValueError(
|
||||
f"电缆数据校验失败:Excel中电缆载流量必须严格递增。第{i+1}行({curr_s[1]}A) >= 第{i+2}行({next_s[1]}A)。"
|
||||
)
|
||||
|
||||
specs.sort(key=lambda x: x[1]) # 按载流量排序
|
||||
|
||||
# --- 输入数据校验 ---
|
||||
# 筛选出所有标记为 Optional='Y' 的电缆
|
||||
optional_cables = [s for s in specs if s[4]]
|
||||
|
||||
# 规则1: 最多只能有一条可选电缆
|
||||
if len(optional_cables) > 1:
|
||||
raise ValueError(
|
||||
f"电缆数据校验失败:检测到 {len(optional_cables)} 条可选电缆(Optional='Y')。系统限制最多只能指定 1 条可选电缆。"
|
||||
)
|
||||
|
||||
# 规则2: 如果存在可选电缆,它必须是所有电缆中截面最大的一条
|
||||
if len(optional_cables) == 1:
|
||||
opt_cable = optional_cables[0]
|
||||
# s[0] 是截面积
|
||||
max_section = max(s[0] for s in specs)
|
||||
if opt_cable[0] < max_section:
|
||||
raise ValueError(
|
||||
f"电缆数据校验失败:可选电缆 ({opt_cable[0]}mm²) 必须是所有电缆中截面最大的一条 (当前最大为 {max_section}mm²)。"
|
||||
)
|
||||
# --------------------
|
||||
|
||||
cable_specs = specs
|
||||
|
||||
print(f"成功加载: {len(turbines)} 台风机, {len(substation)} 座升压站")
|
||||
if cable_specs:
|
||||
print(f"成功加载: {len(cable_specs)} 种电缆规格")
|
||||
|
||||
return turbines, substation, cable_specs
|
||||
# 读取参数数据 (如果存在)
|
||||
system_params = {}
|
||||
param_sheet_name = None
|
||||
if 'Parameters' in xl.sheet_names:
|
||||
param_sheet_name = 'Parameters'
|
||||
elif '参数' in xl.sheet_names:
|
||||
param_sheet_name = '参数'
|
||||
|
||||
if param_sheet_name:
|
||||
try:
|
||||
params_df = pd.read_excel(xl, param_sheet_name)
|
||||
# 假设格式为两列:Parameter (参数名), Value (值)
|
||||
if len(params_df.columns) >= 2:
|
||||
for _, row in params_df.iterrows():
|
||||
key = str(row[0]).strip().lower()
|
||||
try:
|
||||
val = float(row[1])
|
||||
if 'voltage' in key or '电压' in key:
|
||||
# 检测是否为kV单位
|
||||
if 'kv' in key:
|
||||
system_params['voltage'] = val * 1000
|
||||
else:
|
||||
system_params['voltage'] = val
|
||||
elif 'factor' in key or '功率因数' in key:
|
||||
system_params['power_factor'] = val
|
||||
except ValueError:
|
||||
pass
|
||||
if system_params:
|
||||
print(f"成功加载系统参数: {system_params}")
|
||||
except Exception as e:
|
||||
print(f"读取参数Sheet失败: {e}")
|
||||
|
||||
return turbines, substation, cable_specs, system_params
|
||||
|
||||
except Exception as e:
|
||||
print(f"读取Excel文件失败: {str(e)}")
|
||||
@@ -276,7 +347,7 @@ def design_with_kmeans(turbines, substation, n_clusters=3):
|
||||
return cluster_connections + substation_connections, turbines
|
||||
|
||||
# 3.5 带容量约束的扇区扫描算法 (Capacitated Sweep) - 基础版
|
||||
def design_with_capacitated_sweep(turbines, substation, cable_specs=None):
|
||||
def design_with_capacitated_sweep(turbines, substation, cable_specs=None, voltage=VOLTAGE_LEVEL, power_factor=POWER_FACTOR):
|
||||
"""
|
||||
使用带容量约束的扇区扫描算法设计集电线路 (基础版:单次扫描)
|
||||
原理:
|
||||
@@ -286,21 +357,17 @@ def design_with_capacitated_sweep(turbines, substation, cable_specs=None):
|
||||
4. 满载后开启新回路。
|
||||
"""
|
||||
# 1. 获取电缆最大容量
|
||||
max_mw = get_max_cable_capacity_mw(cable_specs)
|
||||
# print(f"DEBUG: 扇区扫描算法启动 - 单回路容量限制: {max_mw:.2f} MW")
|
||||
max_mw = get_max_cable_capacity_mw(cable_specs, voltage=voltage, power_factor=power_factor)
|
||||
|
||||
substation_coord = substation[0]
|
||||
|
||||
# 2. 计算角度 (使用 arctan2 返回 -pi 到 pi)
|
||||
# 避免直接修改原始DataFrame,使用副本
|
||||
work_df = turbines.copy()
|
||||
dx = work_df['x'] - substation_coord[0]
|
||||
dy = work_df['y'] - substation_coord[1]
|
||||
work_df['angle'] = np.arctan2(dy, dx)
|
||||
|
||||
# 3. 寻找最佳起始角度 (最大角度间隙)
|
||||
# 按角度排序
|
||||
work_df = work_df.sort_values('angle').reset_index(drop=True) # 重置索引方便切片
|
||||
work_df = work_df.sort_values('angle').reset_index(drop=True)
|
||||
|
||||
angles = work_df['angle'].values
|
||||
n = len(angles)
|
||||
@@ -381,7 +448,7 @@ def design_with_capacitated_sweep(turbines, substation, cable_specs=None):
|
||||
return cluster_connections + substation_connections, turbines
|
||||
|
||||
# 3.6 旋转扫描算法 (Rotational Sweep) - 优化版
|
||||
def design_with_rotational_sweep(turbines, substation, cable_specs=None):
|
||||
def design_with_rotational_sweep(turbines, substation, cable_specs=None, voltage=VOLTAGE_LEVEL, power_factor=POWER_FACTOR):
|
||||
"""
|
||||
使用带容量约束的扇区扫描算法设计集电线路 (优化版:旋转扫描)
|
||||
原理:
|
||||
@@ -391,8 +458,7 @@ def design_with_rotational_sweep(turbines, substation, cable_specs=None):
|
||||
4. 对每种分组方案计算MST成本,选出总成本最低的方案。
|
||||
"""
|
||||
# 1. 获取电缆最大容量
|
||||
max_mw = get_max_cable_capacity_mw(cable_specs)
|
||||
# print(f"DEBUG: 扇区扫描算法启动 - 单回路容量限制: {max_mw:.2f} MW")
|
||||
max_mw = get_max_cable_capacity_mw(cable_specs, voltage=voltage, power_factor=power_factor)
|
||||
|
||||
substation_coord = substation[0]
|
||||
|
||||
@@ -410,6 +476,7 @@ def design_with_rotational_sweep(turbines, substation, cable_specs=None):
|
||||
best_connections = []
|
||||
best_turbines_state = None
|
||||
best_start_idx = -1
|
||||
best_id_to_cluster = {}
|
||||
|
||||
# 遍历所有可能的起始点
|
||||
for start_idx in range(n_turbines):
|
||||
@@ -463,8 +530,7 @@ def design_with_rotational_sweep(turbines, substation, cable_specs=None):
|
||||
# 2. 连接升压站长度
|
||||
dists = np.sqrt((cluster_rows['x'] - substation_coord[0])**2 +
|
||||
(cluster_rows['y'] - substation_coord[1])**2)
|
||||
min_dist = dists.min()
|
||||
current_total_length += min_dist
|
||||
current_total_length += dists.min()
|
||||
|
||||
# --- 比较并保存最佳结果 ---
|
||||
if current_total_length < best_cost:
|
||||
@@ -506,7 +572,7 @@ def design_with_rotational_sweep(turbines, substation, cable_specs=None):
|
||||
|
||||
return final_connections, turbines
|
||||
|
||||
def get_max_cable_capacity_mw(cable_specs=None):
|
||||
def get_max_cable_capacity_mw(cable_specs=None, voltage=VOLTAGE_LEVEL, power_factor=POWER_FACTOR):
|
||||
"""
|
||||
计算给定电缆规格中能够承载的最大功率 (单位: MW)。
|
||||
|
||||
@@ -514,6 +580,8 @@ def get_max_cable_capacity_mw(cable_specs=None):
|
||||
|
||||
参数:
|
||||
cable_specs (list, optional): 电缆规格列表。每个元素应包含 (截面积, 额定电流, 单价, 损耗系数)。
|
||||
voltage (float): 系统电压 (V), 默认 66000
|
||||
power_factor (float): 功率因数, 默认 0.95
|
||||
|
||||
返回:
|
||||
float: 最大功率承载能力 (MW)。
|
||||
@@ -541,13 +609,13 @@ def get_max_cable_capacity_mw(cable_specs=None):
|
||||
# 计算最大功率:P = √3 * U * I * cosφ
|
||||
# 这里假设降额系数为 1 (不降额)
|
||||
max_current = max_current_capacity * 1
|
||||
max_power_w = np.sqrt(3) * VOLTAGE_LEVEL * max_current * POWER_FACTOR
|
||||
max_power_w = np.sqrt(3) * voltage * max_current * power_factor
|
||||
|
||||
# 将单位从 W 转换为 MW
|
||||
return max_power_w / 1e6
|
||||
|
||||
# 5. 计算集电线路方案成本
|
||||
def evaluate_design(turbines, connections, substation, cable_specs=None, is_offshore=False, method_name="Unknown Method"):
|
||||
def evaluate_design(turbines, connections, substation, cable_specs=None, is_offshore=False, method_name="Unknown Method", voltage=VOLTAGE_LEVEL, power_factor=POWER_FACTOR):
|
||||
"""评估设计方案的总成本和损耗"""
|
||||
total_cost = 0
|
||||
total_loss = 0
|
||||
@@ -582,8 +650,8 @@ def evaluate_design(turbines, connections, substation, cable_specs=None, is_offs
|
||||
try:
|
||||
# 找到通往升压站的最短路径上的下一个节点
|
||||
path = nx.shortest_path(graph, source=node, target='substation')
|
||||
if len(path) > 1:
|
||||
parent = path[1] # path[0]是node自己,path[1]是父节点
|
||||
if len(path) > 1: # path[0]是node自己,path[1]是父节点
|
||||
parent = path[1]
|
||||
power_flow[parent] += power_flow[node]
|
||||
except nx.NetworkXNoPath:
|
||||
pass
|
||||
@@ -650,7 +718,7 @@ def evaluate_design(turbines, connections, substation, cable_specs=None, is_offs
|
||||
cable_specs_to_use = cable_specs
|
||||
|
||||
# 估算电流
|
||||
current = (power * 1e6) / (np.sqrt(3) * VOLTAGE_LEVEL * POWER_FACTOR)
|
||||
current = (power * 1e6) / (np.sqrt(3) * voltage * power_factor)
|
||||
|
||||
# 选择满足载流量的最小电缆
|
||||
selected_spec = None
|
||||
@@ -842,7 +910,8 @@ def export_all_scenarios_to_excel(results, filename):
|
||||
:param filename: 输出文件路径
|
||||
"""
|
||||
try:
|
||||
with pd.ExcelWriter(filename) as writer:
|
||||
# 使用 openpyxl 引擎以便后续写入单元格
|
||||
with pd.ExcelWriter(filename, engine='openpyxl') as writer:
|
||||
# 1. 总览 Sheet
|
||||
summary_data = []
|
||||
for res in results:
|
||||
@@ -865,7 +934,7 @@ def export_all_scenarios_to_excel(results, filename):
|
||||
# 2. 每个方案的详细 Sheet
|
||||
for res in results:
|
||||
# 清理 Sheet 名称
|
||||
safe_name = res['name'].replace(':', '').replace('/', '-').replace('\\', '-')
|
||||
safe_name = res['name'].replace(':', '').replace('/', '-').replace('\\', '-').replace(' ', '_')
|
||||
# 截断过长的名称 (Excel限制31字符)
|
||||
if len(safe_name) > 25:
|
||||
safe_name = safe_name[:25]
|
||||
@@ -886,7 +955,13 @@ def export_all_scenarios_to_excel(results, filename):
|
||||
'Cost (¥)': conn['cable']['cost']
|
||||
})
|
||||
df = pd.DataFrame(data)
|
||||
df.to_excel(writer, sheet_name=safe_name, index=False)
|
||||
|
||||
# 从第 2 行开始写入数据(startrow=1,Excel中为第2行),留出第 1 行写标题
|
||||
df.to_excel(writer, sheet_name=safe_name, index=False, startrow=1)
|
||||
|
||||
# 在第一行写入方案名称
|
||||
ws = writer.sheets[safe_name]
|
||||
ws.cell(row=1, column=1, value=f"Scenario: {res['name']}")
|
||||
|
||||
print(f"成功导出包含所有方案的Excel文件: {filename}")
|
||||
except Exception as e:
|
||||
@@ -976,10 +1051,10 @@ def visualize_design(turbines, substation, connections, title, ax=None, show_cos
|
||||
legend_handles[section] = line
|
||||
|
||||
# 打印统计信息
|
||||
if is_detailed:
|
||||
print(f"[{title.splitlines()[0]}] 电缆统计:")
|
||||
for section in sorted(cable_counts.keys()):
|
||||
print(f" {section}mm²: {cable_counts[section]} 条")
|
||||
# if is_detailed:
|
||||
# print(f"[{title.splitlines()[0]}] 电缆统计:")
|
||||
# for section in sorted(cable_counts.keys()):
|
||||
# print(f" {section}mm²: {cable_counts[section]} 条")
|
||||
|
||||
# 设置图形属性
|
||||
ax.set_title(title, fontsize=10)
|
||||
@@ -1004,21 +1079,25 @@ def visualize_design(turbines, substation, connections, title, ax=None, show_cos
|
||||
return ax
|
||||
|
||||
# 7. 主函数:比较两种设计方法
|
||||
def compare_design_methods(excel_path=None, n_clusters_override=None):
|
||||
def compare_design_methods(excel_path=None, n_clusters_override=None, interactive=True, plot_results=True):
|
||||
"""
|
||||
比较MST和三种电缆方案下的K-means设计方法
|
||||
:param excel_path: Excel文件路径
|
||||
:param n_clusters_override: 可选,手动指定簇的数量
|
||||
:param interactive: 是否启用交互式导出 (CLI模式)
|
||||
:param plot_results: 是否生成和保存对比图表
|
||||
"""
|
||||
cable_specs = None
|
||||
system_params = {}
|
||||
|
||||
if excel_path:
|
||||
print(f"正在从 {excel_path} 读取坐标数据...")
|
||||
try:
|
||||
turbines, substation, cable_specs = load_data_from_excel(excel_path)
|
||||
turbines, substation, cable_specs, system_params = load_data_from_excel(excel_path)
|
||||
scenario_title = "Offshore Wind Farm (Imported Data)"
|
||||
except Exception:
|
||||
print("回退到自动生成数据模式...")
|
||||
return compare_design_methods(excel_path=None, n_clusters_override=n_clusters_override)
|
||||
return compare_design_methods(excel_path=None, n_clusters_override=n_clusters_override, interactive=interactive, plot_results=plot_results)
|
||||
else:
|
||||
print("正在生成海上风电场数据 (规则阵列布局)...")
|
||||
turbines, substation = generate_wind_farm_data(n_turbines=30, layout='grid', spacing=800)
|
||||
@@ -1026,10 +1105,19 @@ def compare_design_methods(excel_path=None, n_clusters_override=None):
|
||||
|
||||
is_offshore = True
|
||||
|
||||
voltage = system_params.get('voltage', VOLTAGE_LEVEL)
|
||||
power_factor = system_params.get('power_factor', POWER_FACTOR)
|
||||
print(f"使用的系统参数: 电压={voltage} V, 功率因数={power_factor}")
|
||||
|
||||
# 准备三种电缆方案
|
||||
# 原始 specs 是 5 元素元组: (section, capacity, resistance, cost, is_optional)
|
||||
# 下游函数期望 4 元素元组: (section, capacity, resistance, cost)
|
||||
has_optional_cables = False
|
||||
|
||||
if cable_specs:
|
||||
# 检查是否存在 Optional 为 Y 的电缆
|
||||
has_optional_cables = any(s[4] for s in cable_specs)
|
||||
|
||||
# 方案 1: 不含 Optional='Y' (Standard)
|
||||
specs_1 = [s[:4] for s in cable_specs if not s[4]]
|
||||
|
||||
@@ -1049,25 +1137,34 @@ def compare_design_methods(excel_path=None, n_clusters_override=None):
|
||||
specs_1 = default_specs
|
||||
specs_2 = default_specs
|
||||
specs_3 = default_specs[:-1]
|
||||
# 默认库视为没有 optional
|
||||
has_optional_cables = False
|
||||
|
||||
scenarios = [
|
||||
("Scenario 1 (Standard)", specs_1),
|
||||
("Scenario 2 (With Optional)", specs_2),
|
||||
("Scenario 3 (No Max)", specs_3)
|
||||
("Scenario 1 (Standard)", specs_1)
|
||||
]
|
||||
|
||||
if has_optional_cables:
|
||||
scenarios.append(("Scenario 2 (With Optional)", specs_2))
|
||||
scenarios.append(("Scenario 3 (No Max)", specs_3))
|
||||
else:
|
||||
# 重新编号,保证连续性
|
||||
scenarios.append(("Scenario 2 (No Max)", specs_3))
|
||||
|
||||
# 1. MST 方法作为基准 (使用 Scenario 1)
|
||||
mst_connections = design_with_mst(turbines, substation)
|
||||
mst_evaluation = evaluate_design(turbines, mst_connections, substation, cable_specs=specs_1, is_offshore=is_offshore, method_name="MST Method")
|
||||
mst_evaluation = evaluate_design(turbines, mst_connections, substation, cable_specs=specs_1, is_offshore=is_offshore, method_name="MST Method", voltage=voltage, power_factor=power_factor)
|
||||
|
||||
# 准备画布 2x2
|
||||
fig, axes = plt.subplots(2, 2, figsize=(20, 18))
|
||||
axes = axes.flatten()
|
||||
|
||||
# 绘制 MST
|
||||
visualize_design(turbines, substation, mst_evaluation['details'],
|
||||
f"MST Method (Standard Cables)\nTotal Cost: ¥{mst_evaluation['total_cost']/10000:.2f}万",
|
||||
ax=axes[0])
|
||||
fig = None
|
||||
axes = []
|
||||
if plot_results:
|
||||
fig, axes = plt.subplots(2, 2, figsize=(20, 18))
|
||||
axes = axes.flatten()
|
||||
# 绘制 MST
|
||||
visualize_design(turbines, substation, mst_evaluation['details'],
|
||||
f"MST Method (Standard Cables)\nTotal Cost: ¥{mst_evaluation['total_cost']/10000:.2f}万",
|
||||
ax=axes[0])
|
||||
|
||||
print(f"\n===== 开始比较电缆方案 =====")
|
||||
|
||||
@@ -1094,7 +1191,7 @@ def compare_design_methods(excel_path=None, n_clusters_override=None):
|
||||
|
||||
# 计算参数
|
||||
total_power = turbines['power'].sum()
|
||||
max_cable_mw = get_max_cable_capacity_mw(cable_specs=current_specs)
|
||||
max_cable_mw = get_max_cable_capacity_mw(cable_specs=current_specs, voltage=voltage, power_factor=power_factor)
|
||||
|
||||
# 确定簇数 (针对 Base 算法)
|
||||
if n_clusters_override is not None:
|
||||
@@ -1114,11 +1211,11 @@ def compare_design_methods(excel_path=None, n_clusters_override=None):
|
||||
# --- Run 1: Base Algorithm (Capacitated Sweep) ---
|
||||
base_name = f"{name} (Base)"
|
||||
conns_base, turbines_base = design_with_capacitated_sweep(
|
||||
turbines.copy(), substation, cable_specs=current_specs
|
||||
turbines.copy(), substation, cable_specs=current_specs, voltage=voltage, power_factor=power_factor
|
||||
)
|
||||
eval_base = evaluate_design(
|
||||
turbines, conns_base, substation, cable_specs=current_specs,
|
||||
is_offshore=is_offshore, method_name=base_name
|
||||
is_offshore=is_offshore, method_name=base_name, voltage=voltage, power_factor=power_factor
|
||||
)
|
||||
|
||||
comparison_results.append({
|
||||
@@ -1134,11 +1231,11 @@ def compare_design_methods(excel_path=None, n_clusters_override=None):
|
||||
# --- Run 2: Rotational Algorithm (Optimization) ---
|
||||
rot_name = f"{name} (Rotational)"
|
||||
conns_rot, turbines_rot = design_with_rotational_sweep(
|
||||
turbines.copy(), substation, cable_specs=current_specs
|
||||
turbines.copy(), substation, cable_specs=current_specs, voltage=voltage, power_factor=power_factor
|
||||
)
|
||||
eval_rot = evaluate_design(
|
||||
turbines, conns_rot, substation, cable_specs=current_specs,
|
||||
is_offshore=is_offshore, method_name=rot_name
|
||||
is_offshore=is_offshore, method_name=rot_name, voltage=voltage, power_factor=power_factor
|
||||
)
|
||||
|
||||
comparison_results.append({
|
||||
@@ -1158,7 +1255,7 @@ def compare_design_methods(excel_path=None, n_clusters_override=None):
|
||||
)
|
||||
eval_ew = evaluate_design(
|
||||
turbines, conns_ew, substation, cable_specs=current_specs,
|
||||
is_offshore=is_offshore, method_name=ew_name
|
||||
is_offshore=is_offshore, method_name=ew_name, voltage=voltage, power_factor=power_factor
|
||||
)
|
||||
|
||||
comparison_results.append({
|
||||
@@ -1184,15 +1281,17 @@ def compare_design_methods(excel_path=None, n_clusters_override=None):
|
||||
|
||||
# 可视化 (只画 Base 版本)
|
||||
ax_idx = i + 1
|
||||
if ax_idx < 4:
|
||||
if plot_results and ax_idx < 4:
|
||||
n_circuits = turbines_base['cluster'].nunique()
|
||||
title = f"{base_name} ({n_circuits} circuits)\nCost: ¥{eval_base['total_cost']/10000:.2f}万"
|
||||
visualize_design(turbines_base, substation, eval_base['details'], title, ax=axes[ax_idx])
|
||||
|
||||
plt.tight_layout()
|
||||
output_filename = 'wind_farm_design_comparison.png'
|
||||
plt.savefig(output_filename, dpi=300)
|
||||
print(f"\n比较图(Base版)已保存至: {output_filename}")
|
||||
if plot_results:
|
||||
plt.tight_layout()
|
||||
output_filename = 'wind_farm_design_comparison.png'
|
||||
plt.savefig(output_filename, dpi=300)
|
||||
plt.close()
|
||||
print(f"\n比较图(Base版)已保存至: {output_filename}")
|
||||
|
||||
# 准备文件路径
|
||||
if excel_path:
|
||||
@@ -1208,6 +1307,10 @@ def compare_design_methods(excel_path=None, n_clusters_override=None):
|
||||
if comparison_results:
|
||||
export_all_scenarios_to_excel(comparison_results, excel_out_filename)
|
||||
|
||||
if not interactive:
|
||||
print(f"非交互模式:已自动导出 Excel 对比报表: {excel_out_filename}")
|
||||
return comparison_results
|
||||
|
||||
# 交互式选择导出 DXF
|
||||
print("\n===== 方案选择 =====")
|
||||
best_idx = 0
|
||||
@@ -1240,13 +1343,25 @@ def compare_design_methods(excel_path=None, n_clusters_override=None):
|
||||
choice = best_idx
|
||||
|
||||
selected_res = comparison_results[choice]
|
||||
print(f"正在导出 '{selected_res['name']}' 到 DXF: {dxf_filename} ...")
|
||||
export_to_dxf(selected_res['turbines'], substation, selected_res['eval']['details'], dxf_filename)
|
||||
|
||||
# 生成带方案名称的文件名
|
||||
base_dxf_name, ext = os.path.splitext(dxf_filename)
|
||||
safe_suffix = selected_res['name'].replace(' ', '_').replace(':', '').replace('(', '').replace(')', '').replace('/', '-')
|
||||
final_filename = f"{base_dxf_name}_{safe_suffix}{ext}"
|
||||
|
||||
print(f"正在导出 '{selected_res['name']}' 到 DXF: {final_filename} ...")
|
||||
export_to_dxf(selected_res['turbines'], substation, selected_res['eval']['details'], final_filename)
|
||||
except Exception as e:
|
||||
print(f"输入处理出错: {e},将使用默认推荐方案。")
|
||||
selected_res = comparison_results[best_idx]
|
||||
print(f"正在导出 '{selected_res['name']}' 到 DXF: {dxf_filename} ...")
|
||||
export_to_dxf(selected_res['turbines'], substation, selected_res['eval']['details'], dxf_filename)
|
||||
|
||||
# 生成带方案名称的文件名
|
||||
base_dxf_name, ext = os.path.splitext(dxf_filename)
|
||||
safe_suffix = selected_res['name'].replace(' ', '_').replace(':', '').replace('(', '').replace(')', '').replace('/', '-')
|
||||
final_filename = f"{base_dxf_name}_{safe_suffix}{ext}"
|
||||
|
||||
print(f"正在导出 '{selected_res['name']}' 到 DXF: {final_filename} ...")
|
||||
export_to_dxf(selected_res['turbines'], substation, selected_res['eval']['details'], final_filename)
|
||||
|
||||
return comparison_results
|
||||
|
||||
@@ -1260,4 +1375,4 @@ if __name__ == "__main__":
|
||||
|
||||
# 3. 运行比较
|
||||
# 如果没有提供excel文件,将自动回退到生成数据模式
|
||||
compare_design_methods(args.excel, n_clusters_override=args.clusters)
|
||||
compare_design_methods(args.excel, n_clusters_override=args.clusters, interactive=True)
|
||||
|
||||
BIN
使用说明/CAD图纸效果示例.png
Normal file
BIN
使用说明/CAD图纸效果示例.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
163
使用说明/使用说明.md
Normal file
163
使用说明/使用说明.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# 海上风电场集电线路设计优化软件 - 操作手册
|
||||
|
||||
**文档版本:** v1.0
|
||||
**适用对象:** 海上能源业务开发部 - 电气专业组
|
||||
**编制日期:** 2026年1月5日
|
||||
|
||||
---
|
||||
|
||||
## 1. 软件概述
|
||||
|
||||
本软件专为海上风电场内集电系统(35kV/66kV/110kV)设计,旨在通过多种先进的拓扑优化算法(如Esau-Williams、MST、旋转扫描法),辅助电气工程师快速完成集电线路的路径规划与经济性比选。
|
||||
|
||||
软件能够根据风机坐标、海缆载流量及造价数据,自动计算并生成线损最小、投资最优的接线方案,并支持一键导出 CAD 图纸和海缆长度。
|
||||
|
||||
---
|
||||
|
||||
## 2. 准备工作:输入数据编制
|
||||
|
||||
软件通过读取 Excel 文件获取设计输入条件。为了确保计算准确,请严格按照以下格式准备数据。
|
||||
|
||||
### 2.1 获取标准模板
|
||||
启动软件后,点击左侧配置面板顶部的 **“导出 Excel 模板”** 按钮,保存 `coordinates.xlsx` 文件。建议在此模板基础上进行修改。
|
||||
|
||||

|
||||
|
||||
### 2.2 数据表详解
|
||||
|
||||
输入文件通常包含三个 Sheet(工作表):
|
||||

|
||||
#### (1) Coordinates (坐标数据) - **[必须]**
|
||||
录入升压站和所有风机的位置及参数。
|
||||
* **Type**: 填写 `Substation` (升压站) 或 `Turbine` (风机)。
|
||||
* **ID**: 设备编号(如 Sub1, 01, 02...)。
|
||||
* **X / Y**: 投影坐标(单位:米)。建议使用高斯投影坐标 (X, Y),以保证距离计算准确。
|
||||
* **Power**: 设备功率(单位:MW)。升压站填 0。
|
||||
* **PlatformHeight**: 塔筒/升压站平台高度(单位:米),用于计算海缆爬升段长度。
|
||||
|
||||
<!--  -->
|
||||
|
||||
#### (2) Cables (电缆规格) - **[必须]**
|
||||
录入本项目拟采用的海缆截面库。
|
||||
* **Section**: 导体截面 (mm²)。
|
||||
* **Capacity**: 额定载流量 (A)。**注意:** 需填入考虑降容系数后的实际允许载流量。
|
||||
* **Resistance**: 交流电阻 (Ω/km)。
|
||||
* **Cost**: 综合单价 (元/m)。包含本体及敷设费用。
|
||||
* **Optional**: 可选标记。
|
||||
* 填 `Y`: 表示该型号为“可选大截面电缆”(例如仅在特定大负荷回路使用)。
|
||||
* *规则:* 列表中必须按截面**从小到大**排序。
|
||||
|
||||
#### (3) Parameters (系统参数) - **[必须]**
|
||||
定义系统级电气参数。
|
||||
* **Voltage**: 集电系统标称电压(如 66 或 35),单位 kV。
|
||||
* **Power Factor**: 系统功率因数(如 0.95)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 算法与优化策略介绍
|
||||
|
||||
本软件内置了四种不同机制的拓扑优化算法,分别适用于不同的工程场景。在点击“运行”后,系统会并发执行所有算法,模型自动筛选最优解。
|
||||
|
||||
### 3.1 最小生成树算法 (MST Method)
|
||||
* **原理**:基于图论中的 Kruskal 或 Prim 算法,寻找连接所有风机且总路径长度最短的树状结构。此算法**不考虑电缆载流量限制**。
|
||||
* **作用**:仅作为理论上的“距离基准”参考。它展示了如果导线无限粗、电流无限制情况下的最短布线可能。在实际工程中通常不可行,但可用于评估其他方案的距离效率。
|
||||
|
||||
### 3.2 基础扇区扫描法 (Capacitated Sweep - Base)
|
||||
* **原理**:以升压站为中心,将平面划分为若干个扇区。算法按顺时针方向扫描风机,一旦累积功率达到当前最大电缆的承载上限,就进行“切分”,形成一个独立的集电回路。
|
||||
* **特点**:计算速度极快,拓扑结构简单清晰,类似于人工排布的辐射状接线。
|
||||
* **局限**:对起始扫描角度敏感,可能因为恰好在某个位置切分而导致该回路包含距离很远的风机。
|
||||
|
||||
### 3.3 旋转扫描优化法 (Rotational Sweep)
|
||||
* **原理**:这是对“基础扇区扫描法”的增强版。它会自动尝试 0° 到 360° 之间的所有可能的起始扫描角度。
|
||||
* **优势**:通过旋转扫描角度,可以有效避免因特定方位角切分不当造成的“长尾巴”连线,通常能比基础扫描法节省 3%~8% 的线缆成本。这是最接近人工精细化排布的自动化算法。
|
||||
|
||||
### 3.4 Esau-Williams 启发式算法 (Esau-Williams Heuristic)
|
||||
* **原理**:经典的约束最小生成树(CMST)算法。它从“所有风机都直连升压站”的初始状态开始,迭代计算“将两台风机互联并断开其中一条回升压站连线”所能带来的成本节省(Trade-off)。在满足载流量约束的前提下,优先执行节省最大的互联操作。
|
||||
* **优势**:能够跳出辐射状的思维定式,自动发现树状、多分叉等复杂但更经济的拓扑结构。在风机分布不规则、离岸距离较远或电缆造价极高的情况下,往往能得到比扫描法更优的结果。
|
||||
|
||||
---
|
||||
|
||||
## 4. 操作流程
|
||||
|
||||
### 步骤一:启动软件
|
||||
双击运行程序,等待主界面加载完成。界面分为上侧“操作区”和下侧“结果展示区”。
|
||||
|
||||
### 步骤二:上传数据
|
||||
在上侧“配置面板”中,点击 **“选择Excel文件”** 区域(或点击云朵图标),选择编制好的项目 Excel 文件。
|
||||
|
||||
上传成功后:
|
||||
1. 文件名右侧会出现绿色对勾。
|
||||
2. 右侧信息面板会自动解析并显示**系统参数**(电压、功率因数)和**电缆规格列表**,请务必核对这些数据是否正确。
|
||||
|
||||

|
||||
|
||||
### 步骤三:运行计算
|
||||
点击左侧下方的大型按钮 **“运行方案对比”**。
|
||||
|
||||
软件将自动执行以下计算任务:
|
||||
1. **多场景分析**:
|
||||
* *Scenario 1 (标准)*:仅使用标准电缆库进行优化。
|
||||
* *Scenario 2 (含可选)*:尝试引入更大截面的可选电缆,评估是否能减少回路数。
|
||||
* *Scenario 3 (限制)*:模拟最大截面电缆缺货情况下的次优方案。
|
||||
2. **多算法寻优**:对每个场景同时运行 MST、基础扫描、旋转扫描、Esau-Williams 等多种算法。
|
||||
|
||||
*注意:计算过程中下方黑色日志窗口会实时滚动显示计算进度,通常耗时 10-60 秒,取决于风机数量。*
|
||||
|
||||

|
||||
|
||||
### 步骤四:查看与比选
|
||||
计算完成后,系统会自动筛选出**综合造价最低**的推荐方案,并在界面上展示。
|
||||
|
||||
1. **结果列表**:
|
||||
右侧中部的表格列出了所有计算出的可行方案。
|
||||
* `Cost (万元)`:总投资估算。
|
||||
* `Loss (kW)`:全场集电线路总线损。
|
||||
* **操作**:点击表格中的任意一行,下方的拓扑图会自动切换到该方案。
|
||||
|
||||
2. **拓扑可视化**:
|
||||
右侧下方的绘图区展示集电线路走向。
|
||||
* 不同颜色的线条代表不同截面的海缆。
|
||||
* 图例会标明线型对应的截面。
|
||||
* 升压站显示为红色方块,风机为圆点。
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 5. 成果导出
|
||||
|
||||
比选确定最终方案后,可以使用底部的 **“导出与下载”** 功能区生成设计文件。
|
||||
|
||||
### 5.1 导出 CAD 图纸 (.dxf)
|
||||
* **导出推荐方案**:直接点击 **“导出推荐方案 DXF”**。
|
||||
* **导出特定方案**:在表格中选中任意一行,点击 **“导出选中方案 DXF”**。
|
||||
|
||||
生成的 DXF 文件特点:
|
||||
* **分层管理**:不同截面的电缆位于不同图层(Layer),方便在 AutoCAD 中通过图层过滤器批量修改线型或颜色。
|
||||
* **地理坐标**:图纸保留了 Excel 中的原始坐标系,可直接通过“原点粘贴”功能合并到项目总图中。
|
||||
|
||||

|
||||
|
||||
### 5.2 导出 Excel 报告
|
||||
点击 **“下载 Excel 对比表”**,将生成一份包含详细工程数据的 Excel 文件,内容包括:
|
||||
* **Summary**: 所有方案的经济技术指标汇总。
|
||||
* **Details**: 推荐方案的每一条海缆连接明细(起点、终点、长度、型号、负载率)。
|
||||
|
||||
### 5.3 批量归档
|
||||
点击 **“导出全部方案 DXF (ZIP)”**,可将所有计算产生的方案图纸和报表打包下载,便于项目归档。
|
||||
|
||||
---
|
||||
|
||||
## 6. 常见问题 (FAQ)
|
||||
|
||||
**Q: 为什么上传文件后提示“电缆数据校验失败”?**
|
||||
A: 请检查 `Cables` 表。电缆必须严格按照**截面从小到大**排列,且载流量也必须随截面增加而增加。如果定义了 `Optional` 电缆,它必须是列表中截面最大的一条。
|
||||
|
||||
**Q: 计算出的方案有的回路负载率过高怎么办?**
|
||||
A: 软件算法以不超过额定载流量为约束条件(默认允许 100% 满载)。在实际工程中,建议在 `Cables` 表录入载流量时,预先乘以 0.95 或其他安全系数,留出裕度。
|
||||
|
||||
**Q: 图纸导出后,在 CAD 里看不到东西?**
|
||||
A: 请双击鼠标滚轮(Zoom Extents)全屏显示。由于风机坐标通常是大地坐标(数值很大),如果 CAD 当前视口在 (0,0) 附近,可能会找不到图形。
|
||||
|
||||
---
|
||||
**技术支持:** 海上能源业务开发部 - 数字化小组
|
||||
BIN
使用说明/导出模板按钮截图.png
Normal file
BIN
使用说明/导出模板按钮截图.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
BIN
使用说明/数据加载成功截图.png
Normal file
BIN
使用说明/数据加载成功截图.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 108 KiB |
BIN
使用说明/结果比选交互截图.png
Normal file
BIN
使用说明/结果比选交互截图.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 192 KiB |
BIN
使用说明/计算过程截图.png
Normal file
BIN
使用说明/计算过程截图.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 121 KiB |
BIN
使用说明/输入数据表.png
Normal file
BIN
使用说明/输入数据表.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
Reference in New Issue
Block a user