AnsysLink/scripts/demo_launcher.py

478 lines
15 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
CAE Mesh Generator - Demo Launcher
演示版本启动器,包含完整的系统检查和演示数据准备
"""
import os
import sys
import shutil
import subprocess
import webbrowser
import time
from pathlib import Path
from datetime import datetime
class DemoLauncher:
def __init__(self):
self.project_root = Path(__file__).parent.parent # 上一级目录
self.demo_data_dir = self.project_root / 'demo_data'
self.demo_port = 5000
self.demo_url = f'http://localhost:{self.demo_port}'
def print_banner(self):
"""打印演示横幅"""
print("=" * 70)
print("🚀 CAE网格生成助手 - 演示版本")
print(" 基于AI的自动化涡扇叶片网格生成系统")
print("=" * 70)
print(f"启动时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"项目目录: {self.project_root}")
print(f"演示地址: {self.demo_url}")
print("=" * 70)
def check_python_version(self):
"""检查Python版本"""
print("\n📋 检查Python版本...")
version = sys.version_info
if version.major < 3 or (version.major == 3 and version.minor < 8):
print(f"❌ Python版本过低: {version.major}.{version.minor}")
print(" 需要Python 3.8或更高版本")
return False
print(f"✅ Python版本: {version.major}.{version.minor}.{version.micro}")
return True
def check_dependencies(self):
"""检查依赖包"""
print("\n📦 检查依赖包...")
required_packages = [
('flask', 'Flask'),
('werkzeug', 'Werkzeug'),
]
optional_packages = [
('ansys.mechanical.core', 'ANSYS Mechanical'),
]
missing_required = []
missing_optional = []
# 检查必需包
for package, name in required_packages:
try:
__import__(package)
print(f"{name}: 已安装")
except ImportError:
print(f"{name}: 未安装")
missing_required.append(package)
# 检查可选包
for package, name in optional_packages:
try:
__import__(package)
print(f"{name}: 已安装 (完整功能)")
except ImportError:
print(f"⚠️ {name}: 未安装 (将使用演示模式)")
missing_optional.append(package)
if missing_required:
print(f"\n❌ 缺少必需依赖: {', '.join(missing_required)}")
print("请运行: pip install -r requirements.txt")
return False
if missing_optional:
print(f"\n⚠️ 缺少可选依赖: {', '.join(missing_optional)}")
print("系统将在演示模式下运行")
return True
def setup_directories(self):
"""设置目录结构"""
print("\n📁 设置目录结构...")
directories = [
'uploads',
'results',
'temp',
'static/css',
'static/js',
'static/visualizations',
'templates',
'demo_data',
'logs'
]
for directory in directories:
dir_path = self.project_root / directory
dir_path.mkdir(parents=True, exist_ok=True)
print(f"{directory}/")
return True
def create_demo_data(self):
"""创建演示数据"""
print("\n🎯 准备演示数据...")
# 创建示例STEP文件
sample_step_files = [
('simple_blade.step', self.create_simple_blade_step()),
('complex_blade.step', self.create_complex_blade_step()),
('test_geometry.step', self.create_test_geometry_step())
]
for filename, content in sample_step_files:
file_path = self.demo_data_dir / filename
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
print(f"✅ 创建示例文件: {filename}")
# 创建演示说明文件
demo_guide = self.create_demo_guide()
guide_path = self.demo_data_dir / 'DEMO_GUIDE.md'
with open(guide_path, 'w', encoding='utf-8') as f:
f.write(demo_guide)
print(f"✅ 创建演示指南: DEMO_GUIDE.md")
return True
def create_simple_blade_step(self):
"""创建简单叶片STEP文件"""
return """ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('Simple Turbine Blade for CAE Mesh Generator Demo'),'2;1');
FILE_NAME('simple_blade.step','2025-01-01T00:00:00',('Demo'),('CAE Mesh Generator'),'Demo System','ANSYS','');
FILE_SCHEMA(('AUTOMOTIVE_DESIGN'));
ENDSEC;
DATA;
/* 简单涡扇叶片几何定义 */
#1 = CARTESIAN_POINT('Origin',(0.0,0.0,0.0));
#2 = DIRECTION('X-Axis',(1.0,0.0,0.0));
#3 = DIRECTION('Y-Axis',(0.0,1.0,0.0));
#4 = DIRECTION('Z-Axis',(0.0,0.0,1.0));
#5 = AXIS2_PLACEMENT_3D('Global Coordinate System',#1,#4,#2);
/* 叶片轮廓点 */
#10 = CARTESIAN_POINT('Leading Edge Root',(0.0,0.0,0.0));
#11 = CARTESIAN_POINT('Trailing Edge Root',(50.0,0.0,0.0));
#12 = CARTESIAN_POINT('Leading Edge Tip',(5.0,0.0,100.0));
#13 = CARTESIAN_POINT('Trailing Edge Tip',(45.0,0.0,100.0));
/* 叶片表面定义 */
#20 = CARTESIAN_POINT('Pressure Side 1',(0.0,5.0,0.0));
#21 = CARTESIAN_POINT('Pressure Side 2',(25.0,8.0,0.0));
#22 = CARTESIAN_POINT('Pressure Side 3',(50.0,5.0,0.0));
#23 = CARTESIAN_POINT('Suction Side 1',(0.0,-5.0,0.0));
#24 = CARTESIAN_POINT('Suction Side 2',(25.0,-8.0,0.0));
#25 = CARTESIAN_POINT('Suction Side 3',(50.0,-5.0,0.0));
ENDSEC;
END-ISO-10303-21;"""
def create_complex_blade_step(self):
"""创建复杂叶片STEP文件"""
return """ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('Complex Turbine Blade with Cooling Channels for CAE Mesh Generator Demo'),'2;1');
FILE_NAME('complex_blade.step','2025-01-01T00:00:00',('Demo'),('CAE Mesh Generator'),'Demo System','ANSYS','');
FILE_SCHEMA(('AUTOMOTIVE_DESIGN'));
ENDSEC;
DATA;
/* 复杂涡扇叶片几何定义 - 包含冷却通道 */
#1 = CARTESIAN_POINT('Origin',(0.0,0.0,0.0));
#2 = DIRECTION('X-Axis',(1.0,0.0,0.0));
#3 = DIRECTION('Y-Axis',(0.0,1.0,0.0));
#4 = DIRECTION('Z-Axis',(0.0,0.0,1.0));
#5 = AXIS2_PLACEMENT_3D('Global Coordinate System',#1,#4,#2);
/* 主叶片几何 */
#10 = CARTESIAN_POINT('LE Root',(0.0,0.0,0.0));
#11 = CARTESIAN_POINT('TE Root',(60.0,0.0,0.0));
#12 = CARTESIAN_POINT('LE Tip',(8.0,0.0,120.0));
#13 = CARTESIAN_POINT('TE Tip',(52.0,0.0,120.0));
/* 冷却通道几何 */
#30 = CARTESIAN_POINT('Cooling Channel 1 Start',(15.0,0.0,10.0));
#31 = CARTESIAN_POINT('Cooling Channel 1 End',(15.0,0.0,110.0));
#32 = CARTESIAN_POINT('Cooling Channel 2 Start',(30.0,0.0,10.0));
#33 = CARTESIAN_POINT('Cooling Channel 2 End',(30.0,0.0,110.0));
#34 = CARTESIAN_POINT('Cooling Channel 3 Start',(45.0,0.0,10.0));
#35 = CARTESIAN_POINT('Cooling Channel 3 End',(45.0,0.0,110.0));
/* 叶片根部连接 */
#40 = CARTESIAN_POINT('Root Connection 1',(-5.0,0.0,-10.0));
#41 = CARTESIAN_POINT('Root Connection 2',(65.0,0.0,-10.0));
#42 = CARTESIAN_POINT('Root Connection 3',(30.0,0.0,-15.0));
ENDSEC;
END-ISO-10303-21;"""
def create_test_geometry_step(self):
"""创建测试几何STEP文件"""
return """ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('Test Geometry for CAE Mesh Generator Validation'),'2;1');
FILE_NAME('test_geometry.step','2025-01-01T00:00:00',('Test'),('CAE Mesh Generator'),'Test System','ANSYS','');
FILE_SCHEMA(('AUTOMOTIVE_DESIGN'));
ENDSEC;
DATA;
/* 测试几何 - 简单立方体用于验证 */
#1 = CARTESIAN_POINT('Origin',(0.0,0.0,0.0));
#2 = DIRECTION('X-Axis',(1.0,0.0,0.0));
#3 = DIRECTION('Y-Axis',(0.0,1.0,0.0));
#4 = DIRECTION('Z-Axis',(0.0,0.0,1.0));
#5 = AXIS2_PLACEMENT_3D('Global Coordinate System',#1,#4,#2);
/* 立方体顶点 */
#10 = CARTESIAN_POINT('Vertex 1',(0.0,0.0,0.0));
#11 = CARTESIAN_POINT('Vertex 2',(10.0,0.0,0.0));
#12 = CARTESIAN_POINT('Vertex 3',(10.0,10.0,0.0));
#13 = CARTESIAN_POINT('Vertex 4',(0.0,10.0,0.0));
#14 = CARTESIAN_POINT('Vertex 5',(0.0,0.0,10.0));
#15 = CARTESIAN_POINT('Vertex 6',(10.0,0.0,10.0));
#16 = CARTESIAN_POINT('Vertex 7',(10.0,10.0,10.0));
#17 = CARTESIAN_POINT('Vertex 8',(0.0,10.0,10.0));
ENDSEC;
END-ISO-10303-21;"""
def create_demo_guide(self):
"""创建演示指南"""
return """# CAE网格生成助手 - 演示指南
## 欢迎使用演示版本!
本演示系统展示了基于AI的自动化涡扇叶片网格生成功能。
### 🎯 演示目标
- 展示STEP文件上传和验证功能
- 演示自动化网格生成流程
- 展示网格质量检查和评估
- 展示结果可视化和导出功能
### 📁 演示文件说明
1. **simple_blade.step**
- 简单涡扇叶片几何
- 适合快速演示基本功能
- 预计处理时间30-60秒
2. **complex_blade.step**
- 复杂叶片几何,包含冷却通道
- 展示高级网格控制功能
- 预计处理时间2-5分钟
3. **test_geometry.step**
- 简单测试几何(立方体)
- 用于功能验证
- 预计处理时间10-30秒
### 🚀 演示流程
#### 步骤1文件上传
1. 打开演示网页界面
2. 点击上传区域或拖拽文件
3. 选择演示文件推荐从simple_blade.step开始
4. 等待文件验证完成
#### 步骤2网格生成
1. 文件上传成功后,点击"开始生成"按钮
2. 观察实时进度显示和处理日志
3. 系统将自动完成以下步骤:
- 几何导入和验证
- 自动识别关键区域
- 应用网格控制
- 生成网格
- 质量检查
#### 步骤3结果查看
1. 查看网格统计信息
2. 查看质量评估报告
3. 查看可视化结果(如果可用)
4. 下载结果文件
### 🔧 演示模式说明
- **完整模式**如果安装了ANSYS Mechanical将使用真实的网格生成功能
- **演示模式**如果未安装ANSYS将使用模拟数据展示完整流程
### 📊 预期结果
#### Simple Blade (简单叶片)
- 单元数量约8,000-12,000
- 节点数量约12,000-18,000
- 质量评分75-85分
- 生成时间30-60秒
#### Complex Blade (复杂叶片)
- 单元数量约25,000-40,000
- 节点数量约35,000-55,000
- 质量评分70-80分
- 生成时间2-5分钟
#### Test Geometry (测试几何)
- 单元数量约1,000-2,000
- 节点数量约1,500-3,000
- 质量评分85-95分
- 生成时间10-30秒
### 🎨 界面功能
#### 侧边栏
- 处理流程步骤显示
- 系统状态监控
- 实时进度更新
#### 主界面
- 文件上传区域
- 进度显示和日志
- 结果统计和可视化
- 导出选项
### 🔍 故障排除
#### 常见问题
1. **文件上传失败**
- 确认文件格式为.step或.stp
- 确认文件大小不超过100MB
- 检查文件是否损坏
2. **网格生成失败**
- 检查几何文件完整性
- 查看错误日志信息
- 尝试使用测试几何文件
3. **界面无响应**
- 刷新浏览器页面
- 检查网络连接
- 查看浏览器控制台错误
#### 技术支持
如遇到问题,请:
1. 查看浏览器控制台错误信息
2. 查看应用日志文件
3. 尝试重启演示系统
### 📈 性能优化建议
1. **文件选择**首次使用建议从simple_blade.step开始
2. **浏览器**推荐使用Chrome或Firefox最新版本
3. **系统资源**确保有足够的内存和CPU资源
### 🎉 演示完成后
演示完成后,您可以:
1. 查看生成的网格文件
2. 分析质量报告
3. 了解系统架构和技术实现
4. 探索更多高级功能
---
**祝您演示愉快!**
如有任何问题或建议,欢迎反馈。
"""
def check_port_availability(self):
"""检查端口可用性"""
print(f"\n🌐 检查端口 {self.demo_port} 可用性...")
import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
result = s.connect_ex(('localhost', self.demo_port))
if result == 0:
print(f"⚠️ 端口 {self.demo_port} 已被占用")
print("请关闭占用端口的程序或修改配置")
return False
else:
print(f"✅ 端口 {self.demo_port} 可用")
return True
def start_application(self):
"""启动应用程序"""
print(f"\n🚀 启动CAE网格生成助手...")
print(f"访问地址: {self.demo_url}")
print("按 Ctrl+C 停止应用")
print("-" * 50)
try:
# 添加项目根目录到Python路径
sys.path.insert(0, str(self.project_root))
# 启动Flask应用
from app import create_app
app = create_app()
# 延迟打开浏览器
def open_browser():
time.sleep(2)
print(f"\n🌐 正在打开浏览器: {self.demo_url}")
webbrowser.open(self.demo_url)
import threading
browser_thread = threading.Thread(target=open_browser, daemon=True)
browser_thread.start()
# 启动应用
app.run(
host='0.0.0.0',
port=self.demo_port,
debug=False,
use_reloader=False
)
except KeyboardInterrupt:
print("\n\n👋 演示已停止")
print("感谢使用CAE网格生成助手演示版本")
except Exception as e:
print(f"\n❌ 启动失败: {e}")
return False
return True
def run_demo(self):
"""运行完整演示"""
self.print_banner()
# 系统检查
checks = [
("Python版本", self.check_python_version),
("依赖包", self.check_dependencies),
("目录结构", self.setup_directories),
("演示数据", self.create_demo_data),
("端口可用性", self.check_port_availability)
]
for check_name, check_func in checks:
if not check_func():
print(f"\n{check_name}检查失败,演示无法启动")
return False
print("\n✅ 所有检查通过,准备启动演示...")
print("\n📖 演示指南已创建在 demo_data/DEMO_GUIDE.md")
print("建议先阅读演示指南了解使用方法")
# 询问是否继续
try:
response = input("\n是否现在启动演示?(y/N): ").strip().lower()
if response in ['y', 'yes', '']:
return self.start_application()
else:
print("\n演示已取消。您可以稍后运行此脚本启动演示。")
return True
except KeyboardInterrupt:
print("\n\n演示已取消。")
return True
def main():
"""主函数"""
launcher = DemoLauncher()
success = launcher.run_demo()
return 0 if success else 1
if __name__ == '__main__':
sys.exit(main())