Closed jmarrec closed 1 month ago
I'm guessing the issue might be VT, or maybe a backward-compatible setter. I can't reproduce with model
include OpenStudio::Model
m = Model.new
# Hx does not have curves assigned yet
hx = HeatExchangerAirToAirSensibleAndLatent.new(m)
puts hx
OS:HeatExchanger:AirToAir:SensibleAndLatent,
{8c6f9457-55f0-4773-9e9a-7a90368cdbd9}, !- Handle
Heat Exchanger Air To Air Sensible And Latent 2, !- Name
{ace21dbd-41a6-4465-b0d2-1e263620a860}, !- Availability Schedule
autosize, !- Nominal Supply Air Flow Rate {m3/s}
0.76, !- Sensible Effectiveness at 100% Heating Air Flow {dimensionless}
0.68, !- Latent Effectiveness at 100% Heating Air Flow {dimensionless}
0.76, !- Sensible Effectiveness at 100% Cooling Air Flow {dimensionless}
0.68, !- Latent Effectiveness at 100% Cooling Air Flow {dimensionless}
, !- Supply Air Inlet Node
, !- Supply Air Outlet Node
, !- Exhaust Air Inlet Node
, !- Exhaust Air Outlet Node
0, !- Nominal Electric Power {W}
Yes, !- Supply Air Outlet Temperature Control
Plate, !- Heat Exchanger Type
None, !- Frost Control Type
1.7, !- Threshold Temperature {C}
, !- Initial Defrost Time Fraction {dimensionless}
, !- Rate of Defrost Time Fraction Increase {1/K}
Yes, !- Economizer Lockout
, !- Sensible Effectiveness of Heating Air Flow Curve Name
, !- Latent Effectiveness of Heating Air Flow Curve Name
, !- Sensible Effectiveness of Cooling Air Flow Curve Name
; !- Latent Effectiveness of Cooling Air Flow Curve Name
hx.assignHistoricalEffectivenessCurves
m.getTableLookups.map{|t| [t.nameString, t.normalizationDivisor]}.to_h
=> {"Heat Exchanger Air To Air Sensible And Latent 1_LatCoolEff"=>0.68,
"Heat Exchanger Air To Air Sensible And Latent 1_SensCoolEff"=>0.76,
"Heat Exchanger Air To Air Sensible And Latent 1_LatHeatEff"=>0.68,
"Heat Exchanger Air To Air Sensible And Latent 1_SensHeatEff"=>0.76}
Can't do it either with the backward-compatible setters...
m = Model.new
hx = HeatExchangerAirToAirSensibleAndLatent.new(m)
hx.setSensibleEffectivenessat75HeatingAirFlow(0.68)
hx.setLatentEffectivenessat75HeatingAirFlow(0.68)
hx.setSensibleEffectivenessat75CoolingAirFlow(0.68)
hx.setLatentEffectivenessat75CoolingAirFlow(0.68)
m.getTableLookups.map{|t| [t.nameString, t.normalizationDivisor]}.to_h
=> {"Heat Exchanger Air To Air Sensible And Latent 1_LatCoolEff"=>0.68,
"Heat Exchanger Air To Air Sensible And Latent 1_SensCoolEff"=>0.76,
"Heat Exchanger Air To Air Sensible And Latent 1_LatHeatEff"=>0.68,
"Heat Exchanger Air To Air Sensible And Latent 1_SensHeatEff"=>0.76}
Can't reproduce either via VT.
/usr/local/openstudio-3.7.0/bin/openstudio -e "m = OpenStudio::Model::Model.new; hx = OpenStudio::Model::HeatExchangerAirToAirSensibleAndLatent.new(m); m.save('test.osm')"
[1] test(main)> OpenStudio.openStudioLongVersion
=> "3.8.0-beta+d2f0bdd21a"
[2] test(main)> m = osload('test.osm')
=> #<OpenStudio::Model::Model:0x00007f15f8477b00 @__swigtype__="_p_openstudio__model__Model">
[3] test(main)> m.getTableLookups.map{|t| [t.nameString, t.normalizationDivisor]}.to_h
=> {"Heat Exchanger Air To Air Sensible And Latent 1_LatCoolEff"=>0.68,
"Heat Exchanger Air To Air Sensible And Latent 1_LatHeatEff"=>0.68,
"Heat Exchanger Air To Air Sensible And Latent 1_SensCoolEff"=>0.76,
"Heat Exchanger Air To Air Sensible And Latent 1_SensHeatEff"=>0.76}
Apparently it's going to be fixed on openstudio-standards.
Reopening this issue, because it is still possible to cause a divide by zero error in a common use case of the air to air HX:
model = OpenStudio::Model::Model.new
heat_exchanger = OpenStudio::Model::HeatExchangerAirToAirSensibleAndLatent.new(model)
heat_exchanger.setLatentEffectivenessat100HeatingAirFlow(0.0)
heat_exchanger.setLatentEffectivenessat75HeatingAirFlow(0.0)
heat_exchanger.setLatentEffectivenessat100CoolingAirFlow(0.0)
heat_exchanger.setLatentEffectivenessat75CoolingAirFlow(0.0)
model.save('hx_out.osm', true)
creates a model with a Table with a 0 normalization divisor:
OS:HeatExchanger:AirToAir:SensibleAndLatent,
{5e0c8290-c998-417e-871a-5e1d81fdebca}, !- Handle
Heat Exchanger Air To Air Sensible And Latent 1, !- Name
{75a43233-8ab7-4b33-9d8e-e1ce660b3080}, !- Availability Schedule
autosize, !- Nominal Supply Air Flow Rate {m3/s}
0.76, !- Sensible Effectiveness at 100% Heating Air Flow {dimensionless}
0, !- Latent Effectiveness at 100% Heating Air Flow {dimensionless}
0.76, !- Sensible Effectiveness at 100% Cooling Air Flow {dimensionless}
0, !- Latent Effectiveness at 100% Cooling Air Flow {dimensionless}
, !- Supply Air Inlet Node
, !- Supply Air Outlet Node
, !- Exhaust Air Inlet Node
, !- Exhaust Air Outlet Node
0, !- Nominal Electric Power {W}
Yes, !- Supply Air Outlet Temperature Control
Plate, !- Heat Exchanger Type
None, !- Frost Control Type
1.7, !- Threshold Temperature {C}
, !- Initial Defrost Time Fraction {dimensionless}
, !- Rate of Defrost Time Fraction Increase {1/K}
Yes, !- Economizer Lockout
, !- Sensible Effectiveness of Heating Air Flow Curve Name
{961209b4-3204-4900-a992-c77738ff3203}, !- Latent Effectiveness of Heating Air Flow Curve Name
, !- Sensible Effectiveness of Cooling Air Flow Curve Name
{ac21cf30-8b67-45c9-bac1-f7bee22148a3}; !- Latent Effectiveness of Cooling Air Flow Curve Name
OS:Table:Lookup,
{ac21cf30-8b67-45c9-bac1-f7bee22148a3}, !- Handle
Heat Exchanger Air To Air Sensible And Latent 1_LatCoolEff, !- Name
{ec872863-15b9-4ae8-b55a-3854b2709453}, !- Independent Variable List Name
DivisorOnly, !- Normalization Method
0, !- Normalization Divisor
0, !- Minimum Output {BasedOnField A5}
10, !- Maximum Output {BasedOnField A5}
Dimensionless, !- Output Unit Type
, !- External File Name
, !- External File Column Number
, !- External File Starting Row Number
0, !- Output Value 1 {BasedOnField A5}
0; !- Output Value 2 {BasedOnField A5}
A proposed solution is to check if the effectiveness is zero, and don't create the air flow curve if so.
t = TableLookup.new(m)
t.setNormalizationDivisor(0)
=> true
puts t
OS:Table:Lookup,
{d7e6d211-cf84-4977-a37e-09c35bd1128a}, !- Handle
Table Lookup 1, !- Name
{d1a909ea-8356-411e-868f-c8f5962c4f51}, !- Independent Variable List Name
None, !- Normalization Method
0, !- Normalization Divisor
, !- Minimum Output {BasedOnField A5}
, !- Maximum Output {BasedOnField A5}
Dimensionless; !- Output Unit Type
OS:Table:Lookup,
{d7e6d211-cf84-4977-a37e-09c35bd1128a}, !- Handle
Table Lookup 1, !- Name
{d1a909ea-8356-411e-868f-c8f5962c4f51}, !- Independent Variable List Name
None, !- Normalization Method
0, !- Normalization Divisor
, !- Minimum Output {BasedOnField A5}
, !- Maximum Output {BasedOnField A5}
Dimensionless; !- Output Unit Type
OS:Table:Lookup,
{d7e6d211-cf84-4977-a37e-09c35bd1128a}, !- Handle
Table Lookup 1, !- Name
{d1a909ea-8356-411e-868f-c8f5962c4f51}, !- Independent Variable List Name
None, !- Normalization Method
0, !- Normalization Divisor
, !- Minimum Output {BasedOnField A5}
, !- Maximum Output {BasedOnField A5}
Dimensionless; !- Output Unit Type
The problem is what we copied the E+ idd blindly, and it does not have any constraints on the value it accepts at all.
I will reject 0.
Issue overview
@mdahlhausen reported an issue where the Normalization Divisor is zero at https://github.com/NREL/OpenStudio/pull/5099#issuecomment-2050633394
Need to determine what's causing this and ensure it doesn't happen.
Current Behavior
Expected Behavior
Steps to Reproduce
@mdahlhausen can you please help here?
1. 2. 3. 4.
Possible Solution
Details
Environment
Some additional details about your environment for this issue (if relevant):
Context