Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
69 changes: 67 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,15 @@ profile/

*.sublime-workspace

# Qt-generated files
src/openstudio_lib/moc_*.cpp
# Qt moc/rcc-generated files, wherever CMake drops them in the tree
moc_*.cpp
moc_*.cpp_parameters
qrc_*.cpp
*.qrc.depends
**/__/
*_autogen/
.lupdate/
.qt/

*.sublime-project
cmake-build-debug
Expand All @@ -45,3 +52,61 @@ clang_format.patch
conan-cache
.ccache
CMakeUserPresets.json

# This repo is built in-place at the repo root (not an out-of-source build/ dir), so
# CMake/Conan/MSBuild drop generated files alongside tracked source. Ignore those.
/CMakeCache.txt
/CMakePresets.json
/CPackConfig.cmake
/CPackSourceConfig.cmake
/cmakedeps_macros.cmake
/conan_toolchain.cmake
/conanbuild.bat
/conanbuildenv-*.bat
/conandeps_legacy.cmake
/conanrun.bat
/conanrunenv-*.bat
/deactivate_conanbuild.bat
/deactivate_conanrun.bat
/*-Target-release.cmake
/*-release-x86_64-data.cmake
/*Config.cmake
/*ConfigVersion.cmake
/*Targets.cmake
/*-config.cmake
/*-config-version.cmake
/Find*.cmake
/module-*.cmake
/get_output_vars.rb
/output_vars_list.txt
/aqtinstall.log
/build_output.txt
/Products/
/_deps/
/OpenStudio-3.11.0/

# CMake-generated Visual Studio projects/solution, wherever they land
CMakeFiles/
cmake_install.cmake
*.vcxproj
*.vcxproj.filters
*.sln

# Compiled translation binaries (built from the tracked .ts sources)
translations/*.qm

__pycache__/

# EnergyPlus local-docs workflow output (see ENERGYPLUS_DOCS_WORKFLOW.md, itself gitignored)
/ENERGYPLUS_DOCS_WORKFLOW.md
/EnergyPlus/
/EnergyPlusDocsArchive/

# configure_file()-generated from tracked .in templates; AnalyticsHelperSecrets.hxx in
# particular is populated with real secret values at configure time -- never commit it.
src/openstudio_lib/AnalyticsHelperSecrets.hxx
src/openstudio_lib/AnalyticsHelperSecrets.hxx.tmp
src/openstudio_app/AboutBox.hpp
src/model_editor/AboutBox.hpp
src/openstudio_app/OpenStudioApp.rc
src/utilities/OpenStudioApplicationPathHelpers.cxx
58 changes: 58 additions & 0 deletions src/openstudio_app/Resources/default/hvac_library.osm
Original file line number Diff line number Diff line change
Expand Up @@ -6999,6 +6999,64 @@ OS:AirLoopHVAC:UnitarySystem,
, !- Heat Recovery Water Outlet Node Name
; !- Design Specification Multispeed Object Name

OS:Coil:Heating:Desuperheater,
{bdb03443-be0a-4953-8eb4-e6014bbced83}, !- Handle
Desuperheater Reheat Coil, !- Name
{9f54092d-a4a8-41b8-a381-c4c332ecb843}, !- Availability Schedule Name
0.25, !- Heat Reclaim Recovery Efficiency
, !- Air Inlet Node Name
, !- Air Outlet Node Name
{983b9c20-5a9e-49eb-9770-5c1545cc6b65}, !- Heating Source Name
0; !- On Cycle Parasitic Electric Load {W}

OS:AirLoopHVAC:UnitarySystem,
{dbc42aea-40d9-42a6-9016-87cc16813b11}, !- Handle
Unitary - Single Speed DX cooling - Elec heat - CAV - Hotgas reheat, !- Name
Load, !- Control Type
, !- Controlling Zone or Thermostat Location
CoolReheat, !- Dehumidification Control Type
{9f54092d-a4a8-41b8-a381-c4c332ecb843}, !- Availability Schedule Name
, !- Air Inlet Node Name
, !- Air Outlet Node Name
{0c016d27-85cb-4254-8b85-9a16c4586de5}, !- Supply Fan Name
BlowThrough, !- Fan Placement
{9f54092d-a4a8-41b8-a381-c4c332ecb843}, !- Supply Air Fan Operating Mode Schedule Name
{ca3b3fed-58b0-4f64-85f9-257f45d033a5}, !- Heating Coil Name
1, !- DX Heating Coil Sizing Ratio
{983b9c20-5a9e-49eb-9770-5c1545cc6b65}, !- Cooling Coil Name
No, !- Use DOAS DX Cooling Coil
2, !- DOAS DX Cooling Coil Leaving Minimum Air Temperature {C}
LatentOrSensibleLoadControl, !- Latent Load Control
{bdb03443-be0a-4953-8eb4-e6014bbced83}, !- Supplemental Heating Coil Name
SupplyAirFlowRate, !- Supply Air Flow Rate Method During Cooling Operation
autosize, !- Supply Air Flow Rate During Cooling Operation {m3/s}
, !- Supply Air Flow Rate Per Floor Area During Cooling Operation {m3/s-m2}
, !- Fraction of Autosized Design Cooling Supply Air Flow Rate
, !- Design Supply Air Flow Rate Per Unit of Capacity During Cooling Operation {m3/s-W}
SupplyAirFlowRate, !- Supply Air Flow Rate Method During Heating Operation
autosize, !- Supply Air Flow Rate During Heating Operation {m3/s}
, !- Supply Air Flow Rate Per Floor Area during Heating Operation {m3/s-m2}
, !- Fraction of Autosized Design Heating Supply Air Flow Rate
, !- Design Supply Air Flow Rate Per Unit of Capacity During Heating Operation {m3/s-W}
None, !- Supply Air Flow Rate Method When No Cooling or Heating is Required
, !- Supply Air Flow Rate When No Cooling or Heating is Required {m3/s}
, !- Supply Air Flow Rate Per Floor Area When No Cooling or Heating is Required {m3/s-m2}
, !- Fraction of Autosized Design Cooling Supply Air Flow Rate When No Cooling or Heating is Required
, !- Fraction of Autosized Design Heating Supply Air Flow Rate When No Cooling or Heating is Required
, !- Design Supply Air Flow Rate Per Unit of Capacity During Cooling Operation When No Cooling or Heating is Required {m3/s-W}
, !- Design Supply Air Flow Rate Per Unit of Capacity During Heating Operation When No Cooling or Heating is Required {m3/s-W}
Yes, !- No Load Supply Air Flow Rate Control Set To Low Speed
80, !- Maximum Supply Air Temperature {C}
21, !- Maximum Outdoor Dry-Bulb Temperature for Supplemental Heater Operation {C}
, !- Outdoor Dry-Bulb Temperature Sensor Node Name
0, !- Ancilliary On-Cycle Electric Power {W}
0, !- Ancilliary Off-Cycle Electric Power {W}
, !- Design Heat Recovery Water Flow Rate {m3/s}
80, !- Maximum Temperature for Heat Recovery {C}
, !- Heat Recovery Water Inlet Node Name
, !- Heat Recovery Water Outlet Node Name
; !- Design Specification Multispeed Object Name

OS:Fan:OnOff,
{e803e540-d848-409c-9bad-0c0dc9c7b50a}, !- Handle
Fan On Off 14, !- Name
Expand Down
70 changes: 70 additions & 0 deletions src/openstudio_lib/HVACSystemsController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@
#include <openstudio/model/CoilHeatingElectric_Impl.hpp>
#include <openstudio/model/CoilHeatingWater.hpp>
#include <openstudio/model/CoilHeatingWater_Impl.hpp>
#include <openstudio/model/ParentObject.hpp>
#include <openstudio/model/ParentObject_Impl.hpp>
#include <openstudio/model/Model.hpp>
#include <openstudio/model/Model_Impl.hpp>
#include <openstudio/model/Node.hpp>
Expand Down Expand Up @@ -126,6 +128,8 @@
#include <openstudio/utilities/core/Compare.hpp>
#include <openstudio/utilities/idd/OS_ComponentData_FieldEnums.hxx>

#include <map>

#include <QMessageBox>
#include <QTimer>
#include <QPushButton>
Expand Down Expand Up @@ -519,6 +523,69 @@ void HVACLayoutController::addLibraryObjectToTopLevel(const OSItemId& itemId) {
message.exec();
}

namespace {
// ModelObject::clone() clones each child individually and reattaches it via setParent(), so
// true parent-child edges are correctly remapped to point within the new subtree. But children
// are cloned one at a time rather than as a batch sharing a single old->new handle table, so any
// *lateral* object-list reference between two siblings in the cloned subtree (e.g.
// CoilHeatingDesuperheater::heatingSource() pointing at a sibling cooling coil, or a
// SetpointManager's node references) is left pointing at the original objects instead of their
// clones. The functions below fix that up generically, for any object type, rather than special
// casing each lateral-reference field as it's discovered.

// Walks `original` and `clone` in parallel -- children() order is deterministic and preserved by
// clone() -- building a map from each original object's handle to its corresponding clone.
void buildCloneHandleMap(const model::ModelObject& original, const model::ModelObject& clone,
std::map<Handle, model::ModelObject>& handleMap) {
handleMap.emplace(original.handle(), clone);

boost::optional<model::ParentObject> originalParent = original.optionalCast<model::ParentObject>();
boost::optional<model::ParentObject> cloneParent = clone.optionalCast<model::ParentObject>();
if (originalParent && cloneParent) {
std::vector<model::ModelObject> originalChildren = originalParent->children();
std::vector<model::ModelObject> cloneChildren = cloneParent->children();
if (originalChildren.size() == cloneChildren.size()) {
for (size_t i = 0; i < originalChildren.size(); ++i) {
buildCloneHandleMap(originalChildren[i], cloneChildren[i], handleMap);
}
}
}
}

// Rewrites every object-list field on clonedObject (and recursively its children) that still
// points at an object handleMap has a clone for, to point at that clone instead.
void remapLateralReferences(model::ModelObject clonedObject, const std::map<Handle, model::ModelObject>& handleMap) {
IddObject iddObject = clonedObject.iddObject();
for (unsigned index = 0; index < clonedObject.numFields(); ++index) {
if (iddObject.objectLists(index).empty()) {
continue;
}
boost::optional<WorkspaceObject> target = clonedObject.getTarget(index);
if (!target) {
continue;
}
auto it = handleMap.find(target->handle());
if (it != handleMap.end() && it->second.handle() != target->handle()) {
clonedObject.setPointer(index, it->second.handle());
}
}

if (boost::optional<model::ParentObject> parent = clonedObject.optionalCast<model::ParentObject>()) {
for (const model::ModelObject& child : parent->children()) {
remapLateralReferences(child, handleMap);
}
}
}

// `original` is the subtree that was cloned; `clonedObject` is its clone. Re-links any lateral
// reference in the clone that still points into the original subtree.
void fixupClonedReferences(const model::ModelObject& original, model::ModelObject clonedObject) {
std::map<Handle, model::ModelObject> handleMap;
buildCloneHandleMap(original, clonedObject, handleMap);
remapLateralReferences(clonedObject, handleMap);
}
} // namespace

void HVACLayoutController::addLibraryObjectToModelNode(const OSItemId& itemId, model::HVACComponent& comp) {
model::OptionalModelObject object;
bool remove = false;
Expand All @@ -527,7 +594,9 @@ void HVACLayoutController::addLibraryObjectToModelNode(const OSItemId& itemId, m
object = doc->getModelObject(itemId);
if (object) {
if (!doc->fromModel(itemId)) {
model::ModelObject original = object.get();
object = object->clone(comp.model());
fixupClonedReferences(original, object.get());
remove = true;
}
}
Expand Down Expand Up @@ -893,6 +962,7 @@ void HVACSystemsController::onCopySystemClicked() {
auto loop = currentLoop();
if (loop) {
auto clone = loop->clone(loop->model());
fixupClonedReferences(loop.get(), clone);
setCurrentHandle(toQString(clone.handle()));
}
}
Expand Down
Loading