Fix segfault with ZoneControl:ContaminantController - #11709
Fix segfault with ZoneControl:ContaminantController#11709joseph-robertson wants to merge 4 commits into
Conversation
| state.dataContaminantBalance->ZoneCO2SetPoint(ZoneNum) = | ||
| state.dataContaminantBalance->ContaminantControlledZone(Loop).setptSched->getCurrentVal(); | ||
| if (state.dataContaminantBalance->ContaminantControlledZone(Loop).setptSched == nullptr) { | ||
| state.dataContaminantBalance->ZoneCO2SetPoint(ZoneNum) = 0.0; |
There was a problem hiding this comment.
I think this maintains previous behavior (e.g., v24.2 initialized SPSchedIndex to zero) before use of getCurrentVal(). I suppose the alternative to this fix is to fatal and require that the schedule be populated?
| \paragraph{Field:Carbon Dioxide Setpoint Schedule Name}\label{fieldcarbon-dioxide-setpoint-schedule-name} | ||
|
|
||
| This field contains the name of a schedule that contains the zone carbon dioxide concentration setpoint as a function of time. The units for carbon dioxide setpoint are ppm. The setpoint values in the schedule must be between 0 and 2000 ppm. . This field is used when the field System Outdoor Air Method = IndoorAirQualityProcedure in the \hyperref[controllermechanicalventilation]{Controller:MechanicalVentilation} object. | ||
| This field contains the name of a schedule that contains the zone carbon dioxide concentration setpoint as a function of time. The units for carbon dioxide setpoint are ppm. The setpoint values in the schedule must be between 0 and 2000 ppm. This field is used when the field System Outdoor Air Method = IndoorAirQualityProcedure in the \hyperref[controllermechanicalventilation]{Controller:MechanicalVentilation} object. |
There was a problem hiding this comment.
Should description for Carbon Dioxide Setpoint Schedule Name (and Generic Contaminant Setpoint Schedule Name) be updated to include language about being used when field Carbon Dioxide Concentration (and Generic Contaminant Concentration) is Yes on the ZoneAirContaminantBalance object?
There was a problem hiding this comment.
Pull request overview
This PR addresses a crash in the zone contaminant control initialization path by guarding access to optional contaminant setpoint schedules, and updates the Input Output Reference text to better describe when those schedules are used.
Changes:
- Add nullptr checks before dereferencing CO₂ and generic contaminant setpoint schedule pointers in
InitZoneContSetPoints. - Default the zone setpoint value when a schedule pointer is missing to avoid a segfault.
- Update IO Reference text to clarify the contexts in which the setpoint schedule fields are used.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/EnergyPlus/ZoneContaminantPredictorCorrector.cc | Adds null-guarding around contaminant setpoint schedule dereferences to prevent segfaults. |
| doc/input-output-reference/src/overview/group-zone-controls-thermostats.tex | Clarifies documentation around CO₂/GC setpoint schedule field usage conditions. |
Suppressed comments (2)
src/EnergyPlus/ZoneContaminantPredictorCorrector.cc:1445
- When the generic contaminant setpoint schedule pointer is null, the fallback setpoint of 0.0 can unintentionally trigger any logic that treats ZoneAirGC > ZoneGCSetPoint as a control threshold (similar to the CO2 case), leading to non-obvious behavior changes. Consider using a large sentinel (Constant::BigNumber) to effectively disable the threshold when the schedule is absent, or report a clear input error.
if (state.dataContaminantBalance->ContaminantControlledZone(Loop).genericContamSetptSched == nullptr) {
state.dataContaminantBalance->ZoneGCSetPoint(ZoneNum) = 0.0;
} else {
state.dataContaminantBalance->ZoneGCSetPoint(ZoneNum) =
state.dataContaminantBalance->ContaminantControlledZone(Loop).genericContamSetptSched->getCurrentVal();
src/EnergyPlus/ZoneContaminantPredictorCorrector.cc:1432
- The new nullptr handling for contaminant setpoint schedules fixes a crash-prone path, but there is no unit test exercising the missing-schedule case to prevent regressions. Consider adding a test in tst/EnergyPlus/unit/ZoneContaminantPredictorCorrector.unit.cc that sets CO2Simulation/GenericContamSimulation true with a controlled zone whose setpoint schedule pointers are null, and verifies InitZoneContSetPoints completes without crashing and produces the expected fallback behavior.
if (state.dataContaminantBalance->ContaminantControlledZone(Loop).setptSched == nullptr) {
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (state.dataContaminantBalance->ContaminantControlledZone(Loop).setptSched == nullptr) { | ||
| state.dataContaminantBalance->ZoneCO2SetPoint(ZoneNum) = 0.0; | ||
| } else { | ||
| state.dataContaminantBalance->ZoneCO2SetPoint(ZoneNum) = | ||
| state.dataContaminantBalance->ContaminantControlledZone(Loop).setptSched->getCurrentVal(); | ||
| } |
There was a problem hiding this comment.
Hm I'm not really sure about this one. Is this not a deviation from previous (before the getCurrentVal() change) behavior?
| \paragraph{Field:Carbon Dioxide Setpoint Schedule Name}\label{fieldcarbon-dioxide-setpoint-schedule-name} | ||
|
|
||
| This field contains the name of a schedule that contains the zone carbon dioxide concentration setpoint as a function of time. The units for carbon dioxide setpoint are ppm. The setpoint values in the schedule must be between 0 and 2000 ppm. . This field is used when the field System Outdoor Air Method = IndoorAirQualityProcedure in the \hyperref[controllermechanicalventilation]{Controller:MechanicalVentilation} object. | ||
| This field contains the name of a schedule that contains the zone carbon dioxide concentration setpoint as a function of time. The units for carbon dioxide setpoint are ppm. The setpoint values in the schedule must be between 0 and 2000 ppm. This field is used when the field System Outdoor Air Method = IndoorAirQualityProcedure in the \hyperref[controllermechanicalventilation]{Controller:MechanicalVentilation} object and the field Carbon Dioxide Concentration = Yes in the \hyperref[zoneaircontaminantbalance]{ZoneAirContaminantBalance} object. |
| \paragraph{Field: Generic Contaminant Setpoint Schedule Name}\label{field-generic-contaminant-setpoint-schedule-name} | ||
|
|
||
| This field contains the name of a schedule that contains the zone generic contaminant concentration setpoint as a function of time. The units for generic contaminant setpoint are ppm. The setpoint values in the schedule must be\textgreater{} = 0. | ||
| This field contains the name of a schedule that contains the zone generic contaminant concentration setpoint as a function of time. The units for generic contaminant setpoint are ppm. The setpoint values in the schedule must be \textgreater{}= 0. This field is used when the field Generic Contaminant Concentration = Yes in the \hyperref[zoneaircontaminantbalance]{ZoneAirContaminantBalance} object. |
Pull request overview
ZoneControl:ContaminantControllerobject, is accessed when field Carbon Dioxide Concentration (or Generic Contaminant Concentration) is Yes on theZoneAirContaminantBalanceobject. If setpoint schedule field not populated, a segfault occurs. (Found while investigating Pump:ConstantSpeed operating at less than full flow but consuming full power #10821.)Description of the purpose of this PR
Pull Request Author
Reviewer