Skip to content

Add NFP for DefaultConstructionSet - #11613

Open
kbenne wants to merge 5 commits into
developfrom
NFP-DefaultConstructionSet-nfp-only
Open

Add NFP for DefaultConstructionSet#11613
kbenne wants to merge 5 commits into
developfrom
NFP-DefaultConstructionSet-nfp-only

Conversation

@kbenne

@kbenne kbenne commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Pull request overview

Adds the NFP design document for native DefaultConstructionSet support in EnergyPlus, proposing building and space level default construction assignments to reduce repeated surface construction inputs and facilitate OpenStudio alignment.

@RKStrand

RKStrand commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

I get the desire to provide something that makes E+ and OS closer to the same thing and don't really have any problems with this. As long as users can still do what they have done previously--still define a construction for every surface as part of that object (which you propose is still going to be allowed), I don't have anything against moving this forward. While it doesn't add new functionality to E+, there could be some potential benefits to having this option. The slight downside is that for those who read their IDF directly, it's one more layer of search that one might have to go through to find the construction information, but presumably users taking advantage of this proposed new feature will trade that for a more universal definition of construction that simplifies the input and changes.

@JasonGlazer JasonGlazer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Overall, I have no objection to the concept of defaulting constructions but some of the details may still need some refinement.

Two existing objects are extended with an optional field:

- **`Building`** — gains `Default Construction Set Name`.
- **`Space`** — gains `Default Construction Set Name`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems to me that at the space level, there aren't typically that many surfaces and the value is smaller. The user can just enter the constructions for each surface. If that is the case then there would only need to be one DefaultConstructionSet object which would be a \unique-object and that corresponds better with the concept of "default" to me. I guess having multiple DefaultConstructionSet input objects seems a bit contradictory to me. It is just an idea but I think it might be cleaner.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

See "This matters because conceptually you have to be thinking about what owns/drives the constructions" in #11613 (comment)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not sure I'm convinced that this is a good approach.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

One tweak could be a name change to ConstructionAssignmentSet instead of DefaultConstructionSet. The supporting type names could be SurfaceConstructionAssignments and SubSurfaceConstructionAssignments. This might communicate the concept a little better.


- Space
- SpaceType (no E+ equivalent)
- BuildingStory (no E+ equivalent)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Given the lack of the SpaceType and BuildingStory levels of inheritance, does this overall approach really help or just make it complicated in a different way?

For support of OS <-> E+ Alignment.
`DefaultConstructionSet` is widely used in OpenStudio; breaking API here would have too much impact.

EnergyPlus currently requires a `Construction Name` to be explicitly specified on every surface and sub-surface — potentially hundreds or thousands of objects in a large model.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

EnergyPlus has a long history of trying to make things exhaustively self documenting. I'm not sure that was ever a great approach but I understand the philosophy of looking at an input object and knowing what it means from the list of field values. This approach, purposefully, changes course to make some input objects not self documenting. I'm not apposed to the change but it should not be done without understanding that this is a shift in philosophy. It will potentially impact the users perspective with an added question in their mind, "does blank field mean it is defined somewhere else?" Overall, I am not opposed to this approach but it might be good to step back and try to make a comprehensive plan for how defaulting should work in general.

Constructions are resolved at run time based on surface type and boundary condition. This offers several advantages:

1. **DRY input data** — a single construction assignment at the building or space level avoids redundant repetition across every surface.
2. **Easy global swaps** — changing a construction type (e.g., upgrading wall insulation) requires editing one object instead of hundreds.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think most users just redefine the construction when they need to (such as upgrading wall insulation) so I think that is just changing one object also.

Comment thread design/FY2026/NFP-DefaultConstructionSet.md Outdated

## Outputs Description ##

No new output variables are added.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think that maybe we do need to think of a new tabular report or column that shows if it a construction was blank what it inherited.

- **`BuildingSurface:Detailed`**, **`FenestrationSurface:Detailed`**, **`InternalMass`** — `Construction Name` changes from required to optional. No data change needed; existing IDFs with explicit constructions are unaffected.
- **`FenestrationSurface:Detailed` `Surface Type`** — four new keys added (`FixedWindow`, `OperableWindow`, `Skylight`, `OverheadDoor`). No data change needed; existing `Window` values remain valid and are treated as `FixedWindow` for `DefaultConstructionSet` resolution.

## References ##

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you make these links?


- Parse all `DefaultSurfaceConstructions` and `DefaultSubSurfaceConstructions` objects into structs.
- Parse all `DefaultConstructionSet` objects, resolving the nested object-list references.
- Read the new `Default Construction Set Name` field from `Building` and each `Space`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thinking about levels of defaulting, would it make sense for a Building Surface to have defaulting so that all subsurfaces can default to the same?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not sure I follow correctly.

You mean a single BuildingSurface:Detailed could have a DefaultConstructionSet assigned? It's tedious for little gain, there shouldn't be a large number of SubSurfaces for a given Surface

\type object-list
\object-list ConstructionNames

DefaultSubSurfaceConstructions,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe the orientation direction should play a part in defaulting. Is is very common for northern facing windows to be different than east, west, and south facing windows.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That'd be multpliying the number of fields a lot and would hurt readability badly IMHO.
You could hard-assign the northern ones, or use a DefaultConstructionSet with only the window types specified (the rest will still resolve up the inheritance) and assign that to the north spaces.

Comment thread design/FY2026/NFP-DefaultConstructionSet.md Outdated
@Myoldmopar

Copy link
Copy Markdown
Member

[TRANE] We have something like this in our UI so that it is easy to change constructions for a whole space type or building. I didn't expect it to be such a challenge to translate that into the engine level's current input structure.

[Myoldmopar] I'm not a big fan of this one. Currently we have construction name explicitly written on each surface. If you want to change the type of construction throughout the file, you can do a search and replace or poke around or whatever. If you have them blank, then you need to go in and even more surgically look through the file to decide which surfaces have the default and which don't. You can't search and replace on the blank field. Seems like there's a bigger chance of forgetting to update some surfaces and ending up with incorrect envelope physics. Maybe this change is more about a UI writing the file? But if so, it seems quite trivial for the UI to just determine which construction name to use and put it in there when creating the input file. Maybe I'm missing something.

@jmarrec

jmarrec commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

[Myoldmopar] I'm not a big fan of this one. Currently we have construction name explicitly written on each surface. If you want to change the type of construction throughout the file, you can do a search and replace or poke around or whatever. If you have them blank, then you need to go in and even more surgically look through the file to decide which surfaces have the default and which don't. You can't search and replace on the blank field. Seems like there's a bigger chance of forgetting to update some surfaces and ending up with incorrect envelope physics.

You are absolutely not obligated to use this feature. If you prefer to hard-assign every construction because that's what you are used to, that's totally fine.

If you do decide to use it, the main point is you don't need a search and replace at all. Just swap constructions in your DefaultConstructionSet and you're done.

Maybe this change is more about a UI writing the file? But if so, it seems quite trivial for the UI to just determine which construction name to use and put it in there when creating the input file. Maybe I'm missing something.

The main thing you're probably not considering is the ability to round-trip.
OpenStudio has been filling the Construction Name field during ForwardTranslation to IDF for more than a decade without any issues.
But once you have written the IDF and try to re-load it, there is no way to determine whether you actually intended to hard-assign a surface construction or leave it as inherited.

This matters because conceptually you have to be thinking about what owns/drives the constructions. In this NFP, to reduce the scope we aren't proposing to have the ability to assign one at BuildingStory/SpaceType, but you still have Building and Space Levels. One example could be a 3 story Spaces of type "Office", and one-below ground "Basement" Space. You'd start by maybe assigning one DefaultConstructionSet at the Building level, which would have all constructions for the Office, and specialize with another DefaultConstructionSet, partially filled (most constructions aren't specified so they would still resolve to the Building level one, but you might specify for eg Exterior Wall construction, Exterior Floor construction), for the Basement Space.
There's zero way to accurately reconstruct this information from an IDF with all construction names being filled in: you can envision trying to be smart and detect common patterns but:

  • would you actually want that? Seems like you personally would prefer hard-assigning everything, which has to be respected
  • during the course of your modeling, it's possible that you might temporarily try to change the exterior wall construction of the Basement to be the same as the Building level, and now that information is completely gone

Side note: Speaking about UIs, using the OpenStudio SDK you have methods to check if the construction is hard-assigned or inherited, and what it resolves to. And it wouldn't be rocket science to implement the same yourself in python if need be.
You can then let the user always see the construction that's going to be used even if the field is blank, and display it differently whether it's inherited or not (The OpenStudioApplication for eg has inherited values in green).

image

And you also have methods to hard-assign the inherited constructions, so you can run a one-liner python script (which can be run using the embedded python interprerter) to take an IDF with inheritance and "fill" up the Construction Name fields.

openstudio -c "m = openstudio.epmodel.Model.load('in.idf'); [s.hardApplyConstructions() for s in m.getSpaces()]; m.save('in.idf')"

@jmarrec jmarrec added DoNotPublish Includes changes that shouldn't be reported in the changelog NewFeature Includes code to add a new feature to EnergyPlus labels Jul 6, 2026
@jmarrec
jmarrec force-pushed the NFP-DefaultConstructionSet-nfp-only branch from 8c955ca to d9b75e1 Compare July 6, 2026 08:58
@jasondegraw

Copy link
Copy Markdown
Member

I won't try to speak for @Myoldmopar, but I share his concerns. I'm not sure I like the invisible object linkage (for lack of better terminology) that this introduces, but there's precedent for that (in AirflowNetwork, so no stones shall be thrown by me). I've said this on at least one call, so apologies for being the broken record, but there needs to be more focus on the benefits for EnergyPlus users. In my opinion, the document does not present a very compelling case that this benefits all EnergyPlus users. The first three advantages appear to me to be three different angles on reduction of repetition (where perhaps that repetition could be viewed as being explicit) and the last one is nice, but not a benefit to all EnergyPlus users. Finally, I agree with @JasonGlazer about possibly reconsidering how defaults are handled. If we're going to do this, we probably should take that extra precaution.

@jmarrec

jmarrec commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

IMHO, the use case for EnergyPlus users that opt-in to this feature is pretty compelling.

You could have a "library" IDF with a DefaultConstructionSet and the child constructions (eg: one for 189.1-2009 - CZ4 - Office) and you could drag that into any IDF (or just start by creating one) and just focus on producing your BuildingSurfaces and that's it. You don't need to manually figure out whether a given Building Surface is an Exterior Wall or a Ground Floor to determine what construction you need to hard-assign yourself (and risk messing it up without having written an algorithm to do so yourself). The gain in terms of time and pain is substantial.


Most people - I would assume - are probably using some kind of UI to create geometry, or a script that could turn a floor plan (2D) + floor height to 3D Spaces, as opposed to writing vertices by hand (if you do that, then the time to assign a construction is probably small compared to the time spent figuring out vertices and their order manually unless it's a shoebox - and again this is purely opt-in).

In openstudio-sketchup-plugin, without this feature, you'd have to click on each on surface to hard-assign a construction after you've created your 3D geometry.
I haven't used Euclid (which operates on IDF directly) in a long time but I would assume the same still applies: while you can detect the Surface Type and boundary condition type via surface matching, the step to assign a construction is most likely still manual: click, assign, rinse and repeat. Or do it in your generated IDF file which is way worse unless you've named your surfaces descriptively beforehand (manually again...) as looking at vertices isn't self-explanatory for their position and orientation, and you need to combine that with their Surface Type and Outside Boundary Condition to determine what the construction should be.

@jasondegraw

Copy link
Copy Markdown
Member

That seems to me to be restatement(s) of the "reduction of repetition" argument that's already in the NFP. Computers are generally pretty good at repetition and the similar case that I am familiar with (AFN's reference crack conditions) still trips people up even though it's pretty well documented (I hope) and fairly well considered (in my opinion, but not everyone agrees). This situation is much wider in scope and potentially impacts a lot more users at more stages of model development.

So if it comes down to just "reduction of repetition" versus "explicitness", then I think I land on "explicitness" (i.e., we should pass on this feature) unless we back up, consider what this means for default handling in general, and rethink how this is implemented.

@mitchute

mitchute commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Thanks everyone for their reviews and the discussion here. If I were to make an attempt at summarizing where everyone is at, I think I see the following. Please correct me if I’ve misstated anything:

  • @RKStrand - OK with enabling better alignment with the OS schema, provided we don’t break existing users/workflows.

  • @JasonGlazer - not opposed to the concept, but there may still be unresolved questions around the structure, scope, and some implementation details.

  • TRANE - noted that they do something similar in their UI.

  • @Myoldmopar / @jasondegraw - unconvinced of the need, would like to see less emphasis on reduction of repetition, and would like to see a clearer benefit to E+ directly.

Multiple people stated that the added implicitness is a downside, suggesting that this is creating an implicit object linkage between a blank construction field and the resolved construction. More specifically, users would now need to know which variant of surface they are using, what boundary condition applies, and how that resolves through the Space/Building default construction set. Implicit object linkage is not unprecedented in E+, but it is also not common.

Multiple people also stated that we should first consider/resolve how we should be handling defaults in general before tackling this.

Counterpoints by @kbenne / @jmarrec:

  • If you prefer to hard-code everything, you can keep doing so. The only models with changed behavior are the ones opting into the defaulting capability.

  • This enables round-tripping from OS -> E+ -> OS, since during forward translation you currently lose the knowledge of which constructions came through defaults and which came through manual inputs.

  • This enables users to develop libraries for specific building vintages, types, locations, etc. that they can “just” load, let surfaces pick up the valid construction, and move on. No more manually specifying the construction for each individual surface.

@mitchute comments:

  • DOE asked for better OS-E+ schema alignment, and that ain’t nothing, so we have to acknowledge the ask and work toward it.

  • I agree that the benefits are a bit one-sided, i.e. this benefits OS users more than direct E+ users. But we’re keeping backwards compatibility, so if you don’t want to use it, you don’t have to.

  • I agree that this makes manually auditing the IDF a bit more difficult. However, the resolved surface-construction connections are already reported via our existing tabular reports, so one (me) would think they should be looking there first/anyway, since 1) it’s a compact summary table and easier to interpret, and 2) it’s faster than sifting through the IDF. Important caveat: those reports show the resolved construction, not whether it was hard-assigned or inherited/defaulted, and that table might need to be augmented with that information.

  • Enabling OS -> E+ -> OS round-tripping has been a key deficiency for a long time, and allowing a concession on this project's part to help enable that seems like a net-positive that enables more/better use of E+ via OS. I do acknowledge that this project will be supporting any issues with this new feature into the future.

  • Asking for a larger discussion around default handling is a fair point to request, but at the moment I don’t know what we would be discussing that isn’t an abstract concept. This, at least, is a concrete thing we can grasp onto, which helps pin down the specific issues. Right now, to me, the implicit object connection seems like the key sticking point. As was acknowledged, that’s not totally unprecedented, but it is also not common; however, users are generally very comfortable with E+ setting many default values. Regardless, I don't feel this would be too much of stretch, provided it's all very well documented. If we can get consensus on this point, maybe we can punt a larger default behavior discussion until the application presents itself, like is happening here.

My vote is to approve, but I acknowledge we may need further discussion on how to handle defaults and more iteration on the specific implementation points.

@jasondegraw

Copy link
Copy Markdown
Member

@mitchute Apologies, the first version of this comment got eaten by a power outage, so I had to write it again. The first version was better.

No, you misunderstand. I am taking no position on the need, what I'd like to see is an NFP that makes a case for the feature on its own merits, and it currently falls well short. The NFP claims that this feature "offers several advantages", and then lists out three variations of "reduction of repetition" and an out-of-scope alignment concern.

  • Advantages: The use of this word makes things relative, and I guess we're supposed to infer that it's the current situation in E+ that we're comparing to. I disagree most vehemently with that, it isn't better, it's just different. Much has been made in the comments about this feature being opt-in, but that's not what's in the NFP.
  • Reduction of repetition: I'm not looking for "less emphasis on reduction of repetition", in fact I'm looking for the opposite. If the case for adoption is "reduction of repetition", and at this point that appears to me to be the case, then that needs to be the case that's made. But that's not what's in the NFP.
  • Alignment: Your reframing of this part is better stated that what's in the NFP, but unfortunately for everyone that's not what's in the NFP.

If merged as-is, the NFP sets a bad precedent. What I'd want to see:

  1. Fix the NFP issues by removing the relative framing (remove advantage(s)), go with "reduction of repetition" as the justification, include opt-in as part of the justification, and delete alignment. It'd also be good to include a summary of the discussion in the "email and conference call section", these comments really aren't part of the permanent record, the NFP is.
  2. Let's discuss the default handling (on an iteration call, the technicalities call, a separate call, whatever). It doesn't necessarily need to be a long discussion, but it needs to happen and it's not abstract. While there's still code with manual default management around, new code should be using the convenience functions that puts that somewhat behind the scenes in the input processor. This is going the other way, moving default handling out to object code, which has implications well beyond this feature (input processing order, etc.). Given the team changes over the last year, we all need to be more aware of this aspect of E+.

kbenne added 3 commits July 22, 2026 11:30
Present the feature as an optional way to reduce repeated construction assignments while acknowledging the tradeoff in local explicitness. State that explicit Construction Name values remain authoritative and that models may mix explicit and inherited assignments.

Move OpenStudio and EnergyPlus alignment into the recorded review context instead of using it as the native feature justification. Explain why multiple named sets and Space scope are needed for partial specialization and Building fallback. Add a narrow requirement for the existing Envelope Summary to identify whether each resolved assignment came from an explicit value, Space, or Building.
@mitchute

Copy link
Copy Markdown
Collaborator

Thanks everyone for all the good discussion here. As discussed on the call yesterday, this is very close. @kbenne IIRC there were a few remaining comments to address, and I took a to-do for myself to work up a more comprehensive plan on our proposed approach to default handling in general. If anyone has anything other open comments or questions, please post them ASAP.

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

Labels

DoNotPublish Includes changes that shouldn't be reported in the changelog NewFeature Includes code to add a new feature to EnergyPlus

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants