gPROMS二次开发教程(06):MODEL 语言精讲(二)——数组、并行结构与层次化模型
gPROMS二次开发教程06MODEL 语言精讲二——数组、并行结构与层次化模型版本声明块工具/软件gPROMS 桌面建模环境gPROMS ModelBuilder检索期官方发布锚点gPROMS Process 2022.1.0适用版本以官方发布说明为准语言/环境gPROMS 语言equation-oriented modelling实体MODELS段PARAMETER/VARIABLE关键字UNIT本文目标把一个单元抄三遍的手工作法升级为数组批量方程 层次化实例复用的装置级写法并把这种写法带来的诊断代价讲清楚一句话结论当模型里出现三个以上同类单元时重复代码就从勤快变成负债——正确做法是在同一模型内用下标把重复结构压成一条方程模板一条方程覆盖 N 级 / N 组分如F*(C_A(i) - C_A(i-1)) - V*(-r_A(i)) 0跨模型的逻辑复用则用UNIT声明把子模型实例化进父模型官方能力名Models in hierarchy代价是报错定位从看一行变成沿一条层次路径找。〇、本篇要解决的认知问题Q1模型里的重复有哪几种形态数组下标批量方程、层次化、参数化分别对应哪一种Q2官方能力名Models in hierarchy说的层次化在代码里到底由什么关键字承载父模型与子模型的边界在哪Q3参数化子模型如何实例化怎样做到一份定义、多处复用、各自的参数独立Q4大规模模型里书写效率与可读性怎么权衡层次化带来的诊断代价具体是什么Q5本篇的层次化写法与后续自定义模型库第 13 篇是什么关系一、机制解析1.1 先分清三种重复写装置级模型时你遇到的重复其实有三种它们的解法完全不同。把它们混为一谈是装置级模型写崩的第一原因重复形态典型场景对应写法主要代价同一模型内的重复结构多级 CSTR 序列、多组分、多反应、多测点数组 下标批量方程下标写错不易发现一处模板错全部实例错不同模型之间的重复逻辑三个流程都用同一个 CSTR、同一个换热器层次化 UNIT实例Models in hierarchy报错路径变长实例参数传递容易漏项同一模型的不同工况同一反应器换进料、换几何、换动力学参数化子模型 多次实例化参数语义易混哪些该由父模型传、哪些该在子模型内定经验法则先下标后层次。如果一个模型内部就存在重复结构先用数组把它压掉只有当整块逻辑需要在别的模型里复用时才升级为层次化。反过来做先把单级单元做成子模型再在父模型里实例化 N 次会把一个本该一行解决的问题变成 N 个实例、N 组参数、N 处潜在漏项。1.2 数组与下标把 N 份代码压成一条方程模板数组/下标的本质是把第 i 级这件事从人肉编号变成形式参数。你只写一条守恒方程让 i 遍历整个下标集合平台替你展开成 N 条方程。【三份手写版】 【数组模板版】 E2: F*(C_A1 - C_A0) - V*(-r_A1) 0 E2: F*(C_A(i) - C_A(i-1)) - V*(-r_A(i)) 0 E2: F*(C_A2 - C_A1) - V*(-r_A2) 0 i 遍历 1..N自动展开为 N 条 E2: F*(C_A3 - C_A2) - V*(-r_A3) 0 隐患改一处如加一项要改 N 处漏改一处就是无声错误 优势写 3 遍肉眼可核数组写法真正的收益不是少打字而是一致性序列的第 2 级与第 7 级必须服从同一个物理规律模板写法从语法层面保证了这一点一旦你要加一个热损失项只需改一处全序列同步生效。铁律 4商业闭源软件的诚实边界数组的维度声明、下标区间的书写、下标集合的定义方式属于 gPROMS 语言细节一律以随附官方《gPROMS ModelBuilder Guide》为准。本文代码块中一律用C_A(i)这类形式表达带下标的量并在块首声明为结构示意不代表官方语法细节——这是本系列全篇贯彻的写作纪律。1.3 层次化父模型 UNIT实例Models in hierarchy官方自学资源目录中有名为Models in hierarchy的课程/资源讲的就是把模型组织成父—子两级或多级结构。其代码载体已在计划的事实底账中登记在模型内用UNIT声明单元用PORT端口表达对外接口用TOPOLOGY段表达连接而在层次化语境下关键语义只有一句图形拓扑上的一条连接 ⇔ 把两个 PORT端口内的变量写成逐一相等的方程这句连接即方程第 04 篇已建立是层次化的全部秘密父模型并不调用子模型父模型只是把子模型实例的端口变量与父模型自己的变量、或其他实例的端口变量用等式拴在一起。于是求解器看到的仍然是一个巨大的联立方程组——层次化只是书写与组织方式不是新的求解机制。因此父模型的职责被界定得非常清楚层次负责什么不负责什么子模型如单级 CSTR描述一个单元的物理内部守恒、本构、几何不知道自己在序列中的位置也不知道上游是谁父模型如三级工段实例化子模型、传递参数、写出实例之间的连接与边界不重复写子模型的内部物理那是子模型的事最佳实践子模型必须自足可解——即子模型自身的未知量与方程数在入口变量被当作已知的前提下自由度为零。父模型对子模型所做的全部事情就是补上那些入口变量用参数或上游实例的出口。这条纪律让新单元能否塞进流程变成一个可机械化判断的问题而不是凭感觉。1.4 参数化子模型与实例化一份定义多处复用参数化子模型的写法要点是把随实例变化的量全部提出来。以单级 CSTR 为例V体积、k速率常数甚至几何都可以由父模型传入而一级反应、理想混合、等温这类建模假设则固定在子模型内部不随实例变化。┌───────────────────────────┐ │ 子模型cstr_stage │ ← 一份定义只写一次 │ 内部物料衡算 本构 │ │ 入口C_A_in, C_B_in, F │ ← 由外部赋值参数或上游出口 │ 出口C_A, C_B │ ← 供外部取用下游入口 / 父模型输出 │ 参数V, k │ ← 可由父模型按实例分别赋值 └───────────────────────────┘ ▲ ▲ ▲ ┌───────────┘ │ └───────────┐ stage1(V1e-3, k0.05) stage2(V1e-3, k0.05) stage3(V2e-3, k0.05) 同一份子模型定义三组独立参数 → 三套独立方程 → 一个父模型参数传递的价值在于改变结构而不改变代码把第 3 级体积传成 2 倍就得到非等体积三级序列把某级k传成 0就等价于删除该级的反应——结构实验的成本从改模型降到改一行赋值。1.5 效率与可读性的权衡数组与层次化不是免费的。下表是实打实的取舍维度手写重复版数组版层次化版代码行数随 N 线性膨胀近似常数近似常数子模型 父模型各一份一致性保证靠人眼语法层面保证语法层面保证单点报错定位直接看到那一行需查哪一级的下标需沿父 → 实例 → 子模型路径局部特化能力强本级想改就改中可加例外条款强给该实例传不同参数复用范围仅本模型仅本模型跨模型、跨工程经验法则N ≤ 2 手写N ≥ 3 用模板。两级以内的重复手写反而更直观到了三级以上“一致性带来的收益迅速超过定位便利的损失。另外不要为了 DRY不写重复代码而过度抽象——把两个物理机理完全不同的单元硬塞进一个通用单元模型”会让每个实例都带着一堆无关参数这是装置级模型里最常见的过度设计。1.6 层次化的诊断代价层次化让代码变短却让报错路径变长。求解失败时报错通常指向子模型内部的一条方程但真正的根因可能在父模型的参数传递上比如某个实例的V忘了赋值于是该实例的入口体积异常。定位方法只有一条沿层次路径逐级回落检查 报错的子模型方程 → 该方程依赖的入口变量谁来赋值父模型还是上游实例 → 父模型中对应的赋值语句 / 连接方程 → 更上层如果是三级以上的嵌套最佳实践为控制诊断代价层次深度建议不超过三层子模型 → 父模型 → 工程级超过三层后报错归属开始变得模糊。同时给实例起带层次含义的名字stage1、stage2、preheat_bank_A让报错里的名字自带位置信息——这一步在写模型时几乎零成本在排查时回报极高。1.7 与自定义模型库第 13 篇的衔接层次化是模型库的技术前提只有当一个单元能被独立定义、参数化、并在别的模型里实例化时库才成立。第 13 篇要做的组织规范命名、接口契约、版本管理、回归基线本质上都是给本篇的子模型加一层工程纪律。所以本篇的产出物不是一段示例代码而是一条判据你这个单元模型能不能被别人以一个实例 一组参数的方式直接使用能它就是库资产不能它只是一次性的脚本。二、完整模型与逐行剖析代码 2-1多级 CSTR 序列·数组与下标批量方程结构示意% --------------------------------------------------------------------------- % 说明本块为结构示意。MODELS / PARAMETER / VARIABLE 为已确证关键字 % 数组的维度声明、下标区间与下标集合的定义语法以官方《gPROMS ModelBuilder % Guide》为准此处用 C_A(i) 形式表达带下标的量不代表官方语法细节。 % 数值为教学示例值正式使用须替换为可引用文献或官方示例数据铁律 10。 % 物理背景N 级串联全混流反应器CSTR各级等温、理想混合一级反应 A - B。 % --------------------------------------------------------------------------- MODELS PARAMETER N 3 % 级数示意用 3 级 V 1.0e-3 % 单级有效体积示意单位 F 1.0e-4 % 进料体积流量 C_A0 100.0 % 进料中 A 的浓度 C_B0 0.0 % 进料中 B 的浓度示例不含 B k 0.05 % 一级反应速率常数示例值须以文献/官方数据替换 VARIABLE C_A(i) % 第 i 级出口液相中 A 的浓度维度声明语法以官方文档为准 C_B(i) % 第 i 级出口液相中 B 的浓度 r_A(i) % 第 i 级 A 的净生成速率辅助定义量非独立物理量 %% 批量方程区同一模板覆盖 i 1..N r_A(i) -k*C_A(i) % E1 本构一级反应各级共用一条模板 F*(C_A(i) - C_A(i-1)) - V*(-r_A(i)) 0 % E2 组分 A 稳态物料衡算残差式 F*(C_B(i) - C_B(i-1)) V*(-r_A(i)) 0 % E3 组分 B 稳态物料衡算与 A 计量耦合 %% E2/E3 的解释进料带入 - 出料带出 反应生成 0稳态、无累积项 %% 注意 E3 中生成项符号与 E2 相反A 被消耗即 B 被生成等摩尔计量 %% 序列入口边界把第 1 级的上一级接到进料 C_A(0) C_A0 % E4 入口边界A 的进料浓度 C_B(0) C_B0 % E5 入口边界B 的进料浓度 %% 边界条件的表达方式以下标 0 代表进料或单独写出第 1 级方程 %% 以官方文档为准此处仅为结构示意。逐行剖析N放在PARAMETER段级数是建模前就确定的结构性已知量。注意它同时也决定了下标集合的规模——结构参数与数值参数放在同一段是 gPROMS 语言量与结构不做硬区分的体现。C_A(i)、C_B(i)、r_A(i)是待求量进VARIABLE。其中r_A(i)是辅助定义量它并非独立物理未知量而是为了让方程可读而引入的中间量。它每引入一个就多用一条方程E1去定义它——自由度不变可读性提升。这是长模型里非常划算的一笔交易。E2 的物理身份是稳态物料衡算F*(C_A(i) - C_A(i-1))是进料带入与出料带出的净差V*(-r_A(i))是体积内 A 的消耗量。向右移项写成残差 0与第 05 篇的规范一致。E3 与 E2 的符号关系最容易写错-r_A在 E2 中是消耗项负号在 E3 中是生成项正号。写反应网络时每一个组分的生成/消耗符号都要单独核对这类错误不会报语法错只会给出错误答案铁律 9改完必验。E4/E5 是边界方程把序列入口与进料参数拴起来。没有这两条整个序列的入口是自由的——这是数组模型为什么解不出的头号原因。自由度核对铁律 8项数量说明未知数3N 9C_A(i)、C_B(i)、r_A(i)i 1…3未知数边界2C_A(0)、C_B(0)若按下标 0 写法它们是待求量方程 E1N 3本构速率方程 E2N 3A 的物料衡算方程 E3N 3B 的物料衡算方程 E4/E52入口边界合计未知 11 vs 方程 11自由度 0可解与人手写三份代码相比模板版用3 条 E1 3 条 E2 3 条 E3覆盖了整个序列且第 7 级忘记写衡算这类错误在语法上不可能发生。代码 2-2层次化——父模型内三个UNIT实例与连接结构示意% --------------------------------------------------------------------------- % 说明本块为结构示意。UNIT 为已确证关键字用于声明单元PORT端口 % 与 TOPOLOGY拓扑连接段的语义为把端口内变量写成逐一相等的方程。 % 实例的参数访问写法如 stage1.V与端口变量命名以官方《gPROMS % ModelBuilder Guide》为准此处仅为结构示意不代表官方语法细节。 % 物理背景父模型 一个三级串联反应工段子模型 单级 CSTR见代码 2-3。 % --------------------------------------------------------------------------- MODELS PARAMETER V_stage 1.0e-3 % 单级体积由父模型统一传入便于整体缩放 V_last 2.0e-3 % 末级体积故意传成 2 倍演示非等体积序列 F 1.0e-4 % 工段进料体积流量 C_A0 100.0 % 工段入口 A 浓度 k 0.05 % 速率常数示例值 VARIABLE C_A_out % 工段出口 A 浓度父模型的对外结果量 C_B_out % 工段出口 B 浓度 %% 层次化三个 UNIT 实例复用同一份单级 CSTR子模型定义 UNIT stage1 AS cstr_stage % 实例 1第 1 级 UNIT stage2 AS cstr_stage % 实例 2第 2 级——与 stage1 同一份子模型 UNIT stage3 AS cstr_stage % 实例 3第 3 级——同一份子模型参数不同 %% 参数传递把父模型的参数浇进每个实例 stage1.V V_stage % 1 级体积 stage2.V V_stage % 2 级体积同级同参数一致性由父模型保证 stage3.V V_last % 3 级体积放大 2 倍 → 结构实验只改一行 stage1.k k % 速率常数三个实例逐一套用可分别替换做敏感性分析 stage2.k k stage3.k k stage1.F F % 各实例的流量串联序列中各级流量相同等密度假设 stage2.F F stage3.F F %% 连接与边界连接语义 上游出口变量与下游入口变量逐一等价 stage1.C_A_in C_A0 % 工段入口 → 第 1 级入口边界 stage1.C_B_in 0.0 % 进料不含 B示例 stage2.C_A_in stage1.C_A % 第 1 级出口 → 第 2 级入口 stage2.C_B_in stage1.C_B % 逐组分连接每个组分都要单独接漏一个就欠定 stage3.C_A_in stage2.C_A % 第 2 级出口 → 第 3 级入口 stage3.C_B_in stage2.C_B C_A_out stage3.C_A % 父模型输出 末级出口 C_B_out stage3.C_B逐行剖析UNIT stage1 AS cstr_stage这一类声明的意义是在这里放一个名为 stage1、型号为 cstr_stage 的单元。父模型由此获得三个相互独立的方程组块它们共用同一份子模型的物理描述但各自的参数与状态互不干扰。参数传递段是层次化最容易出错的地方stage1.V、stage2.V、stage3.V三条必须写全。漏掉任何一条该实例的体积就是未赋值状态——报错往往出现在子模型内部因为那里的衡算用到了V但根因在父模型这一行。这就是 §1.6 所说的诊断代价的具体形态。stage3.V V_last是本篇最值得带走的一行它演示了用一行赋值做结构实验。把三级等体积序列改成末级放大 2 倍不需要动子模型一行代码也不需要复制出第二个子模型。连接方程逐组分写出C_A与C_B各一条。这与第 04 篇的连接即方程完全一致平台不会替你猜哪些变量该接。一个组分漏接就少一条方程整个父模型欠定——数组/层次化写法里漏接比写错更常见。注意stage1.C_A_in C_A0是边界而stage2.C_A_in stage1.C_A是连接。两者语义不同但书写形式一样都是等式。这解释了为什么在 equation-oriented 平台里流程连接与边界条件能统一处理——它们都是方程。自由度核对铁律 8本模型的总自由度可按下式理解总自由度 Σ(各实例自由度) − (连接方程消去的重复未知数) 其中每个实例在入口已赋值的意义下自由度 0子模型自足可解原则 父模型叠加的连接方程把 stage2/stage3 的入口变量与其上游出口视为同一量 ⇒ 逐条消去 结论总自由度 0铁律 8建模先算自由度层次化模型的自由度核对最实用的方法是先逐个核对子模型子模型在入口已知的前提下自由度是否为零再数父模型写了多少条连接方程、消去了多少重复未知数。永远不要试图对一整棵层次树直接数方程——那是人眼最容易数错的场合。代码 2-3被复用的子模型——单级 CSTR结构示意% --------------------------------------------------------------------------- % 说明本块为结构示意。MODELS / PARAMETER / VARIABLE 为已确证关键字 % 子模型与实例的绑定方式、实例属性访问写法如 stage1.V以官方 % 《gPROMS ModelBuilder Guide》为准。数值为教学示例值铁律 10。 % 物理背景单级 CSTR 子模型 —— 代码 2-2 的父模型把它实例化了三次。 % 关键纪律子模型必须自足可解——入口量留给父模型赋值内部方程 % 数量与未知量数量在入口已赋值的前提下恰好匹配。 % --------------------------------------------------------------------------- MODELS PARAMETER V 1.0e-3 % 单级有效体积由父模型按实例覆盖如 stage1.V k 0.05 % 速率常数同样留给父模型赋值便于按级做敏感性分析 F 1.0e-4 % 体积流量串联序列中各级相同等密度假设 VARIABLE C_A_in % 入口 A 浓度★本模型决定不了★等父模型赋值 C_B_in % 入口 B 浓度同上 C_A % 出口 A 浓度供下游实例或父模型输出取用 C_B % 出口 B 浓度同上 r_A % 净生成速率内部辅助量不对外暴露 %% 本构与第 05 篇同一物理写法保持一致 r_A -k*C_A % E1 一级反应速率 %% 稳态物料衡算逐组分一条 F*(C_A - C_A_in) - V*(-r_A) 0 % E2 A 的衡算残差式 F*(C_B - C_B_in) V*(-r_A) 0 % E3 B 的衡算生成项符号与 E2 相反 %% 子模型自足性自检写进文件头随模型一起交付 %% 未知量 5C_A_in, C_B_in, C_A, C_B, r_A − 方程 3E1 ~ E3 2 %% ⇒ 剩下的 2 个自由度恰好由入口量 C_A_in、C_B_in 补齐。 %% 因此父模型对每个实例只做两件事 %% (1) 给两个入口量赋值第 1 级用进料第 2、3 级用上游出口 %% (2) 给参数 V、k、F 赋值可按实例分别覆盖逐行剖析子模型与父模型的分工在此一目了然C_A_in、C_B_in被明确标注为本模型决定不了的量——它们就是接口。子模型不关心上游是谁只关心上游会把这两个量填上。自检结论未知量 5 − 方程 3 2恰好由两个入口量补齐与代码 2-1、2-2 完全一致同一台设备无论是在数组里当第 i 级还是在层次里当 stage1它的自足性判据不变。这条不变性正是第 13 篇讨论模型库资产时最重要的一条质量门槛。注意F放在PARAMETER段而不是VARIABLE在等密度假设下各级流量相同因此它不是待求量而是外部给定的工况量。若你的物理里流量会沿程变化例如有侧线进料它就必须变成VARIABLE并进入端口/接口清单——这是把子模型从够用改到通用的典型演进点。代码 2-4层次结构树与层次化工程纪律对照表% % 层次结构树父 → 实例 → 子模型 % % [工程] gPROMS 工程.gPJ % └─ [父模型] reaction_train_3stage % ├─ UNIT stage1 AS cstr_stage (V V_stage, k k, F F) % ├─ UNIT stage2 AS cstr_stage (V V_stage, k k, F F) % └─ UNIT stage3 AS cstr_stage (V V_last , k k, F F) % ▲ % [子模型] cstr_stage见代码 2-3 % 入口C_A_in, C_B_in, F ← 由父模型赋值参数或上游出口 % 出口C_A, C_B ← 供父模型取用 % 参数V, k ← 由父模型按实例分别赋值 % 假设理想混合、等温、一级反应 A - B固定不随实例变化 % % --------------------------------------------------------------------------- % 层次化名册谁负责什么写模型时同步填排查时直接查 % 层次路径 复查责任 % FILENAME:父模型 参数传递完整性 连接方程完整性 边界 % FILENAME:父模型/stage2 该实例参数取值是否符合预期如 V 是否漏传 % FILENAME:子模型 cstr_stage 内部物理正确性衡算 本构 单位 % --------------------------------------------------------------------------- % 命名纪律最佳实践非语法要求 % 实例名带层次含义stage1 / stage2 / stage3而非 u1 / u2 / u3 % 参数名带归属V_stage父级约定vs V子模型内部名一眼看出谁传给谁 % 假设写入子模型文件头更改假设必须在子模型一处改全工程同步生效 % 逐行剖析这份层次名册把 §1.6 的诊断路径预先写下来。当求解失败、报错指向子模型内部时你不需要临时回忆这个实例的参数是谁给的——名册上已经写明。更关键的是最后三条命名纪律它们不是语法要求而是让报错里的名字自带位置信息的低成本手段。在三级以上的层次结构里这三条纪律能省下的排查时间通常超过写这份名册本身的时间。三、常见报错与排查报错 3-1维度/下标不匹配。现象装配阶段报错或某个下标表达式在部分取值下无定义。根因数组维度与下标区间不一致如声明 3 级却引用了第 0 级或第 4 级或标量与数组混算。解法回到声明处统一维度对边界项如C_A(0)显式确认其语义与写法把下标区间的定义放在显眼位置紧邻N。报错 3-2方程数与实例数不一致自由度被破坏。现象求解器报自由度不足或存在自由变量但手写的方程看起来是够的。根因批量方程只覆盖了部分下标例如 E3 只对 i 1…2 生效或跨组分的连接方程漏写一条C_B_in忘了接。解法按每级每组分一条衡算 每条连接逐组分的口径重数一遍用代码 2-4 的名册逐项打勾。报错 3-3实例参数未传递。现象报错指向子模型内部某条方程例如使用了V的衡算看起来是子模型的问题。根因父模型里漏写该实例的参数赋值如stage2.V缺失。解法沿层次路径回落检查逐个实例核对子模型声明的每个可传入参数是否都在父模型被赋值把这项检查写进代码 2-4 的名册。报错 3-4同名量跨层次冲突。现象连接方程写出来了但结果明显偏向某一个实例或报错提示方程重复。根因父模型与子模型用了同一个名字表达不同物理量例如父模型也有一个C_A与实例的C_A混用。解法命名空间纪律——父模型级量用带含义的名字C_A_out、C_A0实例内量只通过实例名访问stage1.C_A不在父模型重名声明。报错 3-5报错停留在子模型定位困难。现象报错信息只给了子模型里的一条方程看不出是哪一级出的问题。根因层次化的固有代价§1.6加上实例命名无区分度u1、u2。解法把实例改为带层次含义的名字建立代码 2-4 式的名册必要时把该子模型单独实例化到一个最小父模型里试算最小可复现工程快速区分子模型自身有问题还是参数传递有问题。四、动手练习练习 1模板化改造把你手上任意一个手写了三份同类单元的模型改成代码 2-1 的数组/下标形式。判定改造后求解结果与原手写版完全一致作为回归基线铁律 9方程总条数与手写版相同随机抽查第 2 级的衡算与手写版逐项吻合。练习 2结构实验在代码 2-2 中把V_last从 2 倍改为 0.5 倍重新求解并对比C_A_out。判定只改一行参数完成末级缩小实验能说明此时的转化率变化方向A 消耗更多/更少并给出数值结果记入回归基线。练习 3自由度核对为代码 2-2 写出完整的自由度核对要求Σ(实例自由度)、连接方程条数、消去的重复未知数三项分别列出。判定三项齐全且结论为自由度 0能指出若删去stage2.C_B_in stage1.C_B会变成欠定。练习 4漏传实验注释掉代码 2-2 中stage2.V V_stage一行重新求解。判定能观察到报错或异常结果并记录报错指向的位置子模型还是父模型能用自己的话说清外部参数漏传为什么会在子模型内部暴雷。练习 5思考题无标准答案官方能力名Models in hierarchy强调层次化组织。请说明什么样的模型不应该层次化即宁可复制代码并给出两条判断依据。五、小结与下一篇预告本篇把模型的规模这一维度补齐了同一模型内的重复用数组与下标压成一条方程模板一致性由语法保证而不是靠人眼跨模型的重复逻辑用UNIT实例 连接方程表达连接即方程父模型只负责实例化、传参、连接、边界参数化子模型让结构实验退化为改一行赋值。同时必须记住两个代价子模型必须自足可解否则父模型永远补不完缺口、层次越深报错越难归属建议不超过三层且实例名必须自带位置信息。自由度核对在层次化语境下的正确姿势是先逐个子模型核对再数连接方程。第 07 篇《物性与热力学》转向模型之外的一个外部世界物理性质从哪里来、怎么被方程消费。物性不是模型的装饰而是方程组里最容易被当成常数、实际上最影响结论的那一半——我们讲物性调用的抽象层、相平衡与热力学一致性对反应/分离模型的影响、物性参数的数据来源纪律以及物性错了会让仿真怎样失败。本篇认知问题回显FAQQ1模型里的重复有哪几种形态三种写法分别对应哪一种A三种形态。第一是同一模型内的重复结构例如多级 CSTR 序列、多组分、多反应对应数组与下标批量方程一条方程模板覆盖 N 级第二是不同模型之间的重复逻辑例如多个流程都用同一个 CSTR对应层次化与UNIT实例即官方能力名 Models in hierarchy第三是同一模型的不同工况例如同一反应器换进料换几何对应参数化子模型与多次实例化。三者混用是装置级模型写崩的常见起点正确顺序是先下标、后层次。Q2层次化在代码里由什么承载父模型与子模型的边界在哪A承载者是模型内用UNIT声明单元、用PORT端口表达对外接口、用TOPOLOGY段表达连接其核心语义是一条连接等价于把两个端口内的变量写成逐一相等的方程即连接即方程。边界上子模型只描述一个单元的物理包括内部守恒、本构、几何与固定假设它不知道自己处在序列的什么位置父模型只负责实例化子模型、传递参数、写出实例之间的连接与工段级边界不重复写子模型内部物理。Q3参数化子模型如何实例化怎么做到一份定义多处复用A把随实例变化的量全部提出来作为可传入参数例如单级 CSTR 的体积 V、速率常数 k、流量 F把建模假设例如理想混合、等温、一级反应 A 到 B固定在子模型内部。父模型用UNIT stage1 AS cstr_stage这类声明建立多个实例再逐个实例赋值stage1.V V_stage、stage3.V V_last等。这样同一份子模型定义可生成三套独立方程组与三组独立参数改变结构只需改一行赋值例如把末级体积设成 2 倍即可完成非等体积序列实验。Q4效率与可读性怎么权衡层次化的诊断代价具体是什么A数组版代码行数近似常数一致性由语法保证但单点报错需查是哪一级的下标层次化版可跨模型复用但报错定位需沿父模型到实例再到子模型这条路径回落。经验法则是 N 小于等于 2 时手写更直观N 大于等于 3 时用模板且不要为了不写重复代码而把机理完全不同的单元硬塞进一个通用模型。诊断代价的具体形态是报错指向子模型内部某条方程根因却在父模型的参数传递漏项上因此层次深度建议不超过三层并给实例起带位置含义的名字。Q5层次化与自定义模型库是什么关系A层次化是模型库的技术前提。只有当一个单元能被独立定义、参数化并在别的模型里实例化时库才成立。第 13 篇要做的组织规范包括命名、接口契约、版本管理、回归基线本质上都是给本篇的子模型再加一层工程纪律。因此本篇真正的判据是这个单元模型能否被别人以一个实例加一组参数的方式直接使用能则是库资产不能则只是一次性脚本。本文涉及的语言细节以所购版本随附的官方 gPROMS 文档为准。