Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2713,7 +2713,7 @@ \subsubsection{References}\label{references-gnd-srfs}

\subsection{SurfaceProperty:LocalEnvironment}\label{surfacePropertylocalEnvironment}

The object links to an exterior surface object \textbf{BuildingSurface:Detailed} or an exterior fenestration object \textbf{FenestrationSurface:Detailed} and is used when there is a need to calculate surface level environmental data externally and import them into the simulation to override existing environmental data, including external solar shading fractions, local air velocity, temperature and humidity, and surrounding surface temperatures, sky view factor, ground surfaces view factors, ground surfaces temperature and ground surfaces reflectance. The object links to four optional objects including a schedule object declared by \textbf{Field: Sunlit Fraction Schedule Name}, a \textbf{\hyperref[surfacePropertySurroundingSurfaces]{SurfaceProperty:SurroundingSurfaces}} object declared by \textbf{Field: Surrounding Surfaces Object Name}, an \textbf{\hyperref[outdoorairnode]{OutdoorAir:Node}} object declared by \textbf{Field: Outdoor Air Node Name}, and a \textbf{\hyperref[surfacePropertyGroundSurfaces]{SurfaceProperty:GroundSurfaces}} object declared by
The object links to an exterior surface object (e.g., \textbf{BuildingSurface:Detailed}) or an exterior fenestration object (e.g., \textbf{FenestrationSurface:Detailed}) and is used when there is a need to calculate surface level environmental data externally and import them into the simulation to override existing environmental data, including external solar shading fractions, local air velocity, temperature and humidity, and surrounding surface temperatures, sky view factor, ground surfaces view factors, ground surfaces temperature and ground surfaces reflectance. The object links to four optional objects including a schedule object declared by \textbf{Field: Sunlit Fraction Schedule Name}, a \textbf{\hyperref[surfacePropertySurroundingSurfaces]{SurfaceProperty:SurroundingSurfaces}} object declared by \textbf{Field: Surrounding Surfaces Object Name}, an \textbf{\hyperref[outdoorairnode]{OutdoorAir:Node}} object declared by \textbf{Field: Outdoor Air Node Name}, and a \textbf{\hyperref[surfacePropertyGroundSurfaces]{SurfaceProperty:GroundSurfaces}} object declared by
\textbf{Field: Ground Surfaces Object Name}. The object provides inputs to calculate shading, solar radiation, zone air balance, and surface exterior heat balance.

\subsubsection{Field: Name}\label{field-surf-localenv-name}
Expand Down
8 changes: 5 additions & 3 deletions idd/Energy+.idd.in
Original file line number Diff line number Diff line change
Expand Up @@ -18873,7 +18873,7 @@ SurfaceProperty:LocalEnvironment,
\reference SurfaceLocalEnvironmentNames
A2, \field Exterior Surface Name
\type object-list
\object-list SurfaceNames
\object-list AllHeatTranSurfNames
Copy link
Collaborator

Choose a reason for hiding this comment

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

I assume this change was made to include FenestrationSurface:Detailed in the list of object names in the IDF Editor. However, AllHeatTranSurfNames (and SurfaceNames) also includes objects that should not show up in that list provided by the IDF Editor. It may also be that the IO Ref description below does not include all valid surface types but I did not check that. The fix would be to add a new reference to the valid objects and use that here instead?

1.11.28 SurfaceProperty:LocalEnvironment
The object links to an exterior surface object BuildingSurface:Detailed or an exterior fenestration object
FenestrationSurface:Detailed and is used when ...

FenestrationSurface:Detailed,
   \memo Allows for detailed entry of subsurfaces
   \memo (windows, doors, glass doors, tubular daylighting devices).
   \min-fields 18
   \format vertices
A1 , \field Name
   \required-field
   \type alpha
   \reference SubSurfNames
   \reference GlazedExtSubSurfNames
   \reference SurfAndSubSurfNames
   \reference AllHeatTranSurfNames

For example, what good would it do to use SurfaceProperty:LocalEnvironment with an adiabatic floor? Maybe I am overthinking this and this change is sufficient to at least include the relevant objects.

Floor:Adiabatic,
   \memo Allows for simplified entry of exterior floors
   \memo ignoring ground contact or interior floors.
   \memo View Factor to Ground is automatically calculated.
A1 , \field Name
   \required-field
   \type alpha
   \reference SurfaceNames
   \reference SurfAndSubSurfNames
   \reference AllHeatTranSurfNames

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point. For example currently if you open SolarShadingTest_ExternalFraction.idf in IDF Editor, the list of SurfaceProperty:LocalEnvironment objects will initially populate the Exterior Surface Name fields with:

  • Shading:Site:Detailed (invalid)
  • FenestrationSurface:Detailed (invalid)
  • BuildingSurface:Detailed (valid)

But the dropdowns don't show any Shading:Site:Detailed or FenestrationSurface:Detailed objects. If we switched SurfaceNames -> AllHeatTranSurfNames we'd still be including invalid Floor:Adiabatic in the dropdowns. So assuming the docs are correct, we'd need a reference that is shared between only FenestrationSurface:Detailed and BuildingSurface:Detailed; if one doesn't already exist, we need to add a new one.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Be careful when thinking the docs are correct. I think as a user I would expect Wall:Detailed to be the same as BuildingSurface:Detailed in the context of SurfaceProperty:LocalEnvironment. Even an exterior door should be able to use the local environment properties? I am sure you can think of other use cases for this object.

Copy link
Collaborator Author

@joseph-robertson joseph-robertson Mar 4, 2026

Choose a reason for hiding this comment

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

See 1886efe. Indeed Wall:Detailed, e.g., is a valid object (I checked locally). Based on the code, shading objects are certainly invalid. So I propose that we stick with the \object-list AllHeatTranSurfNames change (to pick up fenestration), but not get overly ambitious with a new reference as we may accidentally exclude a valid object type.

\note Enter the name of an exterior surface object
A3, \field Sunlit Fraction Schedule Name
\type object-list
Expand Down Expand Up @@ -18920,7 +18920,8 @@ SurfaceProperty:SurroundingSurfaces,
N1, \field Sky View Factor
\minimum 0.0
\maximum 1.0
\default 0.5
\autocalculatable
\default autocalculate
\note optional
A2, \field Sky Temperature Schedule Name
\type object-list
Expand All @@ -18930,7 +18931,8 @@ SurfaceProperty:SurroundingSurfaces,
N2, \field Ground View Factor
\minimum 0.0
\maximum 1.0
\default 0.5
\autocalculatable
\default autocalculate
\note optional
A3, \field Ground Temperature Schedule Name
\type object-list
Expand Down
4 changes: 2 additions & 2 deletions src/EnergyPlus/HeatBalanceManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1805,11 +1805,11 @@ namespace HeatBalanceManager {
// METHODOLOGY EMPLOYED:
// The GetObjectItem routines are employed to retrieve the data.

SolarShading::GetShadowingInput(state);

GetZoneData(state, ErrorsFound); // Read Zone data from input file

SurfaceGeometry::SetupZoneGeometry(state, ErrorsFound);

SolarShading::GetShadowingInput(state);
Comment on lines 1817 to +1819
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This PR inadvertently moved GetShadowingInput before SetupZoneGeometry. But we need it after so that surface data is read first. The existing relevant unit test didn't catch this because of this reason.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@RKStrand Are you OK with this change? I believe the only regression implication is to change the order of a few lines in the EIO file.

Copy link
Contributor

Choose a reason for hiding this comment

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

@joseph-robertson Um, yeah, as long as it doesn't trip any weird things in the unit tests, I'm guessing it will be okay. I seem to vaguely remember some recent work here and there were some issues with order dependence on some of the calls in this area of the code. I think I couldn't move something up as high as I thought because it caused other crashes because stuff wasn't read in yet. Anyway, if you move it an there are no unit test or test suite issues that pop up, then it's probably fine.

}

void GetZoneData(EnergyPlusData &state, bool &ErrorsFound) // If errors found in input
Expand Down
42 changes: 37 additions & 5 deletions src/EnergyPlus/SolarShading.cc
Original file line number Diff line number Diff line change
Expand Up @@ -490,12 +490,15 @@ void GetShadowingInput(EnergyPlusData &state)
format("Value entered=\"{}\" while no Schedule:File:Shading object is defined, InternalCalculation will be used.",
state.dataIPShortCut->cAlphaArgs(aNum)));
}
checkNotScheduledSurfacePresent(state);
} else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "PolygonClipping")) {
state.dataSysVars->shadingMethod = ShadingMethod::PolygonClipping;
state.dataIPShortCut->cAlphaArgs(aNum) = "PolygonClipping";
checkNotScheduledSurfacePresent(state);
} else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(aNum), "PixelCounting")) {
state.dataSysVars->shadingMethod = ShadingMethod::PixelCounting;
state.dataIPShortCut->cAlphaArgs(aNum) = "PixelCounting";
checkNotScheduledSurfacePresent(state);
if (NumNumbers >= 3) {
pixelRes = (unsigned)state.dataIPShortCut->rNumericArgs(3);
}
Expand Down Expand Up @@ -526,6 +529,7 @@ void GetShadowingInput(EnergyPlusData &state)
} else {
state.dataIPShortCut->cAlphaArgs(aNum) = "PolygonClipping";
state.dataSysVars->shadingMethod = ShadingMethod::PolygonClipping;
checkNotScheduledSurfacePresent(state);
}

aNum++;
Expand Down Expand Up @@ -818,7 +822,7 @@ void processShadowingInput(EnergyPlusData &state)

void checkScheduledSurfacePresent(EnergyPlusData &state)
{
// User has chosen "Scheduled" for sunlit fraction so check to see which surfaces don't have a schedule
// User has chosen "Scheduled" for sunlit fraction so check to see which surfaces don't have a schedule.
int numNotDef = 0;
int constexpr maxErrMessages = 50;
auto &surfData = state.dataSurface;
Expand All @@ -831,16 +835,44 @@ void checkScheduledSurfacePresent(EnergyPlusData &state)
if (!thisSurf.SurfSchedExternalShadingFrac) {
numNotDef += 1;
if (numNotDef == 1) {
ShowWarningError(
state,
format("ShadowCalculation specified Schedule for the Shading Calculation Method but no schedule provided for {}", thisSurf.Name));
ShowWarningError(state,
format("ShadowCalculation specified Schedule for the Shading Calculation Method but no schedule provided for {}.",
thisSurf.Name));
ShowContinueError(
state, "When Schedule is selected for the Shading Calculation Method and no schedule is provided for a particular surface,");
ShowContinueError(
state, "EnergyPlus will assume that the surface is not shaded. Use SurfaceProperty:LocalEnvironment to specify a schedule");
ShowContinueError(state, "for sunlit fraction if this was not desired. Otherwise, this surface will not be shaded at all.");
} else if (numNotDef <= maxErrMessages) {
ShowWarningError(state, format("No schedule was provided for {} either. See above error message for more details", thisSurf.Name));
ShowWarningError(state, format("No schedule was provided for {} either. See above error message for more details.", thisSurf.Name));
}
}
}
if (numNotDef > maxErrMessages) {
ShowContinueError(state, format("This message is only shown for the first {} occurrences of this issue.", maxErrMessages));
}
}

void checkNotScheduledSurfacePresent(EnergyPlusData &state)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

New method for issuing a warning when a surface has a sunlit fraction schedule but the ShadowCalculation object has Shading Calculation Method != Scheduled. This is the contrapositive (?!) to checkScheduledSurfacePresent.

{
// User has *not* chosen "Scheduled" for sunlit fraction so check to see which surfaces *have* a schedule.
int numNotDef = 0;
int constexpr maxErrMessages = 50;
auto &surfData = state.dataSurface;
for (int surfNum = 1; surfNum <= surfData->TotSurfaces; ++surfNum) {
auto &thisSurf = surfData->Surface(surfNum);
if ((thisSurf.Class == SurfaceClass::Shading || thisSurf.Class == SurfaceClass::Detached_F || thisSurf.Class == SurfaceClass::Detached_B ||
thisSurf.Class == SurfaceClass::Overhang || thisSurf.Class == SurfaceClass::Fin)) {
continue; // skip shading surfaces
}
if (thisSurf.SurfSchedExternalShadingFrac) {
numNotDef += 1;
if (numNotDef == 1) {
ShowWarningError(state,
format("ShadowCalculation did not specify Schedule for the Shading Calculation Method but schedule provided for {}.",
thisSurf.Name));
} else if (numNotDef <= maxErrMessages) {
ShowWarningError(state, format("Schedule was also provided for {}. See above error message for more details.", thisSurf.Name));
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/EnergyPlus/SolarShading.hh
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ namespace SolarShading {

void checkScheduledSurfacePresent(EnergyPlusData &state);

void checkNotScheduledSurfacePresent(EnergyPlusData &state);

void AllocateModuleArrays(EnergyPlusData &state);

void AnisoSkyViewFactors(EnergyPlusData &state);
Expand Down
209 changes: 0 additions & 209 deletions testfiles/SolarShadingTest_ExternalFraction.idf
Original file line number Diff line number Diff line change
Expand Up @@ -670,215 +670,6 @@
, !- Sky Diffuse Modeling Algorithm
Yes; !- Output External Shading Calculation Results

Copy link
Collaborator

Choose a reason for hiding this comment

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

@joseph-robertson I thought I saw a comment of why these were removed but can't find that now. Could you elaborate why these would need to be removed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The SurfaceProperty:LocalEnvironment objects referencing shading objects don't need to be removed; but I think they can safely be removed since they have no impact on the model.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Got it. Thanks.

SurfaceProperty:LocalEnvironment,
LocEnv:EAST SIDE TREE, !- Name
EAST SIDE TREE, !- Exterior Surface Name
ExtShadingSch:EAST SIDE TREE, !- Sunlit Fraction Schedule Name
, !- Surrounding Surfaces Object Name
; !- Outdoor Air Node Name

Schedule:File,
ExtShadingSch:EAST SIDE TREE, !- Name
Fraction, !- Schedule Type Limits Name
SolarShadingTest_Shading_Data.csv, !- File Name
2, !- Column Number
1, !- Rows to Skip at Top
, !- Number of Hours of Data
, !- Column Separator
, !- Interpolate to Timestep
15, !- Minutes per Item
; !- Adjust Schedule for Daylight Savings

SurfaceProperty:LocalEnvironment,
LocEnv:WEST SIDE TREE, !- Name
WEST SIDE TREE, !- Exterior Surface Name
ExtShadingSch:WEST SIDE TREE, !- Sunlit Fraction Schedule Name
, !- Surrounding Surfaces Object Name
; !- Outdoor Air Node Name

Schedule:File,
ExtShadingSch:WEST SIDE TREE, !- Name
Fraction, !- Schedule Type Limits Name
SolarShadingTest_Shading_Data.csv, !- File Name
4, !- Column Number
1, !- Rows to Skip at Top
, !- Number of Hours of Data
, !- Column Separator
, !- Interpolate to Timestep
15, !- Minutes per Item
; !- Adjust Schedule for Daylight Savings

SurfaceProperty:LocalEnvironment,
LocEnv:ZN001:WALL001:SHADE001, !- Name
ZN001:WALL001:SHADE001, !- Exterior Surface Name
ExtShadingSch:ZN001:WALL001:SHADE001, !- Sunlit Fraction Schedule Name
, !- Surrounding Surfaces Object Name
; !- Outdoor Air Node Name

Schedule:File,
ExtShadingSch:ZN001:WALL001:SHADE001, !- Name
Fraction, !- Schedule Type Limits Name
SolarShadingTest_Shading_Data.csv, !- File Name
6, !- Column Number
1, !- Rows to Skip at Top
, !- Number of Hours of Data
, !- Column Separator
, !- Interpolate to Timestep
15, !- Minutes per Item
; !- Adjust Schedule for Daylight Savings

SurfaceProperty:LocalEnvironment,
LocEnv:ZN002:WALL001:SHADE001, !- Name
ZN002:WALL001:SHADE001, !- Exterior Surface Name
ExtShadingSch:ZN002:WALL001:SHADE001, !- Sunlit Fraction Schedule Name
, !- Surrounding Surfaces Object Name
; !- Outdoor Air Node Name

Schedule:File,
ExtShadingSch:ZN002:WALL001:SHADE001, !- Name
Fraction, !- Schedule Type Limits Name
SolarShadingTest_Shading_Data.csv, !- File Name
8, !- Column Number
1, !- Rows to Skip at Top
, !- Number of Hours of Data
, !- Column Separator
, !- Interpolate to Timestep
15, !- Minutes per Item
; !- Adjust Schedule for Daylight Savings

SurfaceProperty:LocalEnvironment,
LocEnv:ZN003:WALL001:SHADE001, !- Name
ZN003:WALL001:SHADE001, !- Exterior Surface Name
ExtShadingSch:ZN003:WALL001:SHADE001, !- Sunlit Fraction Schedule Name
, !- Surrounding Surfaces Object Name
; !- Outdoor Air Node Name

Schedule:File,
ExtShadingSch:ZN003:WALL001:SHADE001, !- Name
Fraction, !- Schedule Type Limits Name
SolarShadingTest_Shading_Data.csv, !- File Name
10, !- Column Number
1, !- Rows to Skip at Top
, !- Number of Hours of Data
, !- Column Separator
, !- Interpolate to Timestep
15, !- Minutes per Item
; !- Adjust Schedule for Daylight Savings

SurfaceProperty:LocalEnvironment,
LocEnv:ZN004:WALL001:SHADE001, !- Name
ZN004:WALL001:SHADE001, !- Exterior Surface Name
ExtShadingSch:ZN004:WALL001:SHADE001, !- Sunlit Fraction Schedule Name
, !- Surrounding Surfaces Object Name
; !- Outdoor Air Node Name

Schedule:File,
ExtShadingSch:ZN004:WALL001:SHADE001, !- Name
Fraction, !- Schedule Type Limits Name
SolarShadingTest_Shading_Data.csv, !- File Name
12, !- Column Number
1, !- Rows to Skip at Top
, !- Number of Hours of Data
, !- Column Separator
, !- Interpolate to Timestep
15, !- Minutes per Item
; !- Adjust Schedule for Daylight Savings

SurfaceProperty:LocalEnvironment,
LocEnv:ZN005:WALL001:SHADE001, !- Name
ZN005:WALL001:SHADE001, !- Exterior Surface Name
ExtShadingSch:ZN005:WALL001:SHADE001, !- Sunlit Fraction Schedule Name
, !- Surrounding Surfaces Object Name
; !- Outdoor Air Node Name

Schedule:File,
ExtShadingSch:ZN005:WALL001:SHADE001, !- Name
Fraction, !- Schedule Type Limits Name
SolarShadingTest_Shading_Data.csv, !- File Name
14, !- Column Number
1, !- Rows to Skip at Top
, !- Number of Hours of Data
, !- Column Separator
, !- Interpolate to Timestep
15, !- Minutes per Item
; !- Adjust Schedule for Daylight Savings

SurfaceProperty:LocalEnvironment,
LocEnv:ZN006:WALL001:SHADE001, !- Name
ZN006:WALL001:SHADE001, !- Exterior Surface Name
ExtShadingSch:ZN006:WALL001:SHADE001, !- Sunlit Fraction Schedule Name
, !- Surrounding Surfaces Object Name
; !- Outdoor Air Node Name

Schedule:File,
ExtShadingSch:ZN006:WALL001:SHADE001, !- Name
Fraction, !- Schedule Type Limits Name
SolarShadingTest_Shading_Data.csv, !- File Name
16, !- Column Number
1, !- Rows to Skip at Top
, !- Number of Hours of Data
, !- Column Separator
, !- Interpolate to Timestep
15, !- Minutes per Item
; !- Adjust Schedule for Daylight Savings

SurfaceProperty:LocalEnvironment,
LocEnv:ZN007:WALL001:SHADE001, !- Name
ZN007:WALL001:SHADE001, !- Exterior Surface Name
ExtShadingSch:ZN007:WALL001:SHADE001, !- Sunlit Fraction Schedule Name
, !- Surrounding Surfaces Object Name
; !- Outdoor Air Node Name

Schedule:File,
ExtShadingSch:ZN007:WALL001:SHADE001, !- Name
Fraction, !- Schedule Type Limits Name
SolarShadingTest_Shading_Data.csv, !- File Name
18, !- Column Number
1, !- Rows to Skip at Top
, !- Number of Hours of Data
, !- Column Separator
, !- Interpolate to Timestep
15, !- Minutes per Item
; !- Adjust Schedule for Daylight Savings

SurfaceProperty:LocalEnvironment,
LocEnv:ZN008:WALL001:SHADE001, !- Name
ZN008:WALL001:SHADE001, !- Exterior Surface Name
ExtShadingSch:ZN008:WALL001:SHADE001, !- Sunlit Fraction Schedule Name
, !- Surrounding Surfaces Object Name
; !- Outdoor Air Node Name

Schedule:File,
ExtShadingSch:ZN008:WALL001:SHADE001, !- Name
Fraction, !- Schedule Type Limits Name
SolarShadingTest_Shading_Data.csv, !- File Name
20, !- Column Number
1, !- Rows to Skip at Top
, !- Number of Hours of Data
, !- Column Separator
, !- Interpolate to Timestep
15, !- Minutes per Item
; !- Adjust Schedule for Daylight Savings

SurfaceProperty:LocalEnvironment,
LocEnv:ZN009:WALL001:SHADE001, !- Name
ZN009:WALL001:SHADE001, !- Exterior Surface Name
ExtShadingSch:ZN009:WALL001:SHADE001, !- Sunlit Fraction Schedule Name
, !- Surrounding Surfaces Object Name
; !- Outdoor Air Node Name

Schedule:File,
ExtShadingSch:ZN009:WALL001:SHADE001, !- Name
Fraction, !- Schedule Type Limits Name
SolarShadingTest_Shading_Data.csv, !- File Name
22, !- Column Number
1, !- Rows to Skip at Top
, !- Number of Hours of Data
, !- Column Separator
, !- Interpolate to Timestep
15, !- Minutes per Item
; !- Adjust Schedule for Daylight Savings

SurfaceProperty:LocalEnvironment,
LocEnv:ZN001:WALL001, !- Name
ZN001:WALL001, !- Exterior Surface Name
Expand Down
Loading
Loading