Add EMS actuator for CondFD sky longwave radiation override#11478
Add EMS actuator for CondFD sky longwave radiation override#11478brianlball wants to merge 16 commits intodevelopfrom
Conversation
Add "CondFD Surface / Sky Longwave Radiation Override" EMS actuator that replaces the hsky*(Tsky-Tsurf) term in ExteriorBCEqns with a user-supplied net sky radiation flux (W/m2). Positive = heat into surface. Header: add enetActuator field (MaterialActuatorData) to SurfaceDataFD. Source changes: - InitHeatBalFiniteDiff: register actuator + output variable for each exterior CondFD surface - ExteriorBCEqns: override sky term in all 6 locations when actuated: 1. R-layer (massless wall) 2. Crank-Nicolson 2nd order 3. Fully implicit 1st order 4. Movable insulation TInsulOut 5. QNetSurfFromOutside 6. SurfQdotRadOutRepPerArea When actuated, hsky*Tsky is replaced by Enet in numerators and hsky is removed from denominators (Enet is a fixed flux, not temperature-dependent). When not actuated, existing behavior is completely unchanged.
Test HeatBalFiniteDiffManager_EnetActuatorOverride exercises ExteriorBCEqns directly with a single-layer concrete surface under FullyImplicitFirstOrder. Four sub-cases: - Actuator OFF: baseline sky radiation via hsky*(Tsky-Tsurf) - Actuator ON, Enet=0: no sky LW exchange, surface warmer than baseline - Actuator ON, Enet=-200: strong sky cooling, surface colder than baseline - Actuator ON, Enet=+200: sky heats surface, warmest case Verifies temperature ordering: Enet=-200 < baseline < Enet=0 < Enet=+200
1ZoneCondFD_Enet_Test.idf: 1-zone box with CondFD, Denver design days, comprehensive outside face heat balance outputs + SQLite. Baseline for validating actuator behavior. 1ZoneCondFD_Enet_EMS.idf: same model with EMS program setting Enet = -200 W/m2 on roof. Validated against Phase 2 hardcoded results: baseline roof temp -23.8C vs EMS Enet=-200 roof temp -54.0C. Both registered in testfiles/CMakeLists.txt as DESIGN_DAY_ONLY.
PythonPluginCondFD_Enet.py: EnergyPlus plugin class for use inside IDF workflows. Edit SURFACE_NAME and ENET_VALUE, add PythonPlugin:Instance to IDF. scripts/CondFD_Enet_Override.ipynb: Jupyter notebook for interactive use with any IDF/EPW. Features: - Auto-detects exterior CondFD surfaces by parsing IDF - Runs baseline + multiple Enet values in one session - Plots temperature and LW radiation comparison per surface - CSV export and time-varying Enet from CSV (for COMSOL coupling) NFP_SkyLW_Actuator.md: New Feature Proposal documenting the actuator design, physics, sign convention, testing, and scope.
Add QRad sign checks, SurfOpaqOutFaceCondFlux monotonic ordering, and actuator toggle-back test to cover output variable correctness and state restoration.
…-experts - Moved NFP_SkyLW_Actuator.md to design/FY2026/ - Added Background section: Stefan-Boltzmann law, linearization explanation, formal Enet definition, key terminology table - Expanded Physics section with full implicit solver equation - Added sign convention references with 5 verified sources
- I/O ref: document Sky Longwave Radiation Override output - EMS guide: document CondFD Surface actuator and output variable - Register PythonPluginCondFD_Enet integration test - Add CrankNicolson scheme unit test for Enet actuator override
|
|
|
|
|
|
|
|
|
|
|
rraustad
left a comment
There was a problem hiding this comment.
Implementation looks thorough and well tested.
There was a problem hiding this comment.
@brianlball what's the difference between these IDFs? If possible, let's add this behavior to the PythonPlugin1ZoneUncontrolledCondFD test file, so our example files are not blowing up more than they already are.
There was a problem hiding this comment.
@mitchute that test file can get removed, should already be covered by the plugin test. It was my first actuator so I went a little overboard on the testing.
|
@brianlball one minor change here: 9a155c5 Let me know if you have an issue with it. |
|
|
|
|
|
| Real64 const Toa(state.dataMstBal->TempOutsideAirFD(Surf)); | ||
| Real64 const Tgnd(Tgndsurface); | ||
| Real64 const Tsurr(TsurrSurface); | ||
| auto const &enetAct = s_hbfd->SurfaceFD(Surf).enetActuator; |
There was a problem hiding this comment.
This all looks correct so consider this just a suggestion. There are several new conditionals added to this code below, i.e., if (enetAct.isActuated). And in those uses are the same terms, hsky and hsky * Tsky. It may be more efficient to create those terms here and use these new terms below without needing the conditionals.
Real64 eHsky = (enetAct.isActuated) ? 0.0 : hSky;
Real64 eHskyTsky = (enetAct.isActuated) ? enetAct.actuatedValue : hsky * Tsky;
And then just replace those terms below with these new variables without needing the new conditionals?
| QRadSWOutFD + (hgnd * (-TDT_i + Tgnd) + (hconvo + hrad) * Toa_TDT_i + enetAct.actuatedValue + hsurr * (-TDT_i + Tsurr)); | ||
| } else { | ||
| QNetSurfFromOutside = | ||
| QRadSWOutFD + (hgnd * (-TDT_i + Tgnd) + (hconvo + hrad) * Toa_TDT_i + hsky * (-TDT_i + Tsky) + hsurr * (-TDT_i + Tsurr)); |
There was a problem hiding this comment.
The use here and below are different, e.g., hsky * (-TDT_i + Tsky), so could be left as-is.
|
|
Summary
https://github.com/NatLabRockies/EnergyPlus/blob/longwaverad_act/design/FY2026/NFP_SkyLW_Actuator.md
longwave radiation term in the CondFD exterior face heat balance with a user-specified net heat flux [W/m2]. This
enables custom radiative cooling models (e.g., spectrally-selective coatings, sub-ambient sky emitters) without
modifying E+ source.
not actuated).
Changes
both FI and CN code paths; set up output variable.
schemes, verifying temperature shifts and flux restoration on de-actuation.
Test Plan
testfiles/: Integration test IDFs (1ZoneCondFD_Enet_Test.idf, PythonPluginCondFD_Enet.idf).
tst/EnergyPlus/unit/HeatBalFiniteDiffManager.unit.cc: Unit tests covering actuator override for both FI and CN
Integration test PythonPluginCondFD_Enet passes
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.*)
Reviewer