NREL / EnergyPlus

EnergyPlus™ is a whole building energy simulation program that engineers, architects, and researchers use to model both energy consumption and water use in buildings.
https://energyplus.net
Other
1.13k stars 389 forks source link

Error with Zone Air Contaminant Balance #10348

Closed tpistochini closed 4 months ago

tpistochini commented 10 months ago

OS Name Microsoft Windows 11 Enterprise Version 10.0.22000 Build 22000

EnergyPlus version 9.4, but have also tested version 23.1 and encountered the same problem.

https://unmethours.com/question/97822/co2-calculated-incorrectly-zone-air-contaminant-balance/

I am running a single-zone simulation with fixed rate ventilation and a fixed number of people during occupied hours. Outdoor CO2 concentration fixed at 425 ppm always. I am running the same simulation with 70 files of historical weather produced by whitebox technologies. For a portion of the files (approximately 20) on just a few of the days of the simulation, the zone air contaminant balance calculates zone indoor CO2 incorrectly. As an example, I am attaching one weather file. The days that are incorrect are Oct 12, 13 and Dec 13. If I take Oct 11 from the weather file and replace into Oct 12 and 13 and Dec 12 and replace it into Dec 13 with no changes to the IDF the error resolves.

Accurate calculation of the zone air contaminant balance is critical to my project need, so I am at a loss. I could potentially manually update all my weather files to remove the offending days, but I am very concerned with proceeding when I don't understand the root of the error. Additionally, I am unclear how outdoor air conditions impact the zone air contaminant balance calculation, so I'm not sure how to isolate the problem.

I have categorized all the problematic days from all the weather files and looked in detail at the weather, and I see no problems. Neither does Joe Huang @ Whitebox. The weather fields all appear to make sense (and, for example, Oct 12 and 13 are very similar to Oct 11). Example IDF and weather.zip

lgu1234 commented 8 months ago

@tpistochini After downloading the zip file, I am unable to find any idf files. The zipped file contains two epw files, one csv file, one eio file and one xlsx file. Please upload the idf file for verification.

tpistochini commented 8 months ago

@lgu1234 I apologize I uploaded the EIO instead of the IDF. I've attached the IDF here. run12.zip

lgu1234 commented 7 months ago

@tpistochini I debugged the code and found no errors with zone CO2 balance. The difference is caused by zone air density due to different zone air temperature and humidity.

The CO2 internal gain is based on number of people , CO2 generation rate and zone air density. When different weather file is used, different zone air temperatures and humidity ratios are expected.

Here is code extracted from CorrectZoneContaminants in EnergyPlus::ZoneContaminantPredictorCorrector

    Real64 RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisZoneHB.ZT, thisZoneHB.airHumRat, RoutineName);

    if (state.dataContaminantBalance->Contaminant.CO2Simulation) state.dataContaminantBalance->ZoneAirDensityCO(ZoneNum) = RhoAir;
    // Calculate Co2 internal gain
    if (state.dataContaminantBalance->Contaminant.CO2Simulation) CO2Gain = state.dataContaminantBalance->ZoneCO2Gain(ZoneNum) * RhoAir * 1.0e6;

Hope this helps.

tpistochini commented 7 months ago

@lgu1234 thank you for looking into it. I am running a set of 70 simulations using historical weather. A large fraction (~30%) of them run into this problem with the CO2 calculation. I am reporting CO2 statistics for four different control strategies (so 280 simulations), therefore it's a headache to figure out how to deal with these CO2 calculations that are obviously not correct for this particular set of weather files. I also agree the simulation works when changing the weather file. I do not see any anomaly with the weather files that explains what causes this calculation to result in this error. I just gave you one file as an example, but it is not the only one with problems. It's hard to figure out how to correct the weather files when I don't understand what is causing the problem. To clarify - I need to use historical weather and not TMY weather because I am also simulating historical air quality in a parallel air quality simulation.

tpistochini commented 6 months ago

@lgu1234 Checking in one more time to see if you can explain this further. I ran 70 simulations with different weather files and I output zone air density for each simulation. The differences in zone air density (~2%) do not explain the spikes in CO2 (which are sometimes as high as 20%). In this simulation the CO2 should not exceed ~1330 ppm, even with small variations in zone air density. Over the last few months I have shown this to several EnergyPlus users and we are all scratching our heads. I also observed when you change the timestep for the simulation it predicts different CO2 concentrations in the zone during these specific times, which is further evidence there is something amiss here. My project is completely stalled and I have spent days of time attempting to solve this problem. Any more insight you can provide would be greatly appreciated.

lgu1234 commented 6 months ago

@tpistochini Sorry to know your project is stalled. I checked this issue before and was unable to find what is wrong. I am on vacation and will contact you to work together to solve this issue after I come back.

mjwitte commented 6 months ago

@lgu1234 @tpistochini I've been looking at this, and it appears to be an issue with the HVAC system iteration updates. Reporting "System Node CO2 Concentration" shows that the CO2 (and temperature and other properties) do not match for the inlet and outlet nodes of the ZoneHVAC:Splitter. This should trigger another airloop iteration to align the properties, but for some reason it is not updating for certain conditions. In this case, it is happening for about 60 HVAC timesteps of the year. The rest of the simulation matches up exactly.

For this idf and epw file, there is a workaround that eliminates the mismatched node conditions. The flow rates for the HVAC system components are all hardsized to 0.28316846636 {m3/s} except the air terminal unit:

  AirTerminal:SingleDuct:ConstantVolume:NoReheat,
    Air Terminal Single Duct Uncontrolled 1,  !- Name
    ,                        !- Availability Schedule Name
    Zone1 Inlet Air Node ATInlet,  !- Air Inlet Node Name
    Zone1 Inlet Air Node,    !- Air Outlet Node Name
    2;                       !- Maximum Air Flow Rate {m3/s}

Changing the Maximum Air Flow Rate here from 2 to 0.28316846636 eliminates the mismatch. Perhaps aligning the terminal unit flow rate with the rest of the system will solve the problem for the entire suite.

mjwitte commented 6 months ago

@rraustad This is probably happening because of the way that flow rates are set to maximum when FirstHVACIteration is true. It shouldn't be a problem that the terminal unit flow rate is > than the rest of the system, but somewhere along the way, and only under certain conditions, the SimZoneEquipmentFlag flag isn't getting set to trigger another round. Note that changing state.dataHVACGlobal->MinAirLoopIterationsAfterFirst from 1 to 2 eliminates the problem, but that's not the best solution.

rraustad commented 6 months ago

If convergence is based on T, w, H, mass flow rate, energy and pressure then maybe adding CO2 when used would force that extra iteration when necessary? @mjwitte did you find that these values were within tolerance when CO2 did not match?

constexpr Real64 HVACEnthalpyToler(260.0);                  // Tolerance for enthalpy comparisons (in kJ/kgK)
constexpr Real64 HVACFlowRateToler(0.01);                   // Tolerance for mass flow rate convergence (in kg/s) [~20 CFM]
constexpr Real64 HVACHumRatToler(0.0001);                   // Tolerance for humidity ratio comparisons (kg water/kg dryair)
constexpr Real64 HVACPressToler(10.0);                      // Tolerance for pressure comparisons (in Pascals)
constexpr Real64 HVACTemperatureToler(0.01);                // Tolerance for temperature comparisons (in degrees C or K)
constexpr Real64 HVACEnergyToler(10.0);                     // Tolerance for Energy comparisons (in Watts W)
mjwitte commented 6 months ago

@rraustad Yes, that's it. Temperature was within tolerance and adding a CO2 check solves the issue. So, what do you think is a good tolerance for CO2?

rraustad commented 6 months ago

Given the magnitude of CO2 I would think the tolerance would be similar to the pressure tolerance. So 10. How different was CO2 in this defect file? I would also like to know why changing MinAirLoopIterationsAfterFirst to 2 solved this. That tells me that the HVAC system was either off or operated identical to the FirstHVACIteration result (which we know should not happen since TUs fire off max mass flow on FirstHVACIteration). If the HVAC is off, or all TUs are operating at max flow, why would CO2 change on the 2nd iteration? I still don't understand why the CO2 value did not propagate correctly at the interface nodes but adding a CO2 tolerance for CO2 simulations seems somewhat appropriate.

mjwitte commented 6 months ago

For the defect file, the deltaCO2 was on the order of 300ppm. This is a unitary system with a constant flow rate, so here's what I think happened:

  1. On FirstHVACIteration:
    • the TU runs at max (2.0) which results in a return air flow rate of 2.0, so the OA controller runs with a mixed air flow rate of 2.0.
    • Then the branch simulates and the unitary system runs at 0.283 and controls the supply temp to meet the zone load at 0.283.
    • This propogates over to the zone equipment side with 0.283, high CO2, and a supply temp that meets the load.
  2. On second iteration:
    • the flow from the zone is now 0.283, so when the zone equip side calls UpdateHVACInterface with DataConvergParams::CalledFrom::AirSystemDemandSide, it senses the change and sets SimAir to true
    • when SimAirLoops calls UpdateHVACInterface with DataConvergParams::CalledFrom::AirSystemSupplySideDeck1 there is little or no change in the supply temp, humrat, and massflowrate, because the unitarysystem is controlling on load, same as in the first iteration, temp and humrat are converged and SimZoneEquipment is not set to trigger another zone equipment simulation.

So that's how CO2 could change by a lot without any of the other conditions changing at the supply side/demand side interface.

Adding a CO2 (and generic contaminant) check will fix this case, but I wonder if the zone equipment should always be simulated anytime that SimAir is tripped?

rraustad commented 6 months ago

So without zone equipment simulating again after the air loop on the 2nd iteration, the CO2 value at the system level did not propagate back to the zone demand side interface outlet node. I can see that happening. I think I would go with the CO2 tolerance since it would be better to have that check happen each iteration than the entire zone equipment simulation, and only simulate again if 1 of the now 8 tolerances are out of bounds. The tolerances cover most of the NodeData variables now. I think leaving out Node().CO2 was just an oversight.

tpistochini commented 6 months ago

@mjwitte @rraustad - thank you for all the help. I fixed the AirTerminal:SingleDuct:ConstantVolume:NoReheat, maximum flow to match the other HVAC system components (I did not realize I missed this one). Once I did this, all the simulations run with the CO2 calculated as expected. I like the idea to add a tolerance for CO2 and for the generic contaminant controller. But I am good now! I will mark this closed (yay)!

tpistochini commented 6 months ago

Issue resolved per comment above.

mjwitte commented 6 months ago

Reopening this issue until the convergence checks for CO2 and generic contaminant are added.

lgu1234 commented 5 months ago

@mjwitte I plan to add the convergence checks for CO2 and generic contaminant first. Are you OK for me to do it?

mjwitte commented 5 months ago

@mjwitte I plan to add the convergence checks for CO2 and generic contaminant first. Are you OK for me to do it?

@lgu1234 Yes, go ahead.