Skip to content

Conversation

@kevin-moos
Copy link
Contributor

@kevin-moos kevin-moos commented Nov 21, 2025

Pull request overview

Description of the purpose of this PR

I was able to recreate this in unit tests for DX coils and variable speed DX coils using values from the original defect file. It looks like PartLoadFrac already defaults to 0 so I just added some divide by zero checks.

Pull Request Author

  • Title of PR should be user-synopsis style (clearly understandable in a standalone changelog context)
  • Label the PR with at least one of: Defect, Refactoring, NewFeature, Performance, and/or DoNoPublish
  • Pull requests that impact EnergyPlus code must also include unit tests to cover enhancement or defect repair
  • Author should provide a "walkthrough" of relevant code changes using a GitHub code review comment process
  • If any diffs are expected, author must demonstrate they are justified using plots and descriptions
  • If changes fix a defect, the fix should be demonstrated in plots and descriptions
  • If any defect files are updated to a more recent version, upload new versions here or on DevSupport
  • If IDD requires transition, transition source, rules, ExpandObjects, and IDFs must be updated, and add IDDChange label
  • If structural output changes, add to output rules file and add OutputChange label
  • If adding/removing any LaTeX docs or figures, update that document's CMakeLists file dependencies
  • If adding/removing any output files (e.g., eplustbl.*)
    • Update ..\scripts\Epl-run.bat
    • Update ..\scripts\RunEPlus.bat
    • Update ..\src\EPLaunch\ MainModule.bas, epl-ui.frm, and epl.vbp (VersionComments)
    • Update ...github\workflows\energyplus.py

Reviewer

  • Perform a Code Review on GitHub
  • If branch is behind develop, merge develop and build locally to check for side effects of the merge
  • If defect, verify by running develop branch and reproducing defect, then running PR and reproducing fix
  • If feature, test running new feature, try creative ways to break it
  • CI status: all green or justified
  • Check that performance is not impacted (CI Linux results include performance check)
  • Run Unit Test(s) locally
  • Check any new function arguments for performance impacts
  • Verify IDF naming conventions and styles, memos and notes and defaults
  • If new idf included, locally check the err file and other outputs

@mitchute mitchute added the Defect Includes code to repair a defect in EnergyPlus label Nov 24, 2025
@kevin-moos kevin-moos marked this pull request as ready for review November 24, 2025 20:46
Copy link
Collaborator

@mitchute mitchute left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks right.

PartLoadFrac = ReqOutput / FullOutput;
if (FullOutput != 0) {
PartLoadFrac = ReqOutput / FullOutput;
}
Copy link
Contributor

@rraustad rraustad Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is likely a reason (a developer oversight) that FullOutput has not been calculated. Usually FullOutput is set near the beginning of this function when PLR is set to 1 and the system capacity is checked to see if that capacity exceeds the load, otherwise PLR = 1 and more calculations are not needed. See line 13249, 13681 and 13732. One thing is for sure, if this function is iterating with SolveRoot then the system does have a non-zero FullOutput (or maybe the coil is scheduled off? but I would think that would be caught early). To figure out the why you would need to step through this function at the time the error occurred.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rraustad I believe this catches the issue noted, but I'll hold this open for a little bit in case you want to take another quick look for any other higher level issues.

Copy link
Contributor

@rraustad rraustad Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added at line 14133:

if (OutletHumRatLS > DesOutHumRat) {
    CycRatio = 1.0;
    this->m_CoolingSpeedNum = std::max(1, this->m_CoolingSpeedNum);  <-- new line since speedNum was 0

    for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; ++speedNum) {

The reason SolveRoot was failing was that a sensible load did not exist and FullOutput was not calculated and remained 0 from initialization (line 12999). There was, however, a latent load when there should NOT have been a latent load given these inputs. Adding the line above did allow SolveRoot to find the correct PLR and no longer fails with SolFla = -2. But there is another logic issue somewhere, I have not found that yet. I guess this change is OK but avoiding this calculation if FullOutput = 0 is not really the correct thing to do (because calling SolveRoot means the system is trying to meet a load and therefore the system should have a non-zero capacity) since if SolveRoot does fail with -2 then PLR will default to 0 and it would be prudent to at least try to find an operating PLR, as faulty as this could be (i.e., trying to find PLR based on PartLoadFrac = ReqOutput / FullOutput).

CoilSystem:Cooling:DX,
  GUID11_SYS0SCC-1System,
  None,   !- Dehumidification Control Type
  Yes,    !- Run on Sensible Load
  No,     !- Run on Latent Load

CoilSystem:Cooling:DX,
  A10,  \field Run on Latent Load
    \type choice
    \key Yes
    \key No
    \default No
    \note If Yes, unit will run if there is a latent load.
    \note even if there is no sensible load.
    \note If No, unit will not run only if there is a latent load.
    \note Dehumidification controls will be active if specified.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A more important point is that SolveRoot should never fail with -2. That in itself is a developer error.

@rraustad
Copy link
Contributor

rraustad commented Dec 5, 2025

Ah, there are 2 CoilSystem objects in this file. One uses humidity control and the other does not. So my comment about a logic issue was incorrect. I would still add the new line in this comment so that SolveRoot does not fail with -2.

CoilSystem:Cooling:DX,
  GUID11_SYS1SCC-1System,
  ,
  GUID11_SYS1SHC-1Outlet Node,
  GUID11_SYS1SCC-1Outlet Node,
  GUID11_SYS1SCC-1Outlet Node,
  Coil:Cooling:DX:VariableSpeed,
  GUID11_SYS1SCC-1,
  CoolReheat,
  Yes,
  Yes,
  Yes,
  2.22222222222222;

CoilSystem:Cooling:DX,
  GUID11_SYS0SCC-1System,
  ,
  GUID11_SYS0SHC-1Outlet Node,
  GUID11_SYS0SCC-1Outlet Node,
  GUID11_SYS0SCC-1Outlet Node,
  Coil:Cooling:DX:VariableSpeed,
  GUID11_SYS0SCC-1,
  None,
  Yes,
  No,
  No,
  2.22222222222222;

@kevin-moos
Copy link
Contributor Author

Added the new line from this comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Defect Includes code to repair a defect in EnergyPlus

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unitary system div by zero in controlCoolingSystemToSP

5 participants