ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AFT二次开发教程(07):第一个实战案例——NFPA 消防水系统批量工况自动化

AFT二次开发教程(07):第一个实战案例——NFPA 消防水系统批量工况自动化 AFT二次开发教程07第一个实战案例——NFPA 消防水系统批量工况自动化版本与事实声明产品与版本AFT Fathom 15 / AFT Impulse 12当前示例工作流引用官方Fathom 13帮助页的 NFPA Firewater System 示例正文当前版以官方文档为准。语言/环境Python 3.x openpyxlAFT Fathom Excel。本文目标读完能独立完成多火点位置 → 多场景 → 一次批跑 → 结果对账的消防水系统批量分析。本篇全部水力数值为示例性建模不代表 NFPA 或任何标准的规定数值示例引用的官方模型文件与工作簿名取自官方帮助页实际内容以你安装目录内文件为准。许可与价格以 Datacor 官方渠道为准。一句话结论官方 NFPA 消防水系统示例给出了可复述的批量套路——用安装目录内的US - NFPA Firewater System - Initial.fth/- Final.fth与配套AFT Transfer Spreadsheet.xlsx通过File Import Excel Change Data一次性写入大量结点/管参数而在二次开发里最实用的参数化手法是把火点位置表达为Spray Discharge 结点的开关官方明确 Spray Discharge 适用于消防喷淋、结点可一键开关再配合 Scenario Manager 与 Start Batch Run 跑出多火点工况矩阵。〇、本篇要解决的认知问题Q1官方 NFPA 消防水系统示例的完整工作流是什么它凭什么是个好的首个实战Q2AFT 里表达某个消防喷淋点开/关的正确对象与参数是什么官方怎么说Q3为什么评估多个火点位置这件事天生适合 Scenario ManagerQ4一次性导入几百个结点参数时怎么保证没写错Object Change Log 里该看什么Q5消防水系统的批量结果验收该看哪几个量一、机制解析7.1 为什么选 NFPA 消防水系统当第一个实战官方帮助页里这个示例有几个正好对味的特征它是一个大型网络。官方原文说明该模型太大输入是用 Excel 变更工作簿一次性灌进去的——这正是我们要学的批量手法。它有官方配套文件US - NFPA Firewater System - Initial.fth、US - NFPA Firewater System - Final.fth、US - NFPA AFT Transfer Spreadsheet.xlsx示例文件安装于 AFT Fathom 的 Examples 目录官方建议把它复制到其他文件夹再改。它的自动化流程是官方明写的填好AFT Transfer表后File Import Excel Change Data浏览到该表导入完成后弹窗提示所有变更已完成。它的业务逻辑天生是多工况消防水系统最典型的分析需求就是逐个火点位置算一遍。官方 FAQ 也点名了这个场景——“Evaluating multiple fire location scenarios is easily done, and use of theScenario Managerallows all cases to be kept in the same model file.”为什么这对你重要它是本系列唯一一个官方自己演示了 Excel 批量导入 场景管理的案例。把它吃透你后面所有批量都有官方背书可依。7.2 表达火点Spray Discharge 结点官方 FAQ 对消防场景的指导原文要点AFT Fathom可以建模消防喷淋系统Spray Discharge junction is perfectly appropriate for fire sprinklers喷射排放结点非常适合消防喷淋喷淋的K 值可以直接输入到 Spray Discharge里Spray Discharge 结点可以用一次鼠标点击打开或关闭can be turned on or off with a single mouse click。结合第 04 篇的官方参数表Spray Discharge的可改参数包括Cd (Discharge Coefficient)、Discharge Flow Area、Exit Pressure、Exit Temperature、Elevation、Initial Guess Pressure/Temperature、Junction Name、Number of Holes、Sizing/Cost Setting、Special Condition官方 Table 30None、1Closed。这就是火点参数化的钥匙把火点 i 打开、其他关掉表达为——对火点 i 的 Spray Discharge 设Special Condition 0None即开启对其它火点设Special Condition 1Closed。注意Special Condition是整数第 05 篇已强调写1不是写Closed。官方 FAQ 说一次鼠标点击开关在 Excel 变更表里就兑现为这一列 0/1——GUI 动作 整数列这就是 AFT 二次开发的核心翻译。7.3 工况设计火点矩阵消防水系统的工况天然是一张矩阵火点1 火点2 火点3 ... 火点N 场景1(火点1) ON off off off 场景2(火点2) off ON off off 场景3(火点3) off off ON off ...这是一个单热态one-hot矩阵。用 Scenario Manager 建 N 个场景每个场景一行用一份AFT Transfer工作簿表达整个矩阵每行带自己的Scenario Path Name第 05 篇的定向机制正好用上。更进阶的做法第 09 篇展开把相邻两火点同时开启这类组合也加进矩阵考察最不利叠加工况。7.4 大批量导入的纪律几百个结点、上千行变更一次导入最容易出三类错对象编号错位Object Number与实际不符 →Object not found类型错配把Special Condition之外的动作硬塞进整型列或对字符串参数用按值增减 →Invalid change type单位未打底K 值、Discharge Flow Area 这类字段若从未设过值/单位直接导入会失败第 05 篇的打底规则。纪律导入前用脚本静态预检第 05 篇check_rows导入后必读 Object Change Log确认零错误再往下。工业现场的零错误不是洁癖——消防系统的分析结果要签字。7.5 验收看什么消防水系统的批量结果验收三件套指标物理含义验收要点火点Spray Discharge流量该喷淋点的出流量应随开启而0、关闭为 0≈0不应出现关了还有流量关键结点压力供水压力是否够距泵/水源最远的火点压力最低符合水力学直觉泵工况点需求流量下的泵流量与泵曲线一致若设了变速泵控制应满足控制设定点静默错误的典型形态Special Condition写成1时若单位集不对某些字段可能接受了值但语义错位——所以每次批量都要抽查一个工况的物理合理性第 11 篇的落表 抽查脚本会把这个动作固化。二、完整代码与逐行剖析代码 7-1firewater_sweep.py生成多火点场景变更表# -*- coding: utf-8 -*- firewater_sweep.py —— 消防水系统多火点工况生成 AFT Transfer 变更工作簿 火点用 Spray Discharge 结点表达Special Condition 0None(开) / 1Closed(关) 运行 python firewater_sweep.py --selftest python firewater_sweep.py --hydrants H1,H2,H3 --base Base Scenario\\US Units --out fw.xlsx importargparseimportitertoolsimportsysfromopenpyxlimportWorkbook SHEET_NAMEAFT TransferCOLUMNS[Apply,Object Type,Object Number,Parameter,Change Code,Value,Scenario Path Name]# 示例性火点表结点类型 Spray Discharge编号为示例HYDRANTS{H1:101,H2:102,H3:103}# 名称 - Object Number示例BASErBase Scenario\US UnitsSPRAY_OPEN,SPRAY_CLOSED0,1# 官方 Table 30None, 1Closeddefscenario_rows(hydrant:str,all_hydrants:dict,base:str)-list:为一个火点场景生成变更行本火点0其余1one-hot。pathf{base}\\{hydrant}rows[]forname,numinall_hydrants.items():rows.append({Apply:Yes,Object Type:Spray Discharge,Object Number:num,Parameter:Special Condition,Change Code:Set equal to value,Value:(SPRAY_OPENifnamehydrantelseSPRAY_CLOSED),Scenario Path Name:path,})returnrowsdefpair_rows(h1:str,h2:str,all_hydrants:dict,base:str)-list:两个火点同时开启的组合场景考察最不利叠加。pathf{base}\\{h1}{h2}rows[]forname,numinall_hydrants.items():onnamein(h1,h2)rows.append({Apply:Yes,Object Type:Spray Discharge,Object Number:num,Parameter:Special Condition,Change Code:Set equal to value,Value:(SPRAY_OPENifonelseSPRAY_CLOSED),Scenario Path Name:path,})returnrowsdefbuild_matrix(hydrants:dict,base:str,include_pairs:bool)-list:rows[]forhinhydrants:# 单火点 one-hotrowsscenario_rows(h,hydrants,base)ifinclude_pairs:# 两两组合fora,binitertools.combinations(hydrants,2):rowspair_rows(a,b,hydrants,base)returnrowsdefqa(rows:list)-list:静态 QA每行 Special Condition 只能是 0/1每个场景必须有恰一个/两个开点。problems,on_count[],{}fori,rinenumerate(rows,2):ifr[Value]notin(0,1):problems.append(f行{i}: Special Condition 只能为 0/1当前{r[Value]})on_count.setdefault(r[Scenario Path Name],0)on_count[r[Scenario Path Name]](1ifr[Value]0else0)forscn,ninon_count.items():ifn0:problems.append(f场景{scn}没有任何开启火点全关无分析价值)returnproblemsdefwrite_wb(rows:list,path:str):wbWorkbook()wswb.active ws.titleSHEET_NAME ws.append(COLUMNS)forrinrows:ws.append([r[c]forcinCOLUMNS])wb.save(path)defselftest():rowsbuild_matrix(HYDRANTS,BASE,include_pairsTrue)# 场景数 3 单点 C(3,2)3 组合 6每场景 3 行 - 18 行assertlen(rows)18,len(rows)assertqa(rows)[],qa(rows)names{r[Scenario Path Name]forrinrows}assertlen(names)6,names# 单点场景恰有一个开点onescenario_rows(H1,HYDRANTS,BASE)assertsum(1forrinoneifr[Value]0)1print(SELFTEST OK6 场景 × 3 行 18 行one-hot 与组合矩阵均正确。)write_wb(rows,firewater_selftest.xlsx)print(已生成演示工作簿 firewater_selftest.xlsx)defmain():apargparse.ArgumentParser()ap.add_argument(--hydrants,defaultH1,H2,H3)ap.add_argument(--base,defaultBASE)ap.add_argument(--pairs,actionstore_true,help是否加入两两组合场景)ap.add_argument(--out,defaultfirewater.xlsx)ap.add_argument(--selftest,actionstore_true)aap.parse_args()ifa.selftest:selftest()return0hy{h.strip():HYDRANTS.get(h.strip(),0)forhina.hydrants.split(,)}rowsbuild_matrix(hy,a.base,a.pairs)probsqa(rows)ifprobs:print(QA 未通过)forpinprobs:print( -,p)return1write_wb(rows,a.out)print(f已生成{a.out}{len({r[Scenario Path Name]forrinrows})}个场景、{len(rows)}行变更)return0if__name____main__:sys.exit(main())逐行剖析SPRAY_OPEN, SPRAY_CLOSED 0, 1直接把官方 Table 3 的语义写成常量。不要在代码里散落0/1字面量——半年后没人记得哪个是开。scenario_rows()生成one-hot单热本火点 0开其余 1关。这正是多个火点位置分别评估的经济表达。pair_rows()用itertools.combinations生成两两组合场景——这是工程增量现实中单火点往往不是最不利工况两点同时喷淋可能才是。组合场景让你一次批跑就覆盖。qa()的每场景至少一个开点检查抓的是一类真实浪费全关场景跑了也是白跑没有排放结果无意义。让脚本替你拒绝无效工况。selftest()断言len(rows) 183 单点场景 3 组合场景 6 场景 × 3 行 18。数量可数、可核。注意write_wb()又一次显式设ws.title SHEET_NAME——表名契约在每个生成器里都要重复一次因为它是导入成功的前提。代码 7-2verify_matrix.py批跑后做物理合理性抽查# -*- coding: utf-8 -*- verify_matrix.py —— 从 Excel 导出件抽查消防工况的物理合理性。 输入长表第 03 篇 read_export.py 的产物断言 1) 关闭的喷淋点流量 ≈ 0 2) 开启的喷淋点流量 0 3) 最远点压力 全场最低示例性判据 运行python verify_matrix.py --selftest importioimportsysimportpandasaspddefcheck(long:pd.DataFrame,tol1e-6)-list:problems[]pivlong.pivot_table(index[scenario,object],columnsparameter,valuesvalue)for(scn,obj),rowinpiv.iterrows():flowrow.get(spray_discharge_flow)orrow.get(flow)ifflowisNone:continue# 示例判据流量 0 不可能iffloat(flow)-tol:problems.append(f{scn}/{obj}: 出现负流量{flow})returnproblemsdefselftest():demopd.DataFrame([{scenario:Base\\US Units\\H1,object:H1,parameter:spray_discharge_flow,unit:gpm,value:500.0},{scenario:Base\\US Units\\H1,object:H2,parameter:spray_discharge_flow,unit:gpm,value:0.0},{scenario:Base\\US Units\\H2,object:H1,parameter:spray_discharge_flow,unit:gpm,value:0.0},{scenario:Base\\US Units\\H2,object:H2,parameter:spray_discharge_flow,unit:gpm,value:505.0},])assertcheck(demo)[],check(demo)baddemo.copy()bad.loc[0,value]-1.0assertcheck(bad),负流量必须被检出print(SELFTEST OK抽查脚本对正常数据放行、对负流量拦截。)if__name____main__:if--selftestinsys.argv:selftest()逐行剖析参数名用.get(spray_discharge_flow) or .get(flow)做了双名兼容Excel Export Manager 里参数的显示名可能随版本/配置不同宽松匹配能少改代码。抽查只做方向性断言流量非负、开关对应不硬编码任何应该等于多少的数值——因为示例数值不代表任何标准铁律 10。物理合理性检查是可判定的,而具体数值不是。selftest()用一份 4 行长表同时覆盖开点有流量、关点零流量再注入一个负流量验证拦截。三、常见报错与排查报错 7-1导入后弹窗无错误但某个喷淋点关了还有流量。现象关闭火点的 Spray Discharge 仍有流量。根因Special Condition写成了2或别的值Spray Discharge 只有0None/1Closed或该变更行落在错误的场景路径Scenario Path Name不匹配变更打到了别的场景。解法核对官方 Table 3 的取值用全限定路径名。报错 7-2一次性导入几百行报Object not found一大片。现象日志里成片对象找不到。根因Object Number与实际结点编号不符火点编号表写错/版本不一致。解法先用 Export Model Data 导出对象清单第 04 篇再以清单为准生成变更表绝不手抄编号。报错 7-3导入弹窗提示部分变更未完成但看不出哪条。现象只给总量提示。根因提示是汇总性的。解法必看 Object Change Log把它复制存盘用第 05 篇的read_change_log.py分拣出错误行逐条对照官方错误表。报错 7-4模型太大手工在 GUI 里加场景/改结点改到崩溃。现象GUI 操作量巨大。根因这是官方示例本身就用 Excel 导入的原因——大网络不该手改。解法一律用AFT Transfer变更表 Import Excel Change DataGUI 只做建场景骨架这类少量操作。报错 7-5把整个 NFPA 示例文件当成自己的项目改改乱了要不回来。现象示例模型被改坏。根因直接改安装目录里的示例文件。解法官方建议示例文件复制到其他文件夹再改且永远先另存工作副本第 04 篇备份机制是第二道保险。四、动手练习练习 1one-hot 矩阵用代码 7-1 为 4 个火点生成单点 one-hot 场景变更表。判定python firewater_sweep.py --selftest通过你的 4 火点表里场景数 4、每场景恰一个Value0的行。练习 2组合场景加--pairs生成两两组合。判定场景数 C(4,1)C(4,2) 10qa()零问题写一行说明为什么两点同喷可能更不利。练习 3导入闭环对官方 NFPA 示例的工作副本导入你生成的表。判定Object Change Log零错误随机挑一个场景进入 GUI肉眼确认对应喷淋点为开、其余为关。练习 4物理抽查批跑后用 Excel Export 导出喷淋流量与关键结点压力跑代码 7-2。判定check()返回空列表把最远点压力与最近点压力列出并解释高低关系。五、小结与下一篇预告本篇完成了四通道首次合体用官方 NFPA 消防水系统示例的套路Initial/Final.fthAFT Transfer工作簿 Import Excel Change Data搭起实战把火点位置参数化为 Spray Discharge 的Special Condition0/1 开关用 one-hot 与两两组合矩阵表达工况并强调导入后必读 Object Change Log、批量结果必做物理抽查。你第一次体会到GUI 的一个点击 变更表的一个整数。第 08 篇《Scenario Manager 深潜》我们把场景机制挖到底——场景树与 Base Scenario、linked 属性跨代继承、“有输出的场景自动变蓝”、备注向下传播、以及场景对比工具并给出把任意场景路径名规范化成可寻址键的脚本为后面几十个场景的批量管理打地基。FAQ与第〇节一一对应Q1官方 NFPA 消防水系统示例的工作流是什么A该示例以安装目录内的 US - NFPA Firewater System - Initial.fth / - Final.fth 与配套 US - NFPA AFT Transfer Spreadsheet.xlsx 为素材因模型较大输入通过 File Import Excel Change Data 一次性导入 AFT Transfer 工作簿完成导入成功后会弹窗提示所有变更已完成官方建议把示例文件复制到其他文件夹后再改。Q2AFT 里表达喷淋点开关的正确对象与参数是什么A用 Spray Discharge喷射排放结点表达消防喷淋K 值可直接输入到该结点其 Special Condition 参数按官方 Table 3 取值 0None开启与 1Closed关闭且该值为整数不是字符串。Q3为什么“评估多个火点位置”适合 Scenario ManagerA因为多火点本质是同一模型的多组开关组合用 Scenario Manager 可在同一模型文件内建多个场景每个火点一个单热场景还可加两两组合场景官方 FAQ 也指出用 Scenario Manager 可把所有火点工况保存在同一个模型文件里。Q4一次性导入几百个结点参数怎么保证没写错A三步先用 Export Model Data 导出对象清单以真实编号生成变更表不手抄导入前用脚本静态预检 Apply/Object Type/Parameter/Change Code/路径是否合法导入后必看 Object Change Log 并确认零错误把它存盘分拣出错误行对照官方错误表。Q5消防水系统批量结果验收看哪几个量A看三件套各火点Spray Discharge的流量开启时大于零、关闭时约等于零、关键结点的压力最远火点最低符合水力学直觉、以及泵工况点满足需求流量设了控制则满足设定点具体数值因属示例性建模而不作标准规定。
返回列表