活动介绍
file-type

Dymola 7.0用户手册第二卷:模型实验与校准详解

PDF文件

下载需积分: 21 | 5.6MB | 更新于2024-07-06 | 161 浏览量 | 31 下载量 举报 1 收藏
download 立即下载
Dymola是一款强大的动态系统建模和模拟工具,其用户手册第二部分详细介绍了Model Experimentation和Model Calibration的相关内容。该手册适用于Dymola 7.0版本,版权由Dynasim AB持有,Modelica是其注册商标。Dymola在工程领域广泛应用,特别是在系统建模、参数分析以及模型校准等方面。 1. Model Experimentation (模型实验) 这部分首先介绍了模型实验的基本概念,强调了通过Dymola进行动态系统模型的测试和评估。内容包括: - **Introduction**:引导读者理解模型实验的重要性,如何通过模型来验证假设、优化设计或预测行为。 - **Varying parameters of a model**:教用户如何在模型中改变参数,以便观察其对系统响应的影响。例如: - **Case Study: Coupled Clutches model** – 提供了一个实际案例,展示了如何处理耦合系统的参数变化,如双离合器模型,帮助理解参数变化对系统性能的影响。 - **Response to parameter perturbations – perturbParameters**:指导用户如何进行参数扰动实验,以研究系统对小范围参数变化的响应。 - **Sweep one parameter – sweepTwoVariants**:介绍了一种参数扫描方法,即单参数或多参数扫描,用于绘制响应曲线,评估参数空间中的关键特性。 - **Monte Carlo Analysis**:讨论了蒙特卡洛分析,这是一种统计方法,用于评估模型在随机参数变化下的性能。 2. Model Calibration (模型校准) 针对实际应用,这部分着重于模型与真实世界数据的关联。内容包括: - **Introduction**:解释了模型校准的目的,即通过调整模型参数使其更好地匹配实验数据,提升模型的准确性。 - **Basic setup and execution of a calibration task**:指南性质,说明如何设置和执行校准任务,可能涉及数据准备、目标函数设定等步骤。 - **Vehicle data**:提及模型校准时使用的车辆数据,可能是来自实验室测量或传感器的数据,用于指导模型参数的调整。 - **Vehicle model**:详细描述了用于校准的车辆模型结构和组成部分,以及如何与实验数据相结合。 - **Validation of the nominal model**:校准后,如何验证未经过校准的原始模型与实际数据的差距,以确保校准过程的有效性。 总结来说,Dymola User Manual Volume 2提供了深入的实践指导,让工程师能够有效地利用这款软件进行模型实验和参数调整,以提高系统模型的精确性和实用性。无论是对于新用户还是有经验的用户,这份文档都是理解和掌握Dymola功能的重要参考资料。

相关推荐

filetype

DYMOLA可以做一个输出接口将换热器模型summary中的制冷量(换热量)导出吗 model CrossFlowHX "Fin and tube moist air vle fluid cross flow HX" extends ThermalSystems.HeatExchangers.FinAndTube.MoistAirVLEFluid.BaseClasses.PartialHX( final nFinSideParallelHydraulicFlows=hxGeometry.nParallelTubes* nCells, final nFinSideParallelHydraulicFlowsPerCell=hxGeometry.nParallelTubes, final nTubeSideParallelHydraulicFlowsPerCell=hxGeometry.nTubeSideParallelHydraulicFlows, moistAirCell( cellGeometry(each final length=hxGeometry.totalHXDepth), each final useFalseDynamics=false, each final pressureDropMoistAirInitial= pressureDropInitialMoistAir), moistAirA( T_phxi( p=portA_gas.p, h=noEvent(actualStream(portA_gas.h_outflow)), xi=noEvent(actualStream(portA_gas.xi_outflow))), phi_phxi( p=portA_gas.p, h=noEvent(actualStream(portA_gas.h_outflow)), xi=noEvent(actualStream(portA_gas.xi_outflow))), d_phxi( p=portA_gas.p, h=noEvent(actualStream(portA_gas.h_outflow)), xi=noEvent(actualStream(portA_gas.xi_outflow)))), moistAirB( T_phxi( p=portB_gas.p, h=noEvent(actualStream(portB_gas.h_outflow)), xi=noEvent(actualStream(portB_gas.xi_outflow))), phi_phxi( p=portB_gas.p, h=noEvent(actualStream(portB_gas.h_outflow)), xi=noEvent(actualStream(portB_gas.xi_outflow))), d_phxi( p=portB_gas.p, h=noEvent(actualStream(portB_gas.h_outflow)), xi=noEvent(actualStream(portB_gas.xi_outflow)))), vleFluidA(T_phxi( p=portA_vle.p, h=noEvent(actualStream(portA_vle.h_outflow)), xi=noEvent(actualStream(portA_vle.xi_outflow))), d_phxi( p=portA_vle.p, h=noEvent(actualStream(portA_vle.h_outflow)), xi=noEvent(actualStream(portA_vle.xi_outflow)))), vleFluidB(T_phxi( p=portB_vle.p, h=noEvent(actualStream(portB_vle.h_outflow)), xi=noEvent(actualStream(portB_vle.xi_outflow))), d_phxi( p=portB_vle.p, h=noEvent(actualStream(portB_vle.h_outflow)), xi=noEvent(actualStream(portB_vle.xi_outflow)))), redeclare record SummaryClass = ThermalSystems.HeatExchangers.FinAndTube.MoistAirVLEFluid.Summaries.CrossSummary, summary( p_vle_A=portA_vle.p, p_vle_B=portB_vle.p, T_vle_A=vleFluidA.T_phxi(), T_vle_B=vleFluidB.T_phxi(), T_degC_vle_A=Modelica.Units.Conversions.to_degC(vleFluidA.T_phxi()), T_degC_vle_B=Modelica.Units.Conversions.to_degC(vleFluidB.T_phxi()), q_vle_A=vleFluidA.q_phxi( portA_vle.p, noEvent(actualStream(portA_vle.h_outflow)), noEvent(actualStream(portA_vle.xi_outflow))), q_vle_B=vleFluidB.q_phxi( portB_vle.p, noEvent(actualStream(portB_vle.h_outflow)), noEvent(actualStream(portB_vle.xi_outflow))), h_vle_A=noEvent(actualStream(portA_vle.h_outflow)), h_vle_B=noEvent(actualStream(portB_vle.h_outflow)), d_vle_A=vleFluidA.d_phxi(), d_vle_B=vleFluidB.d_phxi(), m_flow_vle_A=portA_vle.m_flow, m_flow_vle_B=portB_vle.m_flow, dp_vle=portA_vle.p - portB_vle.p, superheating=noEvent(max(0, noEvent(max(vleFluidB.T_phxi() - vleFluidB.T_dew_pxi(portB_vle.p, noEvent(actualStream( portB_vle.xi_outflow))), vleFluidA.T_phxi() - vleFluidA.T_dew_pxi(portA_vle.p, noEvent(actualStream( portA_vle.xi_outflow))))))), subcooling=noEvent(max(0, noEvent(max(vleFluidB.T_bubble_pxi( portB_vle.p, noEvent(actualStream(portB_vle.xi_outflow))) - vleFluidB.T_phxi(), vleFluidA.T_bubble_pxi(portA_vle.p, noEvent(actualStream(portA_vle.xi_outflow))) - vleFluidA.T_phxi())))), p_air_A=portA_gas.p, p_air_B=portB_gas.p, T_air_A=moistAirA.T_phxi(), T_air_B=moistAirB.T_phxi(), T_degC_air_A=Modelica.Units.Conversions.to_degC(moistAirA.T_phxi()), T_degC_air_B=Modelica.Units.Conversions.to_degC(moistAirB.T_phxi()), h_air_A=noEvent(actualStream(portA_gas.h_outflow)), h_air_B=noEvent(actualStream(portB_gas.h_outflow)), m_flow_air_A=portA_gas.m_flow, m_flow_air_B=portB_gas.m_flow, humRatio_air_A= MediaConfiguration.Media.GasObjectFunctions.humidityRatio_xi( noEvent(actualStream(portA_gas.xi_outflow)), moistAirA.gasPointer), humRatio_air_B= MediaConfiguration.Media.GasObjectFunctions.humidityRatio_xi( noEvent(actualStream(portB_gas.xi_outflow)), moistAirB.gasPointer), phi_air_A=moistAirA.phi_phxi(), phi_air_B=moistAirB.phi_phxi(), w_air_A=portA_gas.m_flow/moistAirA.d_phxi()/hxGeometry.totalFinSideCrossSectionalArea, w_air_B=-portB_gas.m_flow/moistAirB.d_phxi()/hxGeometry.totalFinSideCrossSectionalArea, dp_air=portA_gas.p - portB_gas.p, arrays( final n=nCells, final m=gasType.nc - 1, T_vle_port= ThermalSystems.Internals.getPortValuesStirredVolumeCells( vleFluidA.T_phxi(), vleFluidCell.vleFluid.T, vleFluidB.T_phxi(), vleFluidCell[2:end].portA.m_flow), T_degC_vle_port=Modelica.Units.Conversions.to_degC(summary.arrays.T_vle_port), T_vle_cell=vleFluidCell.vleFluid.T, T_degC_vle_cell=Modelica.Units.Conversions.to_degC(summary.arrays.T_vle_cell), T_finSideWallSurface_cell=moistAirCell.wallSurfaceTemperature, T_degC_finSideWallSurface_cell= Modelica.Units.Conversions.to_degC(summary.arrays.T_finSideWallSurface_cell), T_wall_cell=moistAirCell.wallMaterial.T, T_degC_wall_cell=Modelica.Units.Conversions.to_degC(summary.arrays.T_wall_cell), T_air_portA={if ((moistAirCellFlowType == "flow A-B") or (( moistAirCellFlowType <> "flow B-A") and noEvent( moistAirCell[i].moistAirPortA.m_flow >= 0))) then moistAirCell[i].moistAir_inStream.T else moistAir_outflow[i].T for i in 1:nCells}, T_degC_air_portA=Modelica.Units.Conversions.to_degC(summary.arrays.T_air_portA), T_air_portB={if ((moistAirCellFlowType == "flow A-B") or (( moistAirCellFlowType <> "flow B-A") and noEvent( moistAirCell[i].moistAirPortA.m_flow >= 0))) then moistAir_outflow[i].T else moistAirCell[i].moistAir_inStream.T for i in 1:nCells}, T_degC_air_portB=Modelica.Units.Conversions.to_degC(summary.arrays.T_air_portB), alpha_vle_cell=vleFluidCell.alphaAState ./ vleFluidCell.cellGeometry.heatTransferArea, q_vle_port= ThermalSystems.Internals.getPortValuesStirredVolumeCells( vleFluidA.q_phxi( portA_vle.p, noEvent(actualStream(portA_vle.h_outflow)), noEvent(actualStream(portA_vle.xi_outflow))), vleFluidCell.vleFluid.q, vleFluidB.q_phxi( portB_vle.p, noEvent(actualStream(portB_vle.h_outflow)), noEvent(actualStream(portB_vle.xi_outflow))), vleFluidCell[2:end].portA.m_flow), p_vle_port=cat( 1, {vleFluidCell[1].portA.p}, vleFluidCell.portB.p), h_vle_port=cat( 1, {noEvent(actualStream(vleFluidCell[1].portA.h_outflow))}, noEvent(actualStream(vleFluidCell.portB.h_outflow))), d_vle_port= ThermalSystems.Internals.getPortValuesStirredVolumeCells( vleFluidA.d_phxi(), vleFluidCell.vleFluid.d, vleFluidB.d_phxi(), vleFluidCell[2:end].portA.m_flow), m_flow_vle_port=cat( 1, {vleFluidCell[1].portA.m_flow}, -vleFluidCell.portB.m_flow), w_vle_port=summary.arrays.m_flow_vle_port ./ (summary.arrays.d_vle_port .* vleFluidCell[1].cellGeometry.hydraulicCrossSectionalArea .* hxGeometry.nTubeSideParallelHydraulicFlows), p_air_portA=moistAirCell.moistAirPortA.p, p_air_portB=moistAirCell.moistAirPortB.p, h_air_portA=noEvent(actualStream(moistAirCell.moistAirPortA.h_outflow)), h_air_portB=noEvent(actualStream(moistAirCell.moistAirPortB.h_outflow)), xi_air_portA={noEvent(actualStream(moistAirCell[:].moistAirPortA.xi_outflow[ i])) for i in 1:gasType.nc - 1}, xi_air_portB={noEvent(actualStream(moistAirCell[:].moistAirPortB.xi_outflow[ i])) for i in 1:gasType.nc - 1}, xis_air_wall_cell=moistAirCell.xiCondensingMoistAirWallSaturation, phi_air_portA={if ((moistAirCellFlowType == "flow A-B") or (( moistAirCellFlowType <> "flow B-A") and noEvent( moistAirCell[i].moistAirPortA.m_flow >= 0))) then moistAirCell[i].moistAir_inStream.phi else moistAir_outflow[ i].phi for i in 1:nCells}, phi_air_portB={if ((moistAirCellFlowType == "flow A-B") or (( moistAirCellFlowType <> "flow B-A") and noEvent( moistAirCell[i].moistAirPortA.m_flow >= 0))) then moistAir_outflow[i].phi else moistAirCell[i].moistAir_inStream.phi for i in 1:nCells}, alpha_air_cell=moistAirCell.heatTransfer.alphaA ./ moistAirCell.cellGeometry.heatTransferArea))); /****************** Connectors *******************/ ThermalSystems.Connectors.VLEFluidPort portB_vle(final vleFluidType= vleFluidType) "VLEFluid portB" annotation (Placement( transformation(extent={{130,-10},{150,10}}, rotation=0))); ThermalSystems.Connectors.VLEFluidPort portA_vle(final vleFluidType= vleFluidType) "VLEFluid portA" annotation (Placement( transformation(extent={{-150,-10},{-130,10}}, rotation=0))); ThermalSystems.Connectors.GasPort portA_gas(final gasType=gasType) "Gas portA" annotation (Placement(transformation(extent={{-10,130}, {10,150}}, rotation=0))); ThermalSystems.Connectors.GasPort portB_gas(final gasType=gasType) "Gas portB" annotation (Placement(transformation(extent={{-10,-150}, {10,-130}}, rotation=0))); /****************** Splitter and joiner *******************/ parameter String splittingModeMoistAir = "fixed" "Mode of mass flow rate splitting" annotation(Dialog(group="Moist Air Cells", tab="Advanced"), choices( choice="fixed" "fixed ratio based on geometry", choice="momentum balance" "dynamic ratio based on momentum balance")); protected SplitterJoiner.GasSplitterJoiner gasSplitterJoiner( final nPorts1 = nCells, final nPorts2 = 1, final gasType=gasType, final cellFlowType=moistAirCellFlowType, final useFalseDynamics=useFalseDynamicsMoistAir, final falseDynamicsTimeConstant=falseDynamicsTimeConstantMoistAir, final pressureDropInitial=pressureDropInitialMoistAir, final fixedPressureDropInitial=fixedPressureDropInitialMoistAir, final splittingMode=splittingModeMoistAir) annotation (Placement(transformation(extent={{-26,-46},{26,-26}}))); /********* Summary ***************/ protected parameter Boolean includeSummaryArrays = true "Obsolete & unused parameter for array entries in summary" annotation(Dialog(tab="Advanced", group="Summary")); protected MediaConfiguration.Media.Gas_ph[nCells] moistAir_outflow( final p = {if ((moistAirCellFlowType == "flow A-B") or ((moistAirCellFlowType <> "flow B-A") and noEvent(moistAirCell[i].moistAirPortA.m_flow >= 0))) then moistAirCell[i].moistAirPortB.p else moistAirCell[i].moistAirPortA.p for i in 1:nCells}, final h = {if ((moistAirCellFlowType == "flow A-B") or ((moistAirCellFlowType <> "flow B-A") and noEvent(moistAirCell[i].moistAirPortA.m_flow >= 0))) then moistAirCell[i].moistAirPortB.h_outflow else moistAirCell[i].moistAirPortA.h_outflow for i in 1:nCells}, final xi = {if ((moistAirCellFlowType == "flow A-B") or ((moistAirCellFlowType <> "flow B-A") and noEvent(moistAirCell[i].moistAirPortA.m_flow >= 0))) then moistAirCell[i].moistAirPortB.xi_outflow else moistAirCell[i].moistAirPortA.xi_outflow for i in 1:nCells}, each final gasType=gasType, each computeTransportProperties=false) if includeSummary annotation (Placement(transformation(extent={{-50,-100},{-30,-80}},rotation= 0))); equation // Connect wall and vleFluid cells with eachother for i in 1:nCells-1 loop connect(vleFluidCell[i].portB, vleFluidCell[i+1].portA); if connectWallCells then connect(moistAirCell[i].wallHeatPortE, moistAirCell[i+1].wallHeatPortW); end if; end for; connect(vleFluidCell[nCells].portB, portB_vle) annotation (Line( points={{10,30},{100,30},{100,0},{140,0}}, color={153,204,0}, thickness=0.5)); connect(portA_vle, vleFluidCell[1].portA) annotation (Line( points={{-140,0},{-100,0},{-100,30},{-10,30}}, color={153,204,0}, thickness=0.5)); connect(vleFluidCell.heatPort, moistAirCell.wallHeatPortN) annotation (Line( points={{0,20},{0,-20}}, color={204,0,0}, pattern=LinePattern.Solid, thickness=0.5)); connect(gasSplitterJoiner.outlet, portB_gas) annotation (Line( points={{26,-36},{40,-36},{40,-100},{0,-100},{0,-140}}, color={255,153,0}, thickness=0.5, smooth=Smooth.None)); connect(gasSplitterJoiner.inlet, portA_gas) annotation (Line( points={{-26,-36},{-40,-36},{-40,100},{0,100},{0,140}}, color={255,153,0}, thickness=0.5, smooth=Smooth.None)); connect(gasSplitterJoiner.outlets[:, 1], moistAirCell.moistAirPortA) annotation (Line( points={{-14,-36},{-10,-36}}, color={255,153,0}, thickness=0.5, smooth=Smooth.None)); connect(gasSplitterJoiner.inlets[:, 1], moistAirCell.moistAirPortB) annotation (Line( points={{14,-36},{10,-36}}, color={255,153,0}, thickness=0.5, smooth=Smooth.None)); annotation(Documentation(info="<html>

-Back to Overview.


Model overview
VLE fluid
mass balance:transient (default) or steady state
energy balance:transient
differential states:h, xi, alphaAState, pressureDropState (default) or derivative of pressure in the PressureStateElement
momentum equation:pressure drop or isobaric

Warning

warning_h_limit

Indicates that the specific enthalpy at the outlet of at least one VLEFLuidCell is limited .

For further information you can check the variable warning_h_limit and the User's Guide Warnings section.

Wall
energy balance:transient
differential states:-
Moist air
mass balance:transient
energy balance:transient
differential states:H_WallPlusFilm, massFilm, pressureDropState
momentum equation:pressure drop or isobaric
</html>"), Diagram(coordinateSystem( preserveAspectRatio=true, extent={{-140,-140},{140,140}}, initialScale=0.1)), Icon(coordinateSystem( preserveAspectRatio=false, extent={{-140,-140},{140,140}}, initialScale=0.1), graphics={ Bitmap(extent={{-140,-140},{140,140}}, imageSource= "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HS7eGJsTG9WNyUJI7Rhkq2tL6WePPPNgmz6SO+5q3OHSsnhsVHFZPL1ubNFkYbEhF33XeQ/sXh77o39yWGxIDfrUq3Qz53aZu8pig5CGST+QKP3k/npXruoPqe+RJ93Mrv7fmYTUkCHvIZv6a0BnFdKWfq+ybW6y6ERIrpE2EQPo2X0r6fteek8W1VtRg2JD+r6959/NXFGRxYZaBtmOrY+9+Mhax1auYnNio4orlh2bLISU1yCbykf/5Kn4gUSdnCxqPM1zjVTdjb+uXbh6stH/9UNT10gl568s79uxZJnbYkNXzCgkLDaAayQQEggJEBIICYQECAmEBEICIQFCAiGBkEBIgJBASCAkEBIgJBASCAmEBAgJhARCAiEBQgIhgZBASICQQEggJEBIICQQEggJEBIICYQEQgKEBEICIYGQACGBkEBIICRASCAkEBIICRASCAmEBEIChARCAiEBQgIhgZBASICQQEggJBASICQQEggJhAQICYQEQgIhAUICIYGQQEiAkEBIICRASCAkEBIICRASCAmEBEIChARCAiGBkAAhgZBASCAkQEggJBASCAkQEggJhARCAoQEQgIhAUICIYGQQEgAAAAAA/wjwAAuFnEcIolTZQAAAABJRU5ErkJggg==", fileName="modelica://ThermalSystems/Resources/Images/CrossFlowHX_VLEGas.png"), Text( extent={{-46,110},{194,70}}, lineColor={153,204,0}, textString= "(%pressureStateID)"), Text( extent={{-140,0},{-100,-40}}, lineColor={0,0,0}, textString= "1"), Text( extent={{100,0},{140,-40}}, lineColor={0,0,0}, textString= "n"), Text( extent={{-132,130},{-92,90}}, lineColor={0,0,0}, textString= "A"), Text( extent={{92,-92},{132,-132}}, lineColor={0,0,0}, textString= "B"), Bitmap( extent=DynamicSelect({{0,0},{0,0}}, if visualizeWarnings and warning_h_limit > 0.5 then {{-140,148},{-103.05,180}} else {{0,0},{0,0}}), fileName="modelica://ThermalSystems/Resources/Images/Warning.png")})); end CrossFlowHX; 换热器模型代码如上

filetype

## Dymola中计算Fan2ndOrder ## 选取额定工况为1600转 import copy import pandas as pd import numpy as np from scipy.optimize import curve_fit as cf from matplotlib import pyplot as plt ## 将不同转速下的流量-功率曲线和流量-静压曲线拟合成三次型函数 ## 系统的静压曲线使用指数型关系式代替 ALPHA = 0.2 BETA = 0.5 class FanCurve: def __init__(self): self.curve_power = { 1280: [np.float64(-1.0939824906995037e-09), np.float64(2.333022185311005e-05), np.float64(-0.06796629659302983), np.float64(2055.3002100486133)], 1440: [np.float64(-1.136696332147217e-09), np.float64(2.7660598448342913e-05), np.float64(-0.09613228325870021), np.float64(2922.59538328202)], 1500: [np.float64(-1.7603856529124879e-09), np.float64(4.4241229797522305e-05), np.float64(-0.14983705834350444), np.float64(5160.7745241685625)], 1600: [np.float64(-1.1701720186561717e-09), np.float64(3.0605089172086764e-05), np.float64(-0.0989935007927685), np.float64(3869.5082357198503)] } self.curve_dp = { 1280: [np.float64(-3.267975749307142e-10), np.float64(5.2912277771354885e-06), np.float64(-0.03403187464621037), np.float64(741.9041721827268)], 1440: [np.float64(-2.422194407553435e-10), np.float64(3.7698924924279502e-06), np.float64(-0.02559742162953265), np.float64(931.5430549263344)], 1500: [np.float64(-2.3878745827961e-10), np.float64(3.921270379695461e-06), np.float64(-0.02640953385995719), np.float64(1002.1261618905066)], 1600: [np.float64(-2.2348965671136672e-10), np.float64(3.886724444389961e-06), np.float64(-0.027754898177200903), np.float64(1147.392301537067)] } self.speed = [1280, 1440, 1500, 1600] # 有顺序的 不要改 self.alpha = ALPHA self.beta = BETA self.q_min = 0 self.q_max = 24000 def pressure_q(self, q): return self.alpha * q ** self.beta @staticmethod def curve_function(q, a, b, c, d): return a * q **3 + b * q **2 + c * q + d @staticmethod def mk_function(a, b, c, d): # 此函数适用于不插值的计算 def curve_function(q): return a * q ** 3 + b * q ** 2 + c * q + d return curve_function @staticmethod def mk_inter_function(percent, a, b, c, d, e, f, g, h): ## 如果使用插值,就用这个方法构造函数 ## abcd是左侧值的参数,efgh是右侧的 def inter_curve_function(q): l_value = a * q ** 3 + b * q ** 2 + c * q + d r_value = e * q ** 3 + f * q ** 2 + g * q + h return (1 - percent) * l_value + percent * r_value return inter_curve_function @staticmethod def mk_outside_function(coefficient, a, b, c, d): def curve_function(q): return (a * q ** 3 + b * q ** 2 + c * q + d) * coefficient return curve_function def get_functions(self, n): """ 使用转速和系统的阻力特性计算体积流量 转速在性能曲线范围内的采用插值处理 转速在性能曲线外的采用风机相似定律 :param n: :return: """ if 1280 <= n <= 1600: ## 插值得出风机的静压,电功率 if n in self.speed: ## 给定的转速在风机性能曲线内,不需要插值 power_params = self.curve_power[n] power_function = self.mk_function(*power_params) dp_params = self.curve_dp[n] dp_function = self.mk_function(*dp_params) else: ## 给定的转速不在风机性能曲线上,则需要进行插值 new_speed = copy.deepcopy(self.speed) new_speed.append(n) new_speed.sort() idx = 0 for i in range(len(new_speed)): if n == new_speed[i]: idx = i break l_speed = new_speed[idx - 1] r_speed = new_speed[idx + 1] l_power_params = self.curve_power[l_speed] r_power_params = self.curve_power[r_speed] l_dp_params = self.curve_dp[l_speed] r_dp_params = self.curve_dp[r_speed] percent = (n - l_speed) / (r_speed - l_speed) power_function = self.mk_inter_function(percent, *l_power_params, *r_power_params) dp_function = self.mk_inter_function(percent, *l_dp_params, *r_dp_params) else: ## 使用风机相似定律求出风机电功率、静压 if n < 1280: volume_coefficient = n / 1280 else: volume_coefficient = n / 1600 pressure_coefficient = volume_coefficient ** 2 power_coefficient = volume_coefficient ** 3 dp_params = self.curve_dp[1280] power_params = self.curve_power[1280] dp_function = self.mk_outside_function(pressure_coefficient, *dp_params) power_function = self.mk_outside_function(power_coefficient, *power_params) return {"dp_function": dp_function, "power_function": power_function} def solve(self, f, g, q_init=10000, convergence = 1e-06, max_iter = 10000): ## 暂时不对无解情况进行规避 count = 0 def difference(q): return f(q) - g(q) l, r = self.q_min, self.q_max if difference(self.q_min) == 0: return self.q_min if difference(self.q_max) == 0: return self.q_max while True: if difference(l) * difference(r) > 0: raise ValueError("使用二分法时,似乎存在多解,无法求得确切值") if 0 < difference(q_init) <= convergence: break if difference(q_init) * difference(l) > 0: ## 跟左边的值同号 l = q_init q_init = (l + r) / 2 else: r = q_init q_init = (l + r) / 2 count += 1 if count > max_iter: raise TimeoutError("迭代次数已经超过了最大迭代次数") return q_init def run(self, n): functions = self.get_functions(n) q = self.solve(functions["dp_function"], self.pressure_q) return q if __name__ == '__main__': # ## 读取数据 # dataframe_dp = pd.read_excel(r"E:\projects\air_conditioner\fan\v_dp_1600.xlsx") # # # dataframe_power = pd.read_excel(r"E:\projects\air_conditioner\fan\power_1600.xlsx") # # ## 拟合 # # def f_power(x, a, b, c, d): # return a * x **3 + b * x **2 + c * x + d # # # for file_name in ["power_1280", "power_1440", "power_1500", "power_1600"]: # file_path = fr"E:\projects\air_conditioner\fan\{file_name}.xlsx" # dataframe_power = pd.read_excel(file_path) # # x_data = np.array(dataframe_power['x']) # y_data = np.array(dataframe_power['y']) # # a, b, c, d = cf(f_power, x_data, y_data)[0] # xx = [a, b, c, d] # print(file_name, f"x={xx}") n_set = 1400 solution = FanCurve() q = solution.run(n_set) p = solution.pressure_q(q) functions = solution.get_functions(n_set) print("性能曲线压力:", functions["dp_function"](q)) print(q) print("阻力压力:", p) 这段代码是如何生成风机性能曲线表达式的

Mr抱抱你
  • 粉丝: 0
上传资源 快速赚钱