dsh-plugin-pscad-expert-vyma 1.0.15 → 1.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/knowledge/emtdc_custom_element_norton.md +75 -0
- package/knowledge/templates_index.md +26 -1
- package/package.json +1 -1
- package/plugin.yaml +4 -1
- package/templates/_blank.pscx +124 -0
- package/templates/tmmb_norton_element.pscx +576 -0
- package/tools/main.py +120 -32
package/README.md
CHANGED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# EMTDC 自定义电气元件开发 SOP(Norton 等效 · 零矩阵重构 · 实证版)
|
|
2
|
+
|
|
3
|
+
> 来源:TMMB 热磁忆阻分支 v6 全链开发与验证(2026-08,PSCAD 5.0.0 / EMTDC gf46 / mhi.pscad 2.2.1)。
|
|
4
|
+
> 全部结论均经生成代码、官方 pslx/示例与对照仿真实证;三路验证(PSCAD ↔ 独立数值参考 ↔ 解析稳态)误差 <0.5%,关键案例逐位吻合。
|
|
5
|
+
|
|
6
|
+
## 一、数值离散(差分推导 → 实现)
|
|
7
|
+
|
|
8
|
+
元件方程:`v = R(w)·i + L0·di/dt`,`R(w) = RMIN + K·w²`,`dw/dt = α·v·i − β·w`。
|
|
9
|
+
|
|
10
|
+
**Norton 隐式梯形伴生模型**(每拍一次网络求解,无受控源一拍延迟):
|
|
11
|
+
```
|
|
12
|
+
G_eq = 1/(R(w) + 2·L0/Δt) # 分支等效电导
|
|
13
|
+
Z1 = R(w) − 2·L0/Δt
|
|
14
|
+
I_hist = (1 − Z1·G_eq)·G_eq·v_prev − Z1·G_eq·I_hist_prev # seriesrl2 官方递推
|
|
15
|
+
```
|
|
16
|
+
- L0=0 时 Z1·G_eq=1 → I_hist≡0(纯电阻无记忆),递推自动退化。
|
|
17
|
+
- 状态方程半隐式(β 隐式保证无条件稳定,功率项显式用上一拍):
|
|
18
|
+
`W_new = (W·(1 − βΔt/2) + α·Δt·v·i) / (1 + βΔt/2)`
|
|
19
|
+
- 代数环闭合:DSDYN 内 Picard 迭代 2–3 次闭合 W↔R 环(稳态零差异,瞬态跟踪改善);DSOUT 校正器为可选补足。**同拍 v,i 完全闭合对注入型组件无公开接口**(EMTDC 的网络迭代 ITN/EBRD 仅分支型元件可用,mmc 的 `EBRD(...)` 写入为证);显式功率 O(Δt) 是 EMTDC 官方非线性元件同款标准精度。
|
|
20
|
+
|
|
21
|
+
## 二、零重构电气接口(最终方案:CCBR/GEQ 分支注入)
|
|
22
|
+
|
|
23
|
+
**核心原则:矩阵静态 + 右端项注入分离。** 每拍开关/变值若改分支拓扑或矩阵电导,EMTDC 将重新三角分解导纳矩阵——大电网灾难(实测 v4 开关阵列方案即如此)。
|
|
24
|
+
|
|
25
|
+
```fortran
|
|
26
|
+
! Branch 段(可切换分支声明,官方 seriesrl2 范式):
|
|
27
|
+
BRR = $NA $NB BREAKER 1.0E6
|
|
28
|
+
|
|
29
|
+
! TIMEZERO(一次,放入 #BEGIN/#ENDBEGIN):
|
|
30
|
+
GEQ($BRR, $SS) = G0 ! 固定电导 → 导纳矩阵逐拍恒不变(零重构)
|
|
31
|
+
DEFRDBR($BRR, $SS) = .TRUE. ! 分支电流源外部驱动
|
|
32
|
+
|
|
33
|
+
! 每拍(仅 RHS,永不触发重构):
|
|
34
|
+
CCBR($BRR, $SS) = I_hist + (G(w) − G0)·V ! 非线性 + 历史电流全部走右端项
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- **G0 选择**:`G0 = 1/(2·RMIN + 2·L0/Δt)`;补偿项 `(G−G0)·V` 随**分支电压**缩放(悬浮场景分支电压小,误差可控);显式补偿稳定条件 `|G−G0|·Z_th < 2`。
|
|
38
|
+
- **性能实证**:5s/50 万步,GGIN 每拍变化 vs 固定:4.44s vs 4.53s——无显著重构开销;CCIN/CCBR 为 RHS 注入,数学上永不触发重构。
|
|
39
|
+
- **状态功率读回**:`V = VBRANCH($SS, $BRR)`(子系统在前);**电流勿读 CBR**(DEFRDBR 外部驱动分支的 CBR 读回符号不可靠,实测导致悬浮案例状态发散)——用 Norton 自洽电流 `I = G·V + I_hist`。
|
|
40
|
+
|
|
41
|
+
## 三、备选接口与实测结论(含陷阱)
|
|
42
|
+
|
|
43
|
+
| 接口 | 结论 |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `E_BRANCH_CFG` 每拍 | 第 6 参=R(Ω)非 G(peswitch 5000Ω/source 0.001Ω 实证);对普通 R 分支每拍调用=no-op(分支停在 TIMEZERO 值);peswitch 生效靠库内部切换 |
|
|
46
|
+
| `E_VARRLC1_EXE` 动态 Z | 低阻区(Z≈1)每拍变 Z 触发网络塌缩(V/I→0);只适合固定 Z+变化 E(MMC 电容模式) |
|
|
47
|
+
| `GEQ`/`E_BRANCH_CFG` 每拍直写 | no-op(无重构标记) |
|
|
48
|
+
| `CCIN/GGIN` 节点注入(seriesrl1) | 单节点/接地场景精确(CCIN=理想电流源实证:0.1kA→节点电压精确偏移 10kV);**GGIN 仅对地**——悬浮双端口跨导耦合须上拍显式化 → 弱网大补偿误差放大(138 倍相消案例 4.8%) |
|
|
49
|
+
| `E1PBRKR1` 开关段(v4 方案) | 每拍切换可行但触发重构 + 开断为 1ms 线性斜坡(瞬态滞后);PESWITCH1 有二极管方向性不适配双向电阻 |
|
|
50
|
+
|
|
51
|
+
## 四、存储与编译规范(踩坑实证)
|
|
52
|
+
|
|
53
|
+
- `#STORAGE REAL:N` 分配到 STORF 池;代码必须写 `STORF(NSTORF+k)` 且段末 `NSTORF = NSTORF + N` 自增。**误写 STORI(整数池)会覆盖相邻组件状态**——曾致源组件损坏、节点电压塌缩到 48V(最小变体二分定位)。
|
|
54
|
+
- `#LOCAL REAL W, V, I, R, G, DTB` 合并行会被生成器丢弃(只剩第一个)→ 隐式类型陷阱(I 变 INTEGER)→ 状态死;**必须每行一条**。
|
|
55
|
+
- `#BEGIN/#ENDBEGIN` 内容进 MainDyn_Begin——该子程序**不含 emtstor.h**,不能访问 STORF/STORI;状态初始化放主段 `IF (TIMEZERO)` 块。
|
|
56
|
+
- 库调用(PESWITCH1_CFG / E1PBRKR1_CFG / E_VARRLC1_CFG / GEQ/DEFRDBR)放 #BEGIN。
|
|
57
|
+
- 电压/电流回读参数顺序:`VBRANCH(SS, NBR)`(子系统在前,RE.f 实证)、`CBR(NBR, SS)` / `GEQ(NBR,SS)` / `CCBR(NBR,SS)`(分支在前);`NODE(INODE+1)−NODE(INODE+2)` 依赖节点分配顺序不可靠。
|
|
58
|
+
|
|
59
|
+
## 五、验证方法(三路对照,防伪造)
|
|
60
|
+
|
|
61
|
+
1. 独立 Python 离散参考:镜像 Fortran 每拍序列(同离散方案、同执行顺序、含源斜坡),逐拍对照。
|
|
62
|
+
2. 解析稳态第三对照:`β·W* = α·Vrms²·R*/(R*²+(ωL0)²)`(L0=0 退化为 `W*·(RMIN+K·W*²)=α·Vrms²/β`)。
|
|
63
|
+
3. **强判别案例**:L0=0.1H 时电感把 W* 从 4.57 压到 ~0.1、电流相位 ~88°——伴生模型与历史电流注入的细微错误都会显形。
|
|
64
|
+
4. source_1 特性:Vm 为 RMS;**启动有 0.05s 线性软启动** `E(t)=Vm·√2·sin(ωt)·min(t/0.05,1)`(包络采样实证)——数值参考必须含斜坡否则早期轨迹偏差;f=0 时源输出为零(无现成直流源)。
|
|
65
|
+
|
|
66
|
+
## 六、TMMB v6 验证结果(PSCAD ↔ 数值参考)
|
|
67
|
+
|
|
68
|
+
| 案例 | I(PSCAD/数值)kA | W(PSCAD/数值) |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| 接地 L0=0(α=1,K=1,RMIN=1,10kV/50Hz) | 0.4575 / 0.4573 | 4.5682 / 4.5678 |
|
|
71
|
+
| 接地 L0=0.1 | 0.3182 / 0.3182 | 0.0939 / 0.0934 |
|
|
72
|
+
| 悬浮 L0=0(NB 经 100Ω 接地) | 0.099 / 0.0990 | 0.009 / 0.0089 |
|
|
73
|
+
| 悬浮 L0=0.1 | 0.0945 / 0.0945 | 0.0082 / 0.0082(逐位精确) |
|
|
74
|
+
|
|
75
|
+
参考实现:`D:\PSCAD_Lab\scripts\r4_tmmb_v6.py`(元件 XML+验证)、`r4_tmmb_num.py`(数值参考)、`r4_tmmb_v5f.py`(悬浮两节点数值参考)、`r4_tmmb_inj.py`/`r4_tmmb_rt.py`(注入行为与重构计时探针)。
|
|
@@ -90,11 +90,35 @@
|
|
|
90
90
|
|
|
91
91
|
---
|
|
92
92
|
|
|
93
|
+
## 4. [tmmb_norton_element.pscx]
|
|
94
|
+
|
|
95
|
+
- **文件位置**:`templates/tmmb_norton_element.pscx`(仓库内副本;源工程 `.gf46` 含 exe + `*_01.out`,运行数据完整)
|
|
96
|
+
- **功能摘要**:**TMMB 热磁忆阻分支(自定义 Norton 元件)验证基准**——source_1(10kV/50Hz,内阻 0.001Ω)→ ammeter → **工程内自定义组件 `TMMB`(CCBR/GEQ 零重构 Norton 范式)** → ground;电压表并行;Wx 状态通道。TMMB 定义内嵌于 .pscx(`UserCmpDefn`),打开即用。参数:RMIN/K/ALPHA/BETA/L0(v=R(w)·i+L0·di/dt,R(w)=RMIN+K·w²,dw/dt=α·v·i−β·w)。L0=0.1 案例验证基准:I_rms≈0.318kA、W≈0.094(电感限制功率,强判别);接地/悬浮、L0=0/0.1 四案例三路对照全通过(详见 knowledge/emtdc_custom_element_norton.md)。
|
|
97
|
+
- **已固化的核心拓扑**(Main 画布):
|
|
98
|
+
| 元件(Name) | 类型 | 位置(网格) |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| Src | source_1(Vm=10kV,f=50Hz,R=0.001Ω) | (60, 200) |
|
|
101
|
+
| Ix | ammeter(回路电流) | (140, 200) |
|
|
102
|
+
| NRT1 | `<工程名>:TMMB`(RMIN=1, K=1, A=1, B=1, L0=0.1) | (220, 200) |
|
|
103
|
+
| G1 | ground | (300, 200) |
|
|
104
|
+
| Vx | voltmetergnd | (180, 150) |
|
|
105
|
+
| Wx/Vx/Ix | pgb 输出通道(Wx=TMMB.OUT 状态信号) | (500~550, 140~200) |
|
|
106
|
+
- **二次开发与扩展指南**:
|
|
107
|
+
- **坐标安全区**:单链结构,新增支路(悬浮负载电阻等)建议 x∈[320, 480]。
|
|
108
|
+
- **修改切入点**:
|
|
109
|
+
- **调参(最常用)**:`find_first('NRT1').parameters(RMIN=..., K=..., ALPHA=..., BETA=..., L0=...)`——L0 设 0 即纯忆阻、设 0.1 即含电感伴生。
|
|
110
|
+
- **悬浮双端口演示**:将 G1 从 NRT1.NB 断开,改接 100Ω 电阻到地(CCBR/GEQ 跨导矩阵内精确,悬浮场景无需补偿)。
|
|
111
|
+
- **Picard 代数环闭合**:工具 `create_norton_element(..., picard=2)` 生成含 2 次 DSDYN 内迭代的定义。
|
|
112
|
+
- **元件定义再生成**:TMMB XML 由 `tools/main.py` 的 `_norton_definition_xml()` 生成;改 XML 后重新 `prj.create_definition(...)`(#LOCAL 每行一条、#BEGIN 禁 STORF、Fortran 注释禁中文——踩坑固化)。
|
|
113
|
+
- **验证基准(三路对照)**:接地 L0=0:I≈0.4575/4.5682(数值 0.4573/4.5678);接地 L0=0.1:0.3182/0.0939(0.3182/0.0934);悬浮 L0=0.1:0.0945/0.0082 逐位精确。source_1 有 0.05s 线性软启动,数值对照须含斜坡。
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
93
117
|
## 备选池(同样验证成功,未入选原因)
|
|
94
118
|
- `line_model_pi_100km.pscx`(source3 单线图 + newpi 空载充电/Ferranti)——结构简单(4 元件),作为"最小线路模板"备用。
|
|
95
119
|
- `gfm_island_droop_nose.pscx`(双 GFM 孤岛下垂+鼻点)——历史经典,但坐标体系为旧布局(y 间距小),易与新代码冲突。
|
|
96
120
|
- `three_phase_cable_fault.pscx`(三相电缆故障,Cable_Coax+cable_interface)——电缆专项模板,无 GFM/控制链。
|
|
97
|
-
- 本仓库 `templates/` 收录
|
|
121
|
+
- 本仓库 `templates/` 收录 7 个验证通过的模板;PSCAD 主库(master.pslx)为安装自带资产,不入库。
|
|
98
122
|
|
|
99
123
|
## 选型速查
|
|
100
124
|
| 需求 | 用哪个模板 |
|
|
@@ -102,3 +126,4 @@
|
|
|
102
126
|
| 并网电压/容量/位置扫描 | **grid_gfm_support**(改 Xg 三处 + RLA 负荷) |
|
|
103
127
|
| 故障/短路/序分量研究 | **fault_study**(改 tbreak TC/TO 选相,独立案例) |
|
|
104
128
|
| 孤岛频率/下垂/自定义控制器 | **island_droop_controller**(改 DROOPC 参数) |
|
|
129
|
+
| 自定义电气元件/Norton 支路(TMMB 类) | **tmmb_norton_element**(改 NRT1 参数或工具 create_norton_element 重建) |
|
package/package.json
CHANGED
package/plugin.yaml
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# 由知识资产固化项目自动生成(2026-08-25)· 部署至 Git 仓库
|
|
4
4
|
# ============================================================
|
|
5
5
|
name: pscad-automation-expert
|
|
6
|
-
version: 1.0.
|
|
6
|
+
version: 1.0.17
|
|
7
7
|
description: PSCAD 自动化建模与仿真控制专家插件
|
|
8
8
|
|
|
9
9
|
# ---- 系统提示词(加载到 Agent 上下文最前置位置)----
|
|
@@ -38,6 +38,7 @@ knowledge_base:
|
|
|
38
38
|
preload:
|
|
39
39
|
- knowledge/pscad_skill_core.md # 核心技能库:元件 API/布线 SOP/TOP3 排错
|
|
40
40
|
- knowledge/templates_index.md # 基准模板索引与二次开发指南
|
|
41
|
+
- knowledge/emtdc_custom_element_norton.md # EMTDC 自定义元件 Norton 等效开发 SOP
|
|
41
42
|
|
|
42
43
|
# ---- 模板资产 ----
|
|
43
44
|
templates:
|
|
@@ -49,6 +50,8 @@ templates:
|
|
|
49
50
|
- line_model_pi_100km.pscx # source3 单线图 + newpi 线路(Ferranti 对照)
|
|
50
51
|
- gfm_island_droop_nose.pscx # 双 GFM 孤岛下垂 + 鼻点(历史经典)
|
|
51
52
|
- three_phase_cable_fault.pscx # 三相电缆故障(Cable_Coax 专项)
|
|
53
|
+
- tmmb_norton_element.pscx # TMMB 热磁忆阻 Norton 等效自定义元件基准(v6 三路验证)
|
|
54
|
+
- _blank.pscx # 最小空白工程模板(create_case 强落盘兜底)
|
|
52
55
|
|
|
53
56
|
# ---- 运行环境(无硬编码:路径由 init_pscad_environment 动态配置于运行时)----
|
|
54
57
|
runtime:
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
<project name="blank_probe_case" version="5.0.0" schema="" Target="EMTDC">
|
|
2
|
+
<paramlist name="Settings">
|
|
3
|
+
<param name="creator" value="Administrator,1788021869" />
|
|
4
|
+
<param name="time_duration" value="0.5" />
|
|
5
|
+
<param name="time_step" value="50" />
|
|
6
|
+
<param name="sample_step" value="250" />
|
|
7
|
+
<param name="chatter_threshold" value=".001" />
|
|
8
|
+
<param name="branch_threshold" value=".0005" />
|
|
9
|
+
<param name="StartType" value="0" />
|
|
10
|
+
<param name="startup_filename" value="$(Namespace).snp" />
|
|
11
|
+
<param name="PlotType" value="0" />
|
|
12
|
+
<param name="output_filename" value="$(Namespace).out" />
|
|
13
|
+
<param name="SnapType" value="0" />
|
|
14
|
+
<param name="SnapTime" value="0.3" />
|
|
15
|
+
<param name="snapshot_filename" value="$(Namespace).snp" />
|
|
16
|
+
<param name="MrunType" value="0" />
|
|
17
|
+
<param name="Mruns" value="1" />
|
|
18
|
+
<param name="Scenario" value="" />
|
|
19
|
+
<param name="Advanced" value="14335" />
|
|
20
|
+
<param name="sparsity_threshold" value="200" />
|
|
21
|
+
<param name="Options" value="16" />
|
|
22
|
+
<param name="Build" value="18" />
|
|
23
|
+
<param name="Warn" value="0" />
|
|
24
|
+
<param name="Check" value="0" />
|
|
25
|
+
<param name="description" value="" />
|
|
26
|
+
<param name="revisor" value="Administrator, 1788021869" />
|
|
27
|
+
</paramlist>
|
|
28
|
+
<Layers />
|
|
29
|
+
<List classid="Settings" />
|
|
30
|
+
<bookmarks />
|
|
31
|
+
<GlobalSubstitutions name="Default">
|
|
32
|
+
<List classid="Sub" />
|
|
33
|
+
<List classid="ValueSet" />
|
|
34
|
+
<paramlist>
|
|
35
|
+
<param name="Current" value="" />
|
|
36
|
+
</paramlist>
|
|
37
|
+
</GlobalSubstitutions>
|
|
38
|
+
<definitions>
|
|
39
|
+
<Definition classid="StationDefn" name="DS" id="2105821578" group="" url="" version="" build="" crc="483640" view="false">
|
|
40
|
+
<paramlist name="">
|
|
41
|
+
<param name="Description" value="" />
|
|
42
|
+
</paramlist>
|
|
43
|
+
<schematic classid="StationCanvas">
|
|
44
|
+
<paramlist>
|
|
45
|
+
<param name="show_grid" value="0" />
|
|
46
|
+
<param name="size" value="0" />
|
|
47
|
+
<param name="orient" value="1" />
|
|
48
|
+
<param name="show_border" value="0" />
|
|
49
|
+
<param name="monitor_bus_voltage" value="0" />
|
|
50
|
+
<param name="show_signal" value="0" />
|
|
51
|
+
<param name="show_virtual" value="0" />
|
|
52
|
+
<param name="show_sequence" value="0" />
|
|
53
|
+
<param name="auto_sequence" value="1" />
|
|
54
|
+
<param name="bus_expand_x" value="8" />
|
|
55
|
+
<param name="bus_expand_y" value="8" />
|
|
56
|
+
<param name="bus_length" value="4" />
|
|
57
|
+
</paramlist>
|
|
58
|
+
<grouping />
|
|
59
|
+
<Wire classid="Branch" id="2138248653" name="Main" x="180" y="180" w="66" h="82" orient="0" disable="false" defn="Main" recv="-1" send="-1" back="-1">
|
|
60
|
+
<vertex x="0" y="0" />
|
|
61
|
+
<vertex x="0" y="18" />
|
|
62
|
+
<vertex x="54" y="54" />
|
|
63
|
+
<vertex x="54" y="72" />
|
|
64
|
+
<User classid="UserCmp" id="1245623415" name="blank_probe_case:Main" x="0" y="0" w="0" h="0" z="-1" orient="0" defn="blank_probe_case:Main" link="-1" q="4" disable="false">
|
|
65
|
+
<paramlist name="" link="-1" crc="4361682" />
|
|
66
|
+
</User>
|
|
67
|
+
</Wire>
|
|
68
|
+
</schematic>
|
|
69
|
+
</Definition>
|
|
70
|
+
<Definition classid="UserCmpDefn" name="Main" id="537127987" group="" url="" version="" build="" crc="17500639" view="false" date="0">
|
|
71
|
+
<paramlist name="">
|
|
72
|
+
<param name="Description" value="" />
|
|
73
|
+
</paramlist>
|
|
74
|
+
<form name="" w="320" h="400" splitter="60" />
|
|
75
|
+
<graphics viewBox="-200 -200 200 200" size="2">
|
|
76
|
+
<Gfx classid="Graphics.Rectangle" id="259254034" x="-36" y="-36" w="72" h="72">
|
|
77
|
+
<paramlist>
|
|
78
|
+
<param name="color" value="Black" />
|
|
79
|
+
<param name="dasharray" value="0" />
|
|
80
|
+
<param name="thickness" value="0" />
|
|
81
|
+
<param name="port" value="" />
|
|
82
|
+
<param name="fill_style" value="0" />
|
|
83
|
+
<param name="fill_fg" value="Black" />
|
|
84
|
+
<param name="fill_bg" value="Black" />
|
|
85
|
+
<param name="cond" value="true" />
|
|
86
|
+
</paramlist>
|
|
87
|
+
</Gfx>
|
|
88
|
+
<Gfx classid="Graphics.Text" id="1721975208" x="0" y="0">
|
|
89
|
+
<paramlist>
|
|
90
|
+
<param name="text" value="%:Name" />
|
|
91
|
+
<param name="anchor" value="0" />
|
|
92
|
+
<param name="full_font" value="Tahoma, 10pt" />
|
|
93
|
+
<param name="angle" value="0" />
|
|
94
|
+
<param name="color" value="Black" />
|
|
95
|
+
<param name="cond" value="true" />
|
|
96
|
+
</paramlist>
|
|
97
|
+
</Gfx>
|
|
98
|
+
</graphics>
|
|
99
|
+
<schematic classid="UserCanvas">
|
|
100
|
+
<paramlist>
|
|
101
|
+
<param name="show_grid" value="0" />
|
|
102
|
+
<param name="size" value="0" />
|
|
103
|
+
<param name="orient" value="1" />
|
|
104
|
+
<param name="show_border" value="0" />
|
|
105
|
+
<param name="monitor_bus_voltage" value="0" />
|
|
106
|
+
<param name="show_signal" value="0" />
|
|
107
|
+
<param name="show_virtual" value="0" />
|
|
108
|
+
<param name="show_sequence" value="0" />
|
|
109
|
+
<param name="auto_sequence" value="1" />
|
|
110
|
+
<param name="bus_expand_x" value="8" />
|
|
111
|
+
<param name="bus_expand_y" value="8" />
|
|
112
|
+
<param name="bus_length" value="4" />
|
|
113
|
+
</paramlist>
|
|
114
|
+
<grouping />
|
|
115
|
+
</schematic>
|
|
116
|
+
</Definition>
|
|
117
|
+
</definitions>
|
|
118
|
+
<List classid="Resource" />
|
|
119
|
+
<hierarchy>
|
|
120
|
+
<call link="371607758" name="blank_probe_case:DS" z="-1" view="false" instance="0">
|
|
121
|
+
<call link="1245623415" name="blank_probe_case:Main" z="-1" view="true" instance="0" />
|
|
122
|
+
</call>
|
|
123
|
+
</hierarchy>
|
|
124
|
+
</project>
|
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
<project name="TMMB_v6_g_l0_1_811387" version="5.0.0" schema="" Target="EMTDC">
|
|
2
|
+
<paramlist name="Settings">
|
|
3
|
+
<param name="creator" value="Administrator,1787881138" />
|
|
4
|
+
<param name="time_duration" value="3" />
|
|
5
|
+
<param name="time_step" value="10" />
|
|
6
|
+
<param name="sample_step" value="50" />
|
|
7
|
+
<param name="chatter_threshold" value=".001" />
|
|
8
|
+
<param name="branch_threshold" value=".0005" />
|
|
9
|
+
<param name="StartType" value="0" />
|
|
10
|
+
<param name="startup_filename" value="$(Namespace).snp" />
|
|
11
|
+
<param name="PlotType" value="1" />
|
|
12
|
+
<param name="output_filename" value="TMMB_v6_g_l0_1_811387.out" />
|
|
13
|
+
<param name="SnapType" value="0" />
|
|
14
|
+
<param name="SnapTime" value="0.3" />
|
|
15
|
+
<param name="snapshot_filename" value="$(Namespace).snp" />
|
|
16
|
+
<param name="MrunType" value="0" />
|
|
17
|
+
<param name="Mruns" value="1" />
|
|
18
|
+
<param name="Scenario" value="" />
|
|
19
|
+
<param name="Advanced" value="14335" />
|
|
20
|
+
<param name="sparsity_threshold" value="200" />
|
|
21
|
+
<param name="Options" value="16" />
|
|
22
|
+
<param name="Build" value="18" />
|
|
23
|
+
<param name="Warn" value="0" />
|
|
24
|
+
<param name="Check" value="0" />
|
|
25
|
+
<param name="description" value="" />
|
|
26
|
+
<param name="revisor" value="Administrator, 1787881143" />
|
|
27
|
+
</paramlist>
|
|
28
|
+
<Layers />
|
|
29
|
+
<List classid="Settings" />
|
|
30
|
+
<bookmarks />
|
|
31
|
+
<GlobalSubstitutions name="Default">
|
|
32
|
+
<List classid="Sub" />
|
|
33
|
+
<List classid="ValueSet" />
|
|
34
|
+
<paramlist>
|
|
35
|
+
<param name="Current" value="" />
|
|
36
|
+
</paramlist>
|
|
37
|
+
</GlobalSubstitutions>
|
|
38
|
+
<definitions>
|
|
39
|
+
<Definition classid="UserCmpDefn" name="TMMB" url="" view="false" instances="0" date="0" crc="63701272" id="362477968" group="R4">
|
|
40
|
+
<paramlist>
|
|
41
|
+
<param name="Description" value="Thermal-Magnetic Memristive Branch (v6: CCBR/GEQ Norton)" />
|
|
42
|
+
</paramlist>
|
|
43
|
+
<form name="TMMB" w="320" h="460" splitter="70" commentlines="4">
|
|
44
|
+
<category name="Configuration" visible="true">
|
|
45
|
+
<parameter name="Name" desc="Name for Identification" type="Text" group="" helpmode="Overwrite" allowemptystr="true">
|
|
46
|
+
<value><![CDATA[]]></value>
|
|
47
|
+
<cond type="Enable"><![CDATA[true]]></cond>
|
|
48
|
+
</parameter>
|
|
49
|
+
<parameter type="Text" name="COM" desc="Fortran Comment" group="" helpmode="Overwrite" allowemptystr="false">
|
|
50
|
+
<value><![CDATA[TMMB]]></value>
|
|
51
|
+
<cond type="Enable" />
|
|
52
|
+
</parameter>
|
|
53
|
+
<cond><![CDATA[true]]></cond>
|
|
54
|
+
</category>
|
|
55
|
+
<category name="TMMB Parameters" visible="true">
|
|
56
|
+
<parameter type="Real" name="RMIN" desc="Minimum resistance [ohm]" content_type="Variable" min="1E-9" max="1E+308" unit="ohm" group="" helpmode="Append" intent="Input" dim="1" animate="false">
|
|
57
|
+
<value><![CDATA[1.0]]></value>
|
|
58
|
+
<cond type="Enable" />
|
|
59
|
+
</parameter>
|
|
60
|
+
<parameter type="Real" name="K" desc="Memristance coefficient [ohm]" content_type="Variable" min="0" max="1E+308" unit="ohm" group="" helpmode="Append" intent="Input" dim="1" animate="false">
|
|
61
|
+
<value><![CDATA[1.0]]></value>
|
|
62
|
+
<cond type="Enable" />
|
|
63
|
+
</parameter>
|
|
64
|
+
<parameter type="Real" name="ALPHA" desc="Heating coupling [1/MW/s]" content_type="Variable" min="0" max="1E+308" unit="" group="" helpmode="Append" intent="Input" dim="1" animate="false">
|
|
65
|
+
<value><![CDATA[1.0]]></value>
|
|
66
|
+
<cond type="Enable" />
|
|
67
|
+
</parameter>
|
|
68
|
+
<parameter type="Real" name="BETA" desc="Cooling rate [1/s]" content_type="Variable" min="0" max="1E+308" unit="" group="" helpmode="Append" intent="Input" dim="1" animate="false">
|
|
69
|
+
<value><![CDATA[1.0]]></value>
|
|
70
|
+
<cond type="Enable" />
|
|
71
|
+
</parameter>
|
|
72
|
+
<parameter type="Real" name="L0" desc="Inductance [H]" content_type="Variable" min="0" max="1E+308" unit="H" group="" helpmode="Append" intent="Input" dim="1" animate="false">
|
|
73
|
+
<value><![CDATA[0.0]]></value>
|
|
74
|
+
<cond type="Enable" />
|
|
75
|
+
</parameter>
|
|
76
|
+
<cond><![CDATA[true]]></cond>
|
|
77
|
+
</category>
|
|
78
|
+
</form>
|
|
79
|
+
<svg viewBox="-200 -200 200 200">
|
|
80
|
+
<port model="Natural" name="NA" x="-72" y="0" dim="1" mode="Electrical" type="NonRemovable"><![CDATA[true]]></port>
|
|
81
|
+
<port model="Natural" name="NB" x="72" y="0" dim="1" mode="Electrical" type="NonRemovable"><![CDATA[true]]></port>
|
|
82
|
+
<port model="Transfer" name="OUT" x="0" y="-36" dim="1" mode="Output" type="Real"><![CDATA[true]]></port>
|
|
83
|
+
<rect x="-27" y="-15" width="54" height="30" stroke="Black" stroke-dasharray="none" stroke-width="0.2" fill-style="Hollow" fill-fg="Black" fill-bg="" />
|
|
84
|
+
<line x1="-72" y1="0" x2="-27" y2="0" stroke="Black" stroke-dasharray="none" stroke-width="0.2" />
|
|
85
|
+
<line x1="27" y1="0" x2="72" y2="0" stroke="Black" stroke-dasharray="none" stroke-width="0.2" />
|
|
86
|
+
<line x1="-12" y1="0" x2="-4" y2="0" stroke="Black" stroke-dasharray="none" stroke-width="0.2" />
|
|
87
|
+
<line x1="-8" y1="-4" x2="-8" y2="4" stroke="Black" stroke-dasharray="none" stroke-width="0.2" />
|
|
88
|
+
<line x1="0" y1="0" x2="8" y2="0" stroke="Black" stroke-dasharray="none" stroke-width="0.2" />
|
|
89
|
+
<line x1="4" y1="-4" x2="4" y2="4" stroke="Black" stroke-dasharray="none" stroke-width="0.2" />
|
|
90
|
+
<line x1="12" y1="0" x2="20" y2="0" stroke="Black" stroke-dasharray="none" stroke-width="0.2" />
|
|
91
|
+
<line x1="16" y1="-4" x2="16" y2="4" stroke="Black" stroke-dasharray="none" stroke-width="0.2" />
|
|
92
|
+
<line x1="0" y1="15" x2="0" y2="36" stroke="Black" stroke-dasharray="none" stroke-width="0.2" />
|
|
93
|
+
<line x1="-5" y1="20" x2="0" y2="15" stroke="Black" stroke-dasharray="none" stroke-width="0.2" />
|
|
94
|
+
<line x1="5" y1="20" x2="0" y2="15" stroke="Black" stroke-dasharray="none" stroke-width="0.2" />
|
|
95
|
+
<text x="0" y="-1" stroke="Black" fill="Black" font-size="Small" text-anchor="Middle"><![CDATA[R(w)]]></text>
|
|
96
|
+
<text x="0" y="13" stroke="Black" fill="Black" font-size="Small" text-anchor="Middle"><![CDATA[TMMB]]></text>
|
|
97
|
+
</svg>
|
|
98
|
+
<script>
|
|
99
|
+
<segment name="Dsdyn" classid="CoreSegment" id="2093360559"><![CDATA[#STORAGE REAL:8
|
|
100
|
+
! $COM
|
|
101
|
+
! v = R(w)*i + L0*di/dt ; R(w)=RMIN+K*w^2 ; dw/dt=ALPHA*v*i-BETA*w
|
|
102
|
+
! CCBR/GEQ branch interface (seriesrl2 official pattern):
|
|
103
|
+
! GEQ fixed G0 at TIMEZERO (matrix static -> zero refactorization);
|
|
104
|
+
! per-step CCBR = I_hist + (G-G0)*V (RHS only).
|
|
105
|
+
! G=1/(R+2L0/DELT); Z1=R-2L0/DELT; I_hist=G*V-Z1*G*I.
|
|
106
|
+
! Storage: (1)w (2)v_prev (3)i_prev (4)i_hist (5)g (6)r (7)ccbr (8)spare
|
|
107
|
+
#LOCAL REAL W
|
|
108
|
+
#LOCAL REAL V
|
|
109
|
+
#LOCAL REAL I
|
|
110
|
+
#LOCAL REAL R
|
|
111
|
+
#LOCAL REAL G
|
|
112
|
+
#LOCAL REAL G0
|
|
113
|
+
#LOCAL REAL DTB
|
|
114
|
+
#LOCAL REAL Z1
|
|
115
|
+
#LOCAL REAL IH
|
|
116
|
+
#LOCAL INTEGER IVD1_1
|
|
117
|
+
#BEGIN
|
|
118
|
+
GEQ($BRR, $SS) = 1.0/(2.0*$RMIN + 2.0*$L0/DELT)
|
|
119
|
+
DEFRDBR($BRR, $SS) = .TRUE.
|
|
120
|
+
#ENDBEGIN
|
|
121
|
+
IF (TIMEZERO) THEN
|
|
122
|
+
STORF(NSTORF+1) = 0.0
|
|
123
|
+
STORF(NSTORF+2) = 0.0
|
|
124
|
+
STORF(NSTORF+3) = 0.0
|
|
125
|
+
STORF(NSTORF+4) = 0.0
|
|
126
|
+
STORF(NSTORF+5) = 1.0/$RMIN
|
|
127
|
+
STORF(NSTORF+6) = $RMIN
|
|
128
|
+
STORF(NSTORF+7) = 0.0
|
|
129
|
+
STORF(NSTORF+8) = 0.0
|
|
130
|
+
CCBR($BRR, $SS) = 0.0
|
|
131
|
+
$OUT = 0.0
|
|
132
|
+
ENDIF
|
|
133
|
+
W = STORF(NSTORF+1)
|
|
134
|
+
IH = STORF(NSTORF+4)
|
|
135
|
+
G = STORF(NSTORF+5)
|
|
136
|
+
V = VBRANCH($SS, $BRR)
|
|
137
|
+
I = G*V + IH
|
|
138
|
+
DTB = 0.5 * $BETA * DELT
|
|
139
|
+
W = (W*(1.0 - DTB) + $ALPHA*DELT*(V*I)) / (1.0 + DTB)
|
|
140
|
+
R = $RMIN + $K * W * W
|
|
141
|
+
G = 1.0/(R + 2.0*$L0/DELT)
|
|
142
|
+
Z1 = R - 2.0*$L0/DELT
|
|
143
|
+
! ---- seriesrl2 official recurrence (no CBR readback needed) ----
|
|
144
|
+
IH = (1.0 - Z1*G)*G*V - Z1*G*IH
|
|
145
|
+
G0 = 1.0/(2.0*$RMIN + 2.0*$L0/DELT)
|
|
146
|
+
CCBR($BRR, $SS) = IH + (G - G0)*V
|
|
147
|
+
STORF(NSTORF+1) = W
|
|
148
|
+
STORF(NSTORF+2) = V
|
|
149
|
+
STORF(NSTORF+3) = I
|
|
150
|
+
STORF(NSTORF+4) = IH
|
|
151
|
+
STORF(NSTORF+5) = G
|
|
152
|
+
STORF(NSTORF+6) = R
|
|
153
|
+
STORF(NSTORF+7) = CCBR($BRR, $SS)
|
|
154
|
+
STORF(NSTORF+8) = 0.0
|
|
155
|
+
NSTORF = NSTORF + 8
|
|
156
|
+
$OUT = W]]></segment>
|
|
157
|
+
<segment name="Branch" classid="CoreSegment" id="1366280103"><![CDATA[BRR = $NA $NB BREAKER 1.0E6]]></segment>
|
|
158
|
+
<segment name="FlyBy" classid="CoreSegment" id="1256125691"><![CDATA[TMMB memristive branch
|
|
159
|
+
:NA
|
|
160
|
+
Positive terminal
|
|
161
|
+
:NB
|
|
162
|
+
Negative terminal
|
|
163
|
+
:OUT
|
|
164
|
+
State variable w]]></segment>
|
|
165
|
+
</script>
|
|
166
|
+
<graphics>
|
|
167
|
+
<paramlist />
|
|
168
|
+
<Port id="137001279" classid="Port" x="-72" y="0">
|
|
169
|
+
<paramlist>
|
|
170
|
+
<param name="name" value="NA" />
|
|
171
|
+
<param name="internal" value="false" />
|
|
172
|
+
<param name="cond" value="true" />
|
|
173
|
+
<param name="mode" value="3" />
|
|
174
|
+
<param name="datatype" value="0" />
|
|
175
|
+
<param name="electype" value="0" />
|
|
176
|
+
<param name="dim" value="1" />
|
|
177
|
+
</paramlist>
|
|
178
|
+
</Port>
|
|
179
|
+
<Port id="1305594588" classid="Port" x="72" y="0">
|
|
180
|
+
<paramlist>
|
|
181
|
+
<param name="name" value="NB" />
|
|
182
|
+
<param name="internal" value="false" />
|
|
183
|
+
<param name="cond" value="true" />
|
|
184
|
+
<param name="mode" value="3" />
|
|
185
|
+
<param name="datatype" value="0" />
|
|
186
|
+
<param name="electype" value="0" />
|
|
187
|
+
<param name="dim" value="1" />
|
|
188
|
+
</paramlist>
|
|
189
|
+
</Port>
|
|
190
|
+
<Port id="1034241133" classid="Port" x="0" y="-36">
|
|
191
|
+
<paramlist>
|
|
192
|
+
<param name="name" value="OUT" />
|
|
193
|
+
<param name="internal" value="false" />
|
|
194
|
+
<param name="cond" value="true" />
|
|
195
|
+
<param name="mode" value="2" />
|
|
196
|
+
<param name="datatype" value="3" />
|
|
197
|
+
<param name="electype" value="0" />
|
|
198
|
+
<param name="dim" value="1" />
|
|
199
|
+
</paramlist>
|
|
200
|
+
</Port>
|
|
201
|
+
<Gfx classid="Graphics.Rectangle" id="2136562982" x="-27" y="-15" w="54" h="30">
|
|
202
|
+
<paramlist>
|
|
203
|
+
<param name="color" value="Black" />
|
|
204
|
+
<param name="dasharray" value="0" />
|
|
205
|
+
<param name="thickness" value="0" />
|
|
206
|
+
<param name="port" value="" />
|
|
207
|
+
<param name="fill_style" value="0" />
|
|
208
|
+
<param name="fill_fg" value="Black" />
|
|
209
|
+
<param name="fill_bg" value="White" />
|
|
210
|
+
<param name="cond" value="true" />
|
|
211
|
+
</paramlist>
|
|
212
|
+
</Gfx>
|
|
213
|
+
<Gfx classid="Graphics.Line" id="45103384" x="-72" y="0">
|
|
214
|
+
<vertex x="0" y="0" />
|
|
215
|
+
<vertex x="45" y="0" />
|
|
216
|
+
<paramlist>
|
|
217
|
+
<param name="color" value="Black" />
|
|
218
|
+
<param name="dasharray" value="0" />
|
|
219
|
+
<param name="thickness" value="0" />
|
|
220
|
+
<param name="port" value="" />
|
|
221
|
+
<param name="cond" value="true" />
|
|
222
|
+
</paramlist>
|
|
223
|
+
</Gfx>
|
|
224
|
+
<Gfx classid="Graphics.Line" id="47389884" x="27" y="0">
|
|
225
|
+
<vertex x="0" y="0" />
|
|
226
|
+
<vertex x="45" y="0" />
|
|
227
|
+
<paramlist>
|
|
228
|
+
<param name="color" value="Black" />
|
|
229
|
+
<param name="dasharray" value="0" />
|
|
230
|
+
<param name="thickness" value="0" />
|
|
231
|
+
<param name="port" value="" />
|
|
232
|
+
<param name="cond" value="true" />
|
|
233
|
+
</paramlist>
|
|
234
|
+
</Gfx>
|
|
235
|
+
<Gfx classid="Graphics.Line" id="708858009" x="-12" y="0">
|
|
236
|
+
<vertex x="0" y="0" />
|
|
237
|
+
<vertex x="8" y="0" />
|
|
238
|
+
<paramlist>
|
|
239
|
+
<param name="color" value="Black" />
|
|
240
|
+
<param name="dasharray" value="0" />
|
|
241
|
+
<param name="thickness" value="0" />
|
|
242
|
+
<param name="port" value="" />
|
|
243
|
+
<param name="cond" value="true" />
|
|
244
|
+
</paramlist>
|
|
245
|
+
</Gfx>
|
|
246
|
+
<Gfx classid="Graphics.Line" id="1382810431" x="-8" y="-4">
|
|
247
|
+
<vertex x="0" y="0" />
|
|
248
|
+
<vertex x="0" y="8" />
|
|
249
|
+
<paramlist>
|
|
250
|
+
<param name="color" value="Black" />
|
|
251
|
+
<param name="dasharray" value="0" />
|
|
252
|
+
<param name="thickness" value="0" />
|
|
253
|
+
<param name="port" value="" />
|
|
254
|
+
<param name="cond" value="true" />
|
|
255
|
+
</paramlist>
|
|
256
|
+
</Gfx>
|
|
257
|
+
<Gfx classid="Graphics.Line" id="316471579" x="0" y="0">
|
|
258
|
+
<vertex x="0" y="0" />
|
|
259
|
+
<vertex x="8" y="0" />
|
|
260
|
+
<paramlist>
|
|
261
|
+
<param name="color" value="Black" />
|
|
262
|
+
<param name="dasharray" value="0" />
|
|
263
|
+
<param name="thickness" value="0" />
|
|
264
|
+
<param name="port" value="" />
|
|
265
|
+
<param name="cond" value="true" />
|
|
266
|
+
</paramlist>
|
|
267
|
+
</Gfx>
|
|
268
|
+
<Gfx classid="Graphics.Line" id="251937415" x="4" y="-4">
|
|
269
|
+
<vertex x="0" y="0" />
|
|
270
|
+
<vertex x="0" y="8" />
|
|
271
|
+
<paramlist>
|
|
272
|
+
<param name="color" value="Black" />
|
|
273
|
+
<param name="dasharray" value="0" />
|
|
274
|
+
<param name="thickness" value="0" />
|
|
275
|
+
<param name="port" value="" />
|
|
276
|
+
<param name="cond" value="true" />
|
|
277
|
+
</paramlist>
|
|
278
|
+
</Gfx>
|
|
279
|
+
<Gfx classid="Graphics.Line" id="2139547155" x="12" y="0">
|
|
280
|
+
<vertex x="0" y="0" />
|
|
281
|
+
<vertex x="8" y="0" />
|
|
282
|
+
<paramlist>
|
|
283
|
+
<param name="color" value="Black" />
|
|
284
|
+
<param name="dasharray" value="0" />
|
|
285
|
+
<param name="thickness" value="0" />
|
|
286
|
+
<param name="port" value="" />
|
|
287
|
+
<param name="cond" value="true" />
|
|
288
|
+
</paramlist>
|
|
289
|
+
</Gfx>
|
|
290
|
+
<Gfx classid="Graphics.Line" id="1002252530" x="16" y="-4">
|
|
291
|
+
<vertex x="0" y="0" />
|
|
292
|
+
<vertex x="0" y="8" />
|
|
293
|
+
<paramlist>
|
|
294
|
+
<param name="color" value="Black" />
|
|
295
|
+
<param name="dasharray" value="0" />
|
|
296
|
+
<param name="thickness" value="0" />
|
|
297
|
+
<param name="port" value="" />
|
|
298
|
+
<param name="cond" value="true" />
|
|
299
|
+
</paramlist>
|
|
300
|
+
</Gfx>
|
|
301
|
+
<Gfx classid="Graphics.Line" id="1995477368" x="0" y="15">
|
|
302
|
+
<vertex x="0" y="0" />
|
|
303
|
+
<vertex x="0" y="21" />
|
|
304
|
+
<paramlist>
|
|
305
|
+
<param name="color" value="Black" />
|
|
306
|
+
<param name="dasharray" value="0" />
|
|
307
|
+
<param name="thickness" value="0" />
|
|
308
|
+
<param name="port" value="" />
|
|
309
|
+
<param name="cond" value="true" />
|
|
310
|
+
</paramlist>
|
|
311
|
+
</Gfx>
|
|
312
|
+
<Gfx classid="Graphics.Line" id="257938923" x="-5" y="20">
|
|
313
|
+
<vertex x="0" y="0" />
|
|
314
|
+
<vertex x="5" y="-5" />
|
|
315
|
+
<paramlist>
|
|
316
|
+
<param name="color" value="Black" />
|
|
317
|
+
<param name="dasharray" value="0" />
|
|
318
|
+
<param name="thickness" value="0" />
|
|
319
|
+
<param name="port" value="" />
|
|
320
|
+
<param name="cond" value="true" />
|
|
321
|
+
</paramlist>
|
|
322
|
+
</Gfx>
|
|
323
|
+
<Gfx classid="Graphics.Line" id="515372674" x="5" y="20">
|
|
324
|
+
<vertex x="0" y="0" />
|
|
325
|
+
<vertex x="-5" y="-5" />
|
|
326
|
+
<paramlist>
|
|
327
|
+
<param name="color" value="Black" />
|
|
328
|
+
<param name="dasharray" value="0" />
|
|
329
|
+
<param name="thickness" value="0" />
|
|
330
|
+
<param name="port" value="" />
|
|
331
|
+
<param name="cond" value="true" />
|
|
332
|
+
</paramlist>
|
|
333
|
+
</Gfx>
|
|
334
|
+
<Gfx classid="Graphics.Text" id="1082658360" x="0" y="-1">
|
|
335
|
+
<paramlist>
|
|
336
|
+
<param name="color" value="Black" />
|
|
337
|
+
<param name="font_size" value="0" />
|
|
338
|
+
<param name="full_font" value="Tahoma, 12world" />
|
|
339
|
+
<param name="anchor" value="1" />
|
|
340
|
+
<param name="cond" value="true" />
|
|
341
|
+
<param name="text" value="R(w)" />
|
|
342
|
+
<param name="angle" value="0" />
|
|
343
|
+
</paramlist>
|
|
344
|
+
</Gfx>
|
|
345
|
+
<Gfx classid="Graphics.Text" id="1380391487" x="0" y="13">
|
|
346
|
+
<paramlist>
|
|
347
|
+
<param name="color" value="Black" />
|
|
348
|
+
<param name="font_size" value="0" />
|
|
349
|
+
<param name="full_font" value="Tahoma, 12world" />
|
|
350
|
+
<param name="anchor" value="1" />
|
|
351
|
+
<param name="cond" value="true" />
|
|
352
|
+
<param name="text" value="TMMB" />
|
|
353
|
+
<param name="angle" value="0" />
|
|
354
|
+
</paramlist>
|
|
355
|
+
</Gfx>
|
|
356
|
+
</graphics>
|
|
357
|
+
</Definition>
|
|
358
|
+
<Definition classid="StationDefn" name="DS" id="528127591" group="" url="" version="" build="" crc="58860711" view="false">
|
|
359
|
+
<paramlist name="">
|
|
360
|
+
<param name="Description" value="" />
|
|
361
|
+
</paramlist>
|
|
362
|
+
<schematic classid="StationCanvas">
|
|
363
|
+
<paramlist>
|
|
364
|
+
<param name="show_grid" value="0" />
|
|
365
|
+
<param name="size" value="0" />
|
|
366
|
+
<param name="orient" value="1" />
|
|
367
|
+
<param name="show_border" value="0" />
|
|
368
|
+
<param name="monitor_bus_voltage" value="0" />
|
|
369
|
+
<param name="show_signal" value="0" />
|
|
370
|
+
<param name="show_virtual" value="0" />
|
|
371
|
+
<param name="show_sequence" value="0" />
|
|
372
|
+
<param name="auto_sequence" value="1" />
|
|
373
|
+
<param name="bus_expand_x" value="8" />
|
|
374
|
+
<param name="bus_expand_y" value="8" />
|
|
375
|
+
<param name="bus_length" value="4" />
|
|
376
|
+
</paramlist>
|
|
377
|
+
<grouping />
|
|
378
|
+
<Wire classid="Branch" id="1776616513" name="Main" x="180" y="180" w="66" h="82" orient="0" disable="false" defn="Main" recv="-1" send="-1" back="-1">
|
|
379
|
+
<vertex x="0" y="0" />
|
|
380
|
+
<vertex x="0" y="18" />
|
|
381
|
+
<vertex x="54" y="54" />
|
|
382
|
+
<vertex x="54" y="72" />
|
|
383
|
+
<User classid="UserCmp" id="262724584" name="TMMB_v6_g_l0_1_811387:Main" x="0" y="0" w="0" h="0" z="-1" orient="0" defn="TMMB_v6_g_l0_1_811387:Main" link="-1" q="4" disable="false">
|
|
384
|
+
<paramlist name="" link="-1" crc="4361682" />
|
|
385
|
+
</User>
|
|
386
|
+
</Wire>
|
|
387
|
+
</schematic>
|
|
388
|
+
</Definition>
|
|
389
|
+
<Definition classid="UserCmpDefn" name="Main" id="1173666291" group="" url="" version="" build="" crc="128000575" view="false" date="0">
|
|
390
|
+
<paramlist name="">
|
|
391
|
+
<param name="Description" value="" />
|
|
392
|
+
</paramlist>
|
|
393
|
+
<form name="" w="320" h="400" splitter="60" />
|
|
394
|
+
<graphics viewBox="-200 -200 200 200" size="2">
|
|
395
|
+
<Gfx classid="Graphics.Rectangle" id="496460006" x="-36" y="-36" w="72" h="72">
|
|
396
|
+
<paramlist>
|
|
397
|
+
<param name="color" value="Black" />
|
|
398
|
+
<param name="dasharray" value="0" />
|
|
399
|
+
<param name="thickness" value="0" />
|
|
400
|
+
<param name="port" value="" />
|
|
401
|
+
<param name="fill_style" value="0" />
|
|
402
|
+
<param name="fill_fg" value="Black" />
|
|
403
|
+
<param name="fill_bg" value="Black" />
|
|
404
|
+
<param name="cond" value="true" />
|
|
405
|
+
</paramlist>
|
|
406
|
+
</Gfx>
|
|
407
|
+
<Gfx classid="Graphics.Text" id="1656279956" x="0" y="0">
|
|
408
|
+
<paramlist>
|
|
409
|
+
<param name="text" value="%:Name" />
|
|
410
|
+
<param name="anchor" value="0" />
|
|
411
|
+
<param name="full_font" value="Tahoma, 10pt" />
|
|
412
|
+
<param name="angle" value="0" />
|
|
413
|
+
<param name="color" value="Black" />
|
|
414
|
+
<param name="cond" value="true" />
|
|
415
|
+
</paramlist>
|
|
416
|
+
</Gfx>
|
|
417
|
+
</graphics>
|
|
418
|
+
<schematic classid="UserCanvas">
|
|
419
|
+
<paramlist>
|
|
420
|
+
<param name="show_grid" value="0" />
|
|
421
|
+
<param name="size" value="0" />
|
|
422
|
+
<param name="orient" value="1" />
|
|
423
|
+
<param name="show_border" value="0" />
|
|
424
|
+
<param name="monitor_bus_voltage" value="0" />
|
|
425
|
+
<param name="show_signal" value="0" />
|
|
426
|
+
<param name="show_virtual" value="0" />
|
|
427
|
+
<param name="show_sequence" value="0" />
|
|
428
|
+
<param name="auto_sequence" value="1" />
|
|
429
|
+
<param name="bus_expand_x" value="8" />
|
|
430
|
+
<param name="bus_expand_y" value="8" />
|
|
431
|
+
<param name="bus_length" value="4" />
|
|
432
|
+
</paramlist>
|
|
433
|
+
<grouping />
|
|
434
|
+
<User classid="UserCmp" id="161649834" name="master:source_1" x="1080" y="3600" w="38" h="122" z="-1" orient="1" defn="master:source_1" link="-1" q="4" disable="false">
|
|
435
|
+
<paramlist name="" link="-1" crc="49505675">
|
|
436
|
+
<param name="Name" value="Src" />
|
|
437
|
+
<param name="Type" value="1" />
|
|
438
|
+
<param name="Grnd" value="1" />
|
|
439
|
+
<param name="Spec" value="0" />
|
|
440
|
+
<param name="Cntrl" value="0" />
|
|
441
|
+
<param name="AC" value="1" />
|
|
442
|
+
<param name="Vm" value="10 [kV]" />
|
|
443
|
+
<param name="Tc" value="0.05" />
|
|
444
|
+
<param name="Ph" value="0.0" />
|
|
445
|
+
<param name="f" value="50.0 [Hz]" />
|
|
446
|
+
<param name="P" value="0.0" />
|
|
447
|
+
<param name="Q" value="0.0" />
|
|
448
|
+
<param name="R" value="0.001 [ohm]" />
|
|
449
|
+
<param name="Rs" value="1.0" />
|
|
450
|
+
<param name="Rp" value="1.0" />
|
|
451
|
+
<param name="Lp" value="0.1" />
|
|
452
|
+
<param name="R_" value="1.0" />
|
|
453
|
+
<param name="L" value="0.1" />
|
|
454
|
+
<param name="C" value="1.0" />
|
|
455
|
+
<param name="L_" value="0.1" />
|
|
456
|
+
<param name="C_" value="1.0" />
|
|
457
|
+
<param name="CUR" value="" />
|
|
458
|
+
</paramlist>
|
|
459
|
+
</User>
|
|
460
|
+
<User classid="UserCmp" id="614898660" name="master:ammeter" x="2520" y="3600" w="44" h="28" z="-1" orient="0" defn="master:ammeter" link="-1" q="4" disable="false">
|
|
461
|
+
<paramlist name="" link="-1" crc="119030036">
|
|
462
|
+
<param name="Name" value="Ix" />
|
|
463
|
+
</paramlist>
|
|
464
|
+
</User>
|
|
465
|
+
<User classid="UserCmp" id="508652399" name="master:voltmetergnd" x="3240" y="2700" w="21" h="36" z="-1" orient="0" defn="master:voltmetergnd" link="-1" q="4" disable="false">
|
|
466
|
+
<paramlist name="" link="-1" crc="116145885">
|
|
467
|
+
<param name="Name" value="Vx" />
|
|
468
|
+
</paramlist>
|
|
469
|
+
</User>
|
|
470
|
+
<User classid="UserCmp" id="546041519" name="master:ground" x="5400" y="3600" w="34" h="26" z="-1" orient="0" defn="master:ground" link="-1" q="4" disable="false">
|
|
471
|
+
<paramlist name="" link="-1" crc="28206164" />
|
|
472
|
+
</User>
|
|
473
|
+
<User classid="UserCmp" id="628458748" name="TMMB_v6_g_l0_1_811387:TMMB" x="3960" y="3600" w="152" h="80" z="-1" orient="0" defn="TMMB_v6_g_l0_1_811387:TMMB" link="-1" q="4" disable="false">
|
|
474
|
+
<paramlist name="" link="-1" crc="90527443">
|
|
475
|
+
<param name="Name" value="TMMB1" />
|
|
476
|
+
<param name="COM" value="TMMB" />
|
|
477
|
+
<param name="RMIN" value="1.0" />
|
|
478
|
+
<param name="K" value="1.0" />
|
|
479
|
+
<param name="ALPHA" value="1.0" />
|
|
480
|
+
<param name="BETA" value="1.0" />
|
|
481
|
+
<param name="L0" value="0.1" />
|
|
482
|
+
</paramlist>
|
|
483
|
+
</User>
|
|
484
|
+
<Wire classid="WireOrthogonal" id="495705146" name="" x="1080" y="3564" w="1450" h="46" orient="0" disable="false">
|
|
485
|
+
<vertex x="0" y="0" />
|
|
486
|
+
<vertex x="0" y="36" />
|
|
487
|
+
<vertex x="1440" y="36" />
|
|
488
|
+
</Wire>
|
|
489
|
+
<Wire classid="WireOrthogonal" id="931971453" name="" x="2556" y="3600" w="1342" h="10" orient="0" disable="false">
|
|
490
|
+
<vertex x="0" y="0" />
|
|
491
|
+
<vertex x="1332" y="0" />
|
|
492
|
+
</Wire>
|
|
493
|
+
<Wire classid="WireOrthogonal" id="1303658187" name="" x="4032" y="3600" w="1378" h="10" orient="0" disable="false">
|
|
494
|
+
<vertex x="0" y="0" />
|
|
495
|
+
<vertex x="1368" y="0" />
|
|
496
|
+
</Wire>
|
|
497
|
+
<Wire classid="WireOrthogonal" id="783384810" name="" x="2556" y="3600" w="694" h="910" orient="0" disable="false">
|
|
498
|
+
<vertex x="0" y="0" />
|
|
499
|
+
<vertex x="0" y="-900" />
|
|
500
|
+
<vertex x="684" y="-900" />
|
|
501
|
+
</Wire>
|
|
502
|
+
<User classid="UserCmp" id="1436320645" name="master:datalabel" x="3960" y="3564" w="24" h="23" z="-1" orient="0" defn="master:datalabel" link="-1" q="4" disable="false">
|
|
503
|
+
<paramlist name="" link="-1" crc="127230955">
|
|
504
|
+
<param name="Name" value="Wx" />
|
|
505
|
+
</paramlist>
|
|
506
|
+
</User>
|
|
507
|
+
<User classid="UserCmp" id="1634070217" name="master:pgb" x="9900" y="3600" w="41" h="40" z="-1" orient="0" defn="master:pgb" link="-1" q="4" disable="false">
|
|
508
|
+
<paramlist name="" link="-1" crc="65740200">
|
|
509
|
+
<param name="Name" value="Wx" />
|
|
510
|
+
<param name="Group" value="" />
|
|
511
|
+
<param name="UseSignalName" value="1" />
|
|
512
|
+
<param name="enab" value="1" />
|
|
513
|
+
<param name="Display" value="1" />
|
|
514
|
+
<param name="Scale" value="1.0" />
|
|
515
|
+
<param name="Units" value="" />
|
|
516
|
+
<param name="mrun" value="0" />
|
|
517
|
+
<param name="Pol" value="0" />
|
|
518
|
+
<param name="Max" value="2.0" />
|
|
519
|
+
<param name="Min" value="-2.0" />
|
|
520
|
+
</paramlist>
|
|
521
|
+
</User>
|
|
522
|
+
<User classid="UserCmp" id="1455815762" name="master:datalabel" x="9900" y="3600" w="24" h="23" z="-1" orient="0" defn="master:datalabel" link="-1" q="4" disable="false">
|
|
523
|
+
<paramlist name="" link="-1" crc="127230955">
|
|
524
|
+
<param name="Name" value="Wx" />
|
|
525
|
+
</paramlist>
|
|
526
|
+
</User>
|
|
527
|
+
<User classid="UserCmp" id="1917243387" name="master:pgb" x="9000" y="3060" w="41" h="40" z="-1" orient="0" defn="master:pgb" link="-1" q="4" disable="false">
|
|
528
|
+
<paramlist name="" link="-1" crc="65740200">
|
|
529
|
+
<param name="Name" value="Vx" />
|
|
530
|
+
<param name="Group" value="" />
|
|
531
|
+
<param name="UseSignalName" value="1" />
|
|
532
|
+
<param name="enab" value="1" />
|
|
533
|
+
<param name="Display" value="1" />
|
|
534
|
+
<param name="Scale" value="1.0" />
|
|
535
|
+
<param name="Units" value="" />
|
|
536
|
+
<param name="mrun" value="0" />
|
|
537
|
+
<param name="Pol" value="0" />
|
|
538
|
+
<param name="Max" value="2.0" />
|
|
539
|
+
<param name="Min" value="-2.0" />
|
|
540
|
+
</paramlist>
|
|
541
|
+
</User>
|
|
542
|
+
<User classid="UserCmp" id="1163648990" name="master:datalabel" x="9000" y="3060" w="20" h="23" z="-1" orient="0" defn="master:datalabel" link="-1" q="4" disable="false">
|
|
543
|
+
<paramlist name="" link="-1" crc="127230955">
|
|
544
|
+
<param name="Name" value="Vx" />
|
|
545
|
+
</paramlist>
|
|
546
|
+
</User>
|
|
547
|
+
<User classid="UserCmp" id="1204200072" name="master:pgb" x="9000" y="2520" w="41" h="40" z="-1" orient="0" defn="master:pgb" link="-1" q="4" disable="false">
|
|
548
|
+
<paramlist name="" link="-1" crc="65740200">
|
|
549
|
+
<param name="Name" value="Ix" />
|
|
550
|
+
<param name="Group" value="" />
|
|
551
|
+
<param name="UseSignalName" value="1" />
|
|
552
|
+
<param name="enab" value="1" />
|
|
553
|
+
<param name="Display" value="1" />
|
|
554
|
+
<param name="Scale" value="1.0" />
|
|
555
|
+
<param name="Units" value="" />
|
|
556
|
+
<param name="mrun" value="0" />
|
|
557
|
+
<param name="Pol" value="0" />
|
|
558
|
+
<param name="Max" value="2.0" />
|
|
559
|
+
<param name="Min" value="-2.0" />
|
|
560
|
+
</paramlist>
|
|
561
|
+
</User>
|
|
562
|
+
<User classid="UserCmp" id="274305448" name="master:datalabel" x="9000" y="2520" w="16" h="23" z="-1" orient="0" defn="master:datalabel" link="-1" q="4" disable="false">
|
|
563
|
+
<paramlist name="" link="-1" crc="127230955">
|
|
564
|
+
<param name="Name" value="Ix" />
|
|
565
|
+
</paramlist>
|
|
566
|
+
</User>
|
|
567
|
+
</schematic>
|
|
568
|
+
</Definition>
|
|
569
|
+
</definitions>
|
|
570
|
+
<List classid="Resource" />
|
|
571
|
+
<hierarchy>
|
|
572
|
+
<call link="157125084" name="TMMB_v6_g_l0_1_811387:DS" z="-1" view="false" instance="0">
|
|
573
|
+
<call link="262724584" name="TMMB_v6_g_l0_1_811387:Main" z="-1" view="true" instance="0" />
|
|
574
|
+
</call>
|
|
575
|
+
</hierarchy>
|
|
576
|
+
</project>
|
package/tools/main.py
CHANGED
|
@@ -55,6 +55,7 @@ from __future__ import annotations
|
|
|
55
55
|
import json
|
|
56
56
|
import os
|
|
57
57
|
import re
|
|
58
|
+
import shutil
|
|
58
59
|
import socket
|
|
59
60
|
import sys
|
|
60
61
|
import time
|
|
@@ -523,13 +524,86 @@ def _gen_name(comp_type: str) -> str:
|
|
|
523
524
|
# ---------------------------------------------------------------------------
|
|
524
525
|
# 工具集 1:连接与工程加载(懒加载 mhi)
|
|
525
526
|
# ---------------------------------------------------------------------------
|
|
526
|
-
def
|
|
527
|
-
"""
|
|
527
|
+
def _walk_find(root: str, fname: str, maxdepth: int = 4) -> Optional[str]:
|
|
528
|
+
"""深度受限目录遍历找同名文件(用于 PSCAD 安装根等大目录,取最新)。"""
|
|
529
|
+
if not root or not os.path.isdir(root):
|
|
530
|
+
return None
|
|
531
|
+
root = os.path.abspath(root)
|
|
532
|
+
best = None
|
|
533
|
+
try:
|
|
534
|
+
for dirpath, dirnames, filenames in os.walk(root):
|
|
535
|
+
depth = dirpath[len(root):].count(os.sep)
|
|
536
|
+
if depth >= maxdepth:
|
|
537
|
+
dirnames[:] = []
|
|
538
|
+
continue
|
|
539
|
+
dirnames[:] = [d for d in dirnames
|
|
540
|
+
if d not in ('__pycache__', '.git', 'node_modules')]
|
|
541
|
+
for fn in filenames:
|
|
542
|
+
if fn == fname:
|
|
543
|
+
p = os.path.join(dirpath, fn)
|
|
544
|
+
if best is None or os.path.getmtime(p) > os.path.getmtime(best):
|
|
545
|
+
best = p
|
|
546
|
+
except Exception:
|
|
547
|
+
pass
|
|
548
|
+
return best
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
def _search_case_file(project_name: str, folder: str) -> Optional[str]:
|
|
552
|
+
"""广搜同名 .pscx:快路径 bases + PSCAD 安装根(深度受限),取最新。"""
|
|
553
|
+
import glob as _glob
|
|
554
|
+
bases = [folder, os.getcwd(), os.path.expanduser('~/Documents'),
|
|
555
|
+
os.path.expanduser('~/PSCAD'), os.path.expanduser('~/pscad_cases')]
|
|
556
|
+
best = None
|
|
557
|
+
for base in bases:
|
|
558
|
+
try:
|
|
559
|
+
hits = _glob.glob(os.path.join(base, '**', project_name + '.pscx'),
|
|
560
|
+
recursive=True)
|
|
561
|
+
except Exception:
|
|
562
|
+
hits = []
|
|
563
|
+
for h in hits:
|
|
564
|
+
if best is None or os.path.getmtime(h) > os.path.getmtime(best):
|
|
565
|
+
best = h
|
|
566
|
+
exe = _cfg_exe()
|
|
567
|
+
if exe:
|
|
568
|
+
root = os.path.dirname(os.path.dirname(os.path.abspath(exe)))
|
|
569
|
+
found = _walk_find(root, project_name + '.pscx')
|
|
570
|
+
if found and (best is None or os.path.getmtime(found) > os.path.getmtime(best)):
|
|
571
|
+
best = found
|
|
572
|
+
return best
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
def _materialize_blank(project_name: str, folder: str) -> Optional[str]:
|
|
576
|
+
"""强落盘兜底:内置空白模板复制为 folder/name.pscx 并改写工程名。
|
|
577
|
+
|
|
578
|
+
覆盖 mhi 2.9.7 + PSCAD 5.0.0(create_case 仅内存、save/save_as 均不可用)
|
|
579
|
+
等任何组合,保证工程一定有磁盘落盘文件。
|
|
580
|
+
"""
|
|
581
|
+
try:
|
|
582
|
+
blank = os.path.join(os.path.dirname(os.path.dirname(
|
|
583
|
+
os.path.abspath(__file__))), 'templates', '_blank.pscx')
|
|
584
|
+
if not os.path.isfile(blank):
|
|
585
|
+
return None
|
|
586
|
+
target = os.path.join(folder, project_name + '.pscx')
|
|
587
|
+
with open(blank, encoding='utf-8') as fh:
|
|
588
|
+
text = fh.read()
|
|
589
|
+
text = re.sub(r'<project name="[^"]*"',
|
|
590
|
+
'<project name="%s"' % project_name, text, count=1)
|
|
591
|
+
with open(target, 'w', encoding='utf-8') as fh:
|
|
592
|
+
fh.write(text)
|
|
593
|
+
return target if os.path.isfile(target) else None
|
|
594
|
+
except Exception:
|
|
595
|
+
return None
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
def _persist_case(prj: Any, project_name: str,
|
|
599
|
+
folder: str) -> Tuple[Optional[str], List[str]]:
|
|
600
|
+
"""尽力把会话内新建工程落盘,返回 (实际 .pscx 路径或 None, 尝试记录)。
|
|
528
601
|
|
|
529
602
|
mhi-pscad 2.9.7 的 create_case(project_name, folder=...) 与 save() 都可能
|
|
530
603
|
不按 folder 写 .pscx(工程仅在 PSCAD 会话内存)。依次尝试:
|
|
531
604
|
① save/save_as/save_case 变体;② prj 路径属性;③ 候选目录全盘搜同名文件。
|
|
532
605
|
"""
|
|
606
|
+
attempts: List[str] = []
|
|
533
607
|
expected = os.path.join(folder, project_name + '.pscx')
|
|
534
608
|
try:
|
|
535
609
|
# ① 常见保存 API
|
|
@@ -538,10 +612,13 @@ def _persist_case(prj: Any, project_name: str, folder: str) -> Optional[str]:
|
|
|
538
612
|
try:
|
|
539
613
|
fn = getattr(prj, meth)
|
|
540
614
|
fn(*args)
|
|
541
|
-
|
|
615
|
+
attempts.append('%s() -> 已调用' % meth)
|
|
616
|
+
except Exception as exc:
|
|
617
|
+
attempts.append('%s() -> 失败: %s' % (meth, exc))
|
|
542
618
|
continue
|
|
543
619
|
if os.path.isfile(expected):
|
|
544
|
-
|
|
620
|
+
attempts.append('目标文件已确认: %s' % expected)
|
|
621
|
+
return expected, attempts
|
|
545
622
|
# ② prj 自带路径属性
|
|
546
623
|
for attr in ('path', 'filename', 'file_name', 'case_path',
|
|
547
624
|
'project_path'):
|
|
@@ -551,27 +628,24 @@ def _persist_case(prj: Any, project_name: str, folder: str) -> Optional[str]:
|
|
|
551
628
|
p = p()
|
|
552
629
|
if isinstance(p, str) and p.lower().endswith('.pscx') \
|
|
553
630
|
and os.path.isfile(p):
|
|
554
|
-
|
|
631
|
+
attempts.append('prj.%s -> %s' % (attr, p))
|
|
632
|
+
return p, attempts
|
|
555
633
|
except Exception:
|
|
556
634
|
continue
|
|
557
|
-
# ③
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
os.path.expanduser('~/PSCAD')]
|
|
561
|
-
best = None
|
|
562
|
-
for base in bases:
|
|
635
|
+
# ③ 广搜同名文件(含 PSCAD 安装根):找到则复制到目标目录(等效落盘)
|
|
636
|
+
found = _search_case_file(project_name, folder)
|
|
637
|
+
if found:
|
|
563
638
|
try:
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
except Exception:
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
return None
|
|
639
|
+
shutil.copy2(found, expected)
|
|
640
|
+
attempts.append('找到并复制到目标目录: %s -> %s' % (found, expected))
|
|
641
|
+
return expected, attempts
|
|
642
|
+
except Exception as exc:
|
|
643
|
+
attempts.append('复制失败: %s' % exc)
|
|
644
|
+
attempts.append('目录搜索无命中')
|
|
645
|
+
return None, attempts
|
|
646
|
+
except Exception as exc:
|
|
647
|
+
attempts.append('整体异常: %s' % exc)
|
|
648
|
+
return None, attempts
|
|
575
649
|
|
|
576
650
|
|
|
577
651
|
def connect_and_load_project(project_name: str,
|
|
@@ -609,10 +683,15 @@ def connect_and_load_project(project_name: str,
|
|
|
609
683
|
return _err(msg)
|
|
610
684
|
|
|
611
685
|
# folder 回退链:显式传入 → PSCAD_WORK_DIR 环境变量 → 用户目录 ~/pscad_cases
|
|
612
|
-
#
|
|
686
|
+
# (无盘符依赖,任何机器开箱即用;立即创建,保证缺省路径同样可写可落盘)
|
|
613
687
|
folder = folder or DEFAULT_FOLDER or os.path.expanduser('~/pscad_cases')
|
|
688
|
+
try:
|
|
689
|
+
os.makedirs(folder, exist_ok=True)
|
|
690
|
+
except Exception:
|
|
691
|
+
pass
|
|
614
692
|
_prj_folder = folder
|
|
615
|
-
pscx_path: Optional[str] = None
|
|
693
|
+
pscx_path: Optional[str] = None # 实际落盘的 .pscx 路径(探测后回报)
|
|
694
|
+
save_attempts: List[str] = [] # 落盘尝试记录(诊断用)
|
|
616
695
|
|
|
617
696
|
prj = None
|
|
618
697
|
try:
|
|
@@ -632,14 +711,20 @@ def connect_and_load_project(project_name: str,
|
|
|
632
711
|
|
|
633
712
|
if prj is None and create_if_missing:
|
|
634
713
|
try:
|
|
635
|
-
# 目录不存在可能导致 create_case 静默不落盘:先确保目标目录存在
|
|
636
|
-
try:
|
|
637
|
-
os.makedirs(folder, exist_ok=True)
|
|
638
|
-
except Exception:
|
|
639
|
-
pass
|
|
640
714
|
_pscad.create_case(project_name, folder=folder)
|
|
641
715
|
prj = _pscad.project(project_name)
|
|
642
|
-
pscx_path = _persist_case(prj, project_name, folder)
|
|
716
|
+
pscx_path, save_attempts = _persist_case(prj, project_name, folder)
|
|
717
|
+
if not pscx_path:
|
|
718
|
+
# 强落盘兜底:内置空白模板复制为 name.pscx 再 load(任何组合都持久化)
|
|
719
|
+
pscx_path = _materialize_blank(project_name, folder)
|
|
720
|
+
if pscx_path:
|
|
721
|
+
try:
|
|
722
|
+
_pscad.load(pscx_path.replace('\\', '/'))
|
|
723
|
+
prj = _pscad.project(project_name)
|
|
724
|
+
save_attempts.append(
|
|
725
|
+
'强落盘兜底:内置空白模板 -> %s' % pscx_path)
|
|
726
|
+
except Exception as exc:
|
|
727
|
+
save_attempts.append('强落盘兜底 load 失败: %s' % exc)
|
|
643
728
|
if pscx_path:
|
|
644
729
|
folder = os.path.dirname(pscx_path) # 会话状态跟随真实落盘目录
|
|
645
730
|
_prj_folder = folder
|
|
@@ -659,11 +744,14 @@ def connect_and_load_project(project_name: str,
|
|
|
659
744
|
_main = None
|
|
660
745
|
return _err('打开 Main 画布失败: %s' % exc)
|
|
661
746
|
result = {'project': project_name, 'canvas': 'Main',
|
|
662
|
-
'pscx_path': pscx_path}
|
|
747
|
+
'folder': folder, 'pscx_path': pscx_path}
|
|
748
|
+
if save_attempts:
|
|
749
|
+
result['save_attempts'] = save_attempts
|
|
663
750
|
if create_if_missing and not pscx_path:
|
|
664
751
|
result['warning'] = ('create_case 未能在磁盘找到 .pscx(mhi 2.9.7 可能仅'
|
|
665
752
|
'内存建工程):工程仅存在于当前 PSCAD 会话,退出即丢;'
|
|
666
|
-
'
|
|
753
|
+
'已尝试落盘目录 <%s>,建议改用已有模板 .pscx 加载,'
|
|
754
|
+
'或确认该目录可写。' % folder)
|
|
667
755
|
return _ok(result)
|
|
668
756
|
except Exception as exc:
|
|
669
757
|
return _err(exc)
|