diff --git a/energyplus_coroutine/variables.cpp b/energyplus_coroutine/variables.cpp index 29f19342..566f0168 100644 --- a/energyplus_coroutine/variables.cpp +++ b/energyplus_coroutine/variables.cpp @@ -925,431 +925,405 @@ namespace other { energyplus::ResetActuator(energyplus_data, actuator_handle_.get(energyplus_data)); } } - // - // void Schedule::create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables) - //{ - // const auto schedules = input.spawnjson.value("model", json::object()).value("schedules", - // std::vector(0)); int value_reference = variables.size(); // NOLINT - // - // // Schedules values are set using the EnergyPlus actuator - // // - // // Since actuators require an EnergyPlus object type and name, - // // the first step is to build a map of schedules names and types. - // std::map schedule_type_map; - // - // for (const auto &type : supportedScheduleTypes) { - // if (input.jsonidf.contains(type)) { - // for (const auto &schedule : input.jsonidf[type].items()) { - // schedule_type_map[schedule.key()] = type; - // } - // } - // } - // - // // Use the type map to find the schedule type, - // // then find the actuator handle, - // // and finally create a new Schedule variable. - // for (const auto &schedule : schedules) { - // const auto idf_name = schedule.value("name", ""); - // const auto name = schedule.value("fmiName", ""); - // - // const auto type = schedule_type_map.find(idf_name); - // if (type != std::end(schedule_type_map)) { - // const auto handle = energyplus::ActuatorHandle(energyplus_data, type->second, "Schedule Value", - // idf_name); variables.push_back(std::unique_ptr(new Schedule(name, handle, value_reference))); - // value_reference++; - // } - // } - // } - // - // Schedule::Schedule(std::string_view name, int handle, int value_reference) // NOLINT - // : InputVariable(name, value_reference, units::UnitType::one, units::UnitType::one), handle_(handle) - //{ - // metadata_.set_name("ScalarVariable"); - // metadata_.append_attribute("name") = name_.c_str(); - // metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); - // metadata_.append_attribute("description") = "Schedule"; - // metadata_.append_attribute("causality") = "input"; - // metadata_.append_attribute("variability") = "continuous"; - // - // auto real = metadata_.append_child("Real"); - // real.append_attribute("unit") = units::toString(mo_unit_).c_str(); - // } - // - // void Schedule::Update(EnergyPlus::EnergyPlusData &energyplus_data) - //{ - // if (value_) { - // energyplus::SetActuatorValue(energyplus_data, handle_, *value_); - // } - // } - // + + void Schedule::create(const Input &input, Variables &variables) + { + const auto schedules = input.spawnjson.value("model", json::object()).value("schedules", std::vector(0)); + + // Schedules values are set using the EnergyPlus actuator + // + // Since actuators require an EnergyPlus object type and name, + // the first step is to build a map of schedules names and types. + std::map schedule_type_map; + + for (const auto &type : supportedScheduleTypes) { + if (input.jsonidf.contains(type)) { + for (const auto &schedule : input.jsonidf[type].items()) { + schedule_type_map[schedule.key()] = type; + } + } + } + + // Use the type map to find the schedule type, + // then find the actuator handle, + // and finally create a new Schedule variable. + for (const auto &schedule : schedules) { + const auto idf_name = schedule.value("name", ""); + const auto name = schedule.value("fmiName", ""); + + const auto type = schedule_type_map.find(idf_name); + if (type != std::end(schedule_type_map)) { + // const auto handle = energyplus::ActuatorHandle(energyplus_data, type->second, "Schedule Value", idf_name); + Schedule(variables, name, idf_name, type->second, "Schedule Value"); + } + } + } + + Schedule::Schedule(Variables &variables, + const std::string_view name, // NOLINT + const std::string_view component_name, + const std::string_view component_type, + const std::string_view component_controltype) + : InputVariable(variables, name, units::UnitType::one, units::UnitType::one), component_name_(component_name), + component_type_(component_type), component_controltype_(component_controltype), + handle_([this](EnergyPlus::EnergyPlusData &data) { + return energyplus::ActuatorHandle(data, component_type_, component_controltype_, component_name_); + }) + { + metadata_.set_name("ScalarVariable"); + metadata_.append_attribute("name") = name_.c_str(); + metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); + metadata_.append_attribute("description") = "Schedule"; + metadata_.append_attribute("causality") = "input"; + metadata_.append_attribute("variability") = "continuous"; + + auto real = metadata_.append_child("Real"); + real.append_attribute("unit") = units::toString(mo_unit_).c_str(); + } + + void Schedule::Update(EnergyPlus::EnergyPlusData &energyplus_data) + { + if (value_) { + energyplus::SetActuatorValue(energyplus_data, handle_.get(energyplus_data), *value_); + } + } } // namespace other -// -// namespace surface { -// -// void A::create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables) -// { -// const auto surfaces = input.spawnjson.value("model", json::object()).value("zoneSurfaces", std::vector(0)); -// int value_reference = variables.size(); // NOLINT -// -// for (const auto &surface : surfaces) { -// const auto surface_name = surface.value("name", ""); -// const auto surface_num = energyplus::SurfaceNum(energyplus_data, surface_name); -// -// variables.push_back(std::unique_ptr(new A(surface_name, surface_num, value_reference))); -// value_reference++; -// } -// } -// -// A::A(std::string_view surface_name, int surface_num, int value_reference) // NOLINT -// : OutputVariable(std::string(surface_name) + "_A", value_reference, units::UnitType::m2, units::UnitType::m2), -// surface_name_(surface_name), surface_num_(surface_num) -// { -// metadata_.set_name("ScalarVariable"); -// metadata_.append_attribute("name") = name_.c_str(); -// metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); -// metadata_.append_attribute("description") = "Area of the surface that is exposed to the thermal zone"; -// metadata_.append_attribute("causality") = "calculatedParameter"; -// metadata_.append_attribute("variability") = "fixed"; -// metadata_.append_attribute("initial") = "calculated"; -// -// auto real = metadata_.append_child("Real"); -// real.append_attribute("quantity") = "Area"; -// real.append_attribute("relativeQuantity") = "false"; -// real.append_attribute("unit") = units::toString(mo_unit_).c_str(); -// } -// -// void A::Update(EnergyPlus::EnergyPlusData &energyplus_data) -// { -// SetValue(energyplus::SurfaceArea(energyplus_data, surface_num_), spawn::units::UnitSystem::EP); -// } -// -// void QFlow::create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables) -// { -// const auto surfaces = input.spawnjson.value("model", json::object()).value("zoneSurfaces", std::vector(0)); -// int value_reference = variables.size(); // NOLINT -// -// for (const auto &surface : surfaces) { -// const auto surface_name = surface.value("name", ""); -// const auto surface_num = energyplus::SurfaceNum(energyplus_data, surface_name); -// -// variables.push_back(std::unique_ptr(new QFlow(surface_name, surface_num, value_reference))); -// value_reference++; -// } -// } -// -// QFlow::QFlow(std::string_view surface_name, int surface_num, int value_reference) // NOLINT -// : OutputVariable(std::string(surface_name) + "_Q_flow", value_reference, units::UnitType::W, -// units::UnitType::W), -// surface_name_(surface_name), surface_num_(surface_num) -// { -// metadata_.set_name("ScalarVariable"); -// metadata_.append_attribute("name") = name_.c_str(); -// metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); -// metadata_.append_attribute("description") = -// "Net heat flow rate from the thermal zone to the surface, consisting of convective heat flow, absorbed " -// "solar radiation, absorbed infrared radiation minus emitted infrared radiation."; -// metadata_.append_attribute("causality") = "output"; -// metadata_.append_attribute("variability") = "continuous"; -// metadata_.append_attribute("initial") = "calculated"; -// -// auto real = metadata_.append_child("Real"); -// real.append_attribute("quantity") = "Power"; -// real.append_attribute("relativeQuantity") = "false"; -// real.append_attribute("unit") = units::toString(mo_unit_).c_str(); -// } -// -// void QFlow::Update(EnergyPlus::EnergyPlusData &energyplus_data) -// { -// SetValue(energyplus::SurfaceInsideHeatFlow(energyplus_data, surface_num_), spawn::units::UnitSystem::EP); -// } -// -// void T::create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables) -// { -// const auto surfaces = input.spawnjson.value("model", json::object()).value("zoneSurfaces", std::vector(0)); -// int value_reference = variables.size(); // NOLINT -// -// const std::string actuator_type("Surface"); -// const std::string actuator_controltype("Surface Inside Temperature"); -// -// for (const auto &surface : surfaces) { -// const auto surface_name = surface.value("name", ""); -// -// const auto handle = -// energyplus::ActuatorHandle(energyplus_data, actuator_type, actuator_controltype, surface_name); -// -// variables.push_back(std::unique_ptr(new T(surface_name, handle, value_reference))); -// value_reference++; -// } -// } -// -// T::T(std::string_view surface_name, int surface_num_, int value_reference) // NOLINT -// : InputVariable(std::string(surface_name) + "_T", value_reference, units::UnitType::C, units::UnitType::K), -// surface_num_(surface_num_) -// { -// metadata_.set_name("ScalarVariable"); -// metadata_.append_attribute("name") = name_.c_str(); -// metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); -// metadata_.append_attribute("description") = "Temperature of the surface."; -// metadata_.append_attribute("causality") = "input"; -// metadata_.append_attribute("variability") = "continuous"; -// -// auto real = metadata_.append_child("Real"); -// real.append_attribute("quantity") = "ThermodynamicTemperature"; -// real.append_attribute("relativeQuantity") = "false"; -// real.append_attribute("unit") = units::toString(mo_unit_).c_str(); -// } -// -// void T::Update(EnergyPlus::EnergyPlusData &energyplus_data) -// { -// if (value_) { -// energyplus::SetInsideSurfaceTemperature(energyplus_data, surface_num_, *value_); -// } -// } -// } // namespace surface -// -// namespace construction { -// void A::create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables) -// { -// const auto surfaces = -// input.spawnjson.value("model", json::object()).value("buildingSurfaceDetailed", std::vector(0)); -// int value_reference = variables.size(); // NOLINT -// -// for (const auto &surface : surfaces) { -// const auto surface_name = surface.value("name", ""); -// const auto surface_num = energyplus::SurfaceNum(energyplus_data, surface_name); -// -// variables.push_back(std::unique_ptr(new A(surface_name, surface_num, value_reference))); -// value_reference++; -// } -// } -// -// A::A(std::string_view surface_name, int surface_num, int value_reference) // NOLINT -// : OutputVariable(std::string(surface_name) + "_A", value_reference, units::UnitType::m2, units::UnitType::m2), -// surface_name_(surface_name), surface_num_(surface_num) -// { -// metadata_.set_name("ScalarVariable"); -// metadata_.append_attribute("name") = name_.c_str(); -// metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); -// metadata_.append_attribute("description") = "Area of the surface that is exposed to the thermal zone"; -// metadata_.append_attribute("causality") = "calculatedParameter"; -// metadata_.append_attribute("variability") = "fixed"; -// metadata_.append_attribute("initial") = "calculated"; -// -// auto real = metadata_.append_child("Real"); -// real.append_attribute("quantity") = "Area"; -// real.append_attribute("relativeQuantity") = "false"; -// real.append_attribute("unit") = units::toString(mo_unit_).c_str(); -// } -// -// void A::Update(EnergyPlus::EnergyPlusData &energyplus_data) -// { -// SetValue(energyplus::SurfaceArea(energyplus_data, surface_num_), spawn::units::UnitSystem::EP); -// } -// -// void QFrontFlow::create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables) -// { -// const auto surfaces = -// input.spawnjson.value("model", json::object()).value("buildingSurfaceDetailed", std::vector(0)); -// int value_reference = variables.size(); // NOLINT -// -// for (const auto &surface : surfaces) { -// const auto surface_name = surface.value("name", ""); -// const auto surface_num = energyplus::SurfaceNum(energyplus_data, surface_name); -// -// variables.push_back(std::unique_ptr(new QFrontFlow(surface_name, surface_num, value_reference))); -// value_reference++; -// } -// } -// -// QFrontFlow::QFrontFlow(std::string_view surface_name, int surface_num, int value_reference) // NOLINT -// : OutputVariable( -// std::string(surface_name) + "_QFront_flow", value_reference, units::UnitType::W, units::UnitType::W), -// surface_name_(surface_name), surface_num_(surface_num) -// { -// metadata_.set_name("ScalarVariable"); -// metadata_.append_attribute("name") = name_.c_str(); -// metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); -// metadata_.append_attribute("description") = -// "Net heat flow rate from the thermal zone to the front-facing surface, consisting of convective heat flow, " -// "absorbed solar radiation, absorbed infrared radiation minus emitted infrared radiation."; -// metadata_.append_attribute("causality") = "output"; -// metadata_.append_attribute("variability") = "continuous"; -// metadata_.append_attribute("initial") = "calculated"; -// -// auto real = metadata_.append_child("Real"); -// real.append_attribute("quantity") = "Power"; -// real.append_attribute("relativeQuantity") = "false"; -// real.append_attribute("unit") = units::toString(mo_unit_).c_str(); -// } -// -// void QFrontFlow::Update(EnergyPlus::EnergyPlusData &energyplus_data) -// { -// SetValue(energyplus::SurfaceInsideHeatFlow(energyplus_data, surface_num_), spawn::units::UnitSystem::EP); -// } -// -// void QBackFlow::create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables) -// { -// const auto surfaces = -// input.spawnjson.value("model", json::object()).value("buildingSurfaceDetailed", std::vector(0)); -// int value_reference = variables.size(); // NOLINT -// -// for (const auto &surface : surfaces) { -// const auto surface_name = surface.value("name", ""); -// const auto surface_num = energyplus::SurfaceNum(energyplus_data, surface_name); -// -// variables.push_back(std::unique_ptr(new QBackFlow(surface_name, surface_num, value_reference))); -// value_reference++; -// } -// } -// -// QBackFlow::QBackFlow(std::string_view surface_name, int surface_num, int value_reference) // NOLINT -// : OutputVariable( -// std::string(surface_name) + "_QBack_flow", value_reference, units::UnitType::W, units::UnitType::W), -// surface_name_(surface_name), surface_num_(surface_num) -// { -// metadata_.set_name("ScalarVariable"); -// metadata_.append_attribute("name") = name_.c_str(); -// metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); -// metadata_.append_attribute("description") = -// "Net heat flow rate to the back-facing surface. If coupled to another thermal zone or the outside, this " -// "consist of convective heat flow, absorbed solar radiation, absorbed infrared radiation minus emitted " -// "infrared radiation. If coupled to the ground, this consists of the heat flow rate from the ground."; -// metadata_.append_attribute("causality") = "output"; -// metadata_.append_attribute("variability") = "continuous"; -// metadata_.append_attribute("initial") = "calculated"; -// -// auto real = metadata_.append_child("Real"); -// real.append_attribute("quantity") = "Power"; -// real.append_attribute("relativeQuantity") = "false"; -// real.append_attribute("unit") = units::toString(mo_unit_).c_str(); -// } -// -// void QBackFlow::Update(EnergyPlus::EnergyPlusData &energyplus_data) -// { -// SetValue(energyplus::SurfaceOutsideHeatFlow(energyplus_data, surface_num_), spawn::units::UnitSystem::EP); -// } -// -// void TFront::create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables) -// { -// const auto surfaces = input.spawnjson.value("model", json::object()).value("zoneSurfaces", std::vector(0)); -// int value_reference = variables.size(); // NOLINT -// -// const std::string actuator_type("Surface"); -// const std::string actuator_controltype("Surface Inside Temperature"); -// -// for (const auto &surface : surfaces) { -// const auto surface_name = surface.value("name", ""); -// int surface_num = energyplus::SurfaceNum(energyplus_data, surface_name); -// variables.push_back(std::unique_ptr(new TFront(surface_name, surface_num, value_reference))); -// value_reference++; -// } -// } -// -// TFront::TFront(std::string_view surface_name, int surface_num, int value_reference) // NOLINT -// : InputVariable(std::string(surface_name) + "_TFront", value_reference, units::UnitType::C, -// units::UnitType::K), -// surface_num_(surface_num) -// { -// metadata_.set_name("ScalarVariable"); -// metadata_.append_attribute("name") = name_.c_str(); -// metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); -// metadata_.append_attribute("description") = "Temperature of the front-facing surface."; -// metadata_.append_attribute("causality") = "input"; -// metadata_.append_attribute("variability") = "continuous"; -// -// auto real = metadata_.append_child("Real"); -// real.append_attribute("quantity") = "ThermodynamicTemperature"; -// real.append_attribute("relativeQuantity") = "false"; -// real.append_attribute("unit") = units::toString(mo_unit_).c_str(); -// } -// -// void TFront::Update(EnergyPlus::EnergyPlusData &energyplus_data) -// { -// if (value_) { -// energyplus::SetInsideSurfaceTemperature(energyplus_data, surface_num_, *value_); -// } -// } -// -// void TBack::create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables) -// { -// const auto surfaces = input.spawnjson.value("model", json::object()).value("zoneSurfaces", std::vector(0)); -// int value_reference = variables.size(); // NOLINT -// -// const std::string actuator_type("Surface"); -// const std::string actuator_controltype("Surface Outside Temperature"); -// -// for (const auto &surface : surfaces) { -// const auto surface_name = surface.value("name", ""); -// -// const auto handle = -// energyplus::ActuatorHandle(energyplus_data, actuator_type, actuator_controltype, surface_name); -// -// variables.push_back(std::unique_ptr(new TBack(surface_name, handle, value_reference))); -// value_reference++; -// } -// } -// -// TBack::TBack(std::string_view surface_name, int surface_num, int value_reference) // NOLINT -// : InputVariable(std::string(surface_name) + "_TBack", value_reference, units::UnitType::C, units::UnitType::K), -// surface_num_(surface_num) -// { -// metadata_.set_name("ScalarVariable"); -// metadata_.append_attribute("name") = name_.c_str(); -// metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); -// metadata_.append_attribute("description") = "Temperature of the back-facing surface."; -// metadata_.append_attribute("causality") = "input"; -// metadata_.append_attribute("variability") = "continuous"; -// -// auto real = metadata_.append_child("Real"); -// real.append_attribute("quantity") = "ThermodynamicTemperature"; -// real.append_attribute("relativeQuantity") = "false"; -// real.append_attribute("unit") = units::toString(mo_unit_).c_str(); -// } -// -// void TBack::Update(EnergyPlus::EnergyPlusData &energyplus_data) -// { -// if (value_) { -// energyplus::SetOutsideSurfaceTemperature(energyplus_data, surface_num_, *value_); -// } -// } -// } // namespace construction + +namespace surface { + void A::create(const Input &input, Variables &variables) + { + const auto surfaces = input.spawnjson.value("model", json::object()).value("zoneSurfaces", std::vector(0)); + + for (const auto &surface : surfaces) { + const auto surface_name = surface.value("name", ""); + A(variables, surface_name); + } + } + + A::A(Variables &variables, const std::string_view surface_name) + : OutputVariable(variables, std::string(surface_name) + "_A", units::UnitType::m2, units::UnitType::m2), + surface_num_( + [surface_name](EnergyPlus::EnergyPlusData &data) { return energyplus::SurfaceNum(data, surface_name); }) + { + metadata_.set_name("ScalarVariable"); + metadata_.append_attribute("name") = name_.c_str(); + metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); + metadata_.append_attribute("description") = "Area of the surface that is exposed to the thermal zone"; + metadata_.append_attribute("causality") = "calculatedParameter"; + metadata_.append_attribute("variability") = "fixed"; + metadata_.append_attribute("initial") = "calculated"; + + auto real = metadata_.append_child("Real"); + real.append_attribute("quantity") = "Area"; + real.append_attribute("relativeQuantity") = "false"; + real.append_attribute("unit") = units::toString(mo_unit_).c_str(); + } + + void A::Update(EnergyPlus::EnergyPlusData &energyplus_data) + { + SetValue(energyplus::SurfaceArea(energyplus_data, surface_num_.get(energyplus_data)), spawn::units::UnitSystem::EP); + } + + void QFlow::create(const Input &input, Variables &variables) + { + const auto surfaces = input.spawnjson.value("model", json::object()).value("zoneSurfaces", std::vector(0)); + + for (const auto &surface : surfaces) { + const auto surface_name = surface.value("name", ""); + QFlow(variables, surface_name); + } + } + + QFlow::QFlow(Variables &variables, const std::string_view surface_name) + : OutputVariable(variables, std::string(surface_name) + "_Q_flow", units::UnitType::W, units::UnitType::W), + surface_num_( + [surface_name](EnergyPlus::EnergyPlusData &data) { return energyplus::SurfaceNum(data, surface_name); }) + { + metadata_.set_name("ScalarVariable"); + metadata_.append_attribute("name") = name_.c_str(); + metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); + metadata_.append_attribute("description") = + "Net heat flow rate from the thermal zone to the surface, consisting of convective heat flow, absorbed " + "solar radiation, absorbed infrared radiation minus emitted infrared radiation."; + metadata_.append_attribute("causality") = "output"; + metadata_.append_attribute("variability") = "continuous"; + metadata_.append_attribute("initial") = "calculated"; + + auto real = metadata_.append_child("Real"); + real.append_attribute("quantity") = "Power"; + real.append_attribute("relativeQuantity") = "false"; + real.append_attribute("unit") = units::toString(mo_unit_).c_str(); + } + + void QFlow::Update(EnergyPlus::EnergyPlusData &energyplus_data) + { + SetValue(energyplus::SurfaceInsideHeatFlow(energyplus_data, surface_num_.get(energyplus_data)), + spawn::units::UnitSystem::EP); + } + + void T::create(const Input &input, Variables &variables) + { + const auto surfaces = input.spawnjson.value("model", json::object()).value("zoneSurfaces", std::vector(0)); + + const std::string actuator_type("Surface"); + const std::string actuator_controltype("Surface Inside Temperature"); + + for (const auto &surface : surfaces) { + const auto surface_name = surface.value("name", ""); + + T(variables, surface_name); + } + } + + T::T(Variables &variables, const std::string_view surface_name) + : InputVariable(variables, std::string(surface_name) + "_T", units::UnitType::C, units::UnitType::K), + surface_num_( + [surface_name](EnergyPlus::EnergyPlusData &data) { return energyplus::SurfaceNum(data, surface_name); }) + { + metadata_.set_name("ScalarVariable"); + metadata_.append_attribute("name") = name_.c_str(); + metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); + metadata_.append_attribute("description") = "Temperature of the surface."; + metadata_.append_attribute("causality") = "input"; + metadata_.append_attribute("variability") = "continuous"; + + auto real = metadata_.append_child("Real"); + real.append_attribute("quantity") = "ThermodynamicTemperature"; + real.append_attribute("relativeQuantity") = "false"; + real.append_attribute("unit") = units::toString(mo_unit_).c_str(); + } + + void T::Update(EnergyPlus::EnergyPlusData &energyplus_data) + { + if (value_) { + energyplus::SetInsideSurfaceTemperature(energyplus_data, surface_num_.get(energyplus_data), *value_); + } + } +} // namespace surface + +namespace construction { + void A::create(const Input &input, Variables &variables) + { + const auto surfaces = + input.spawnjson.value("model", json::object()).value("buildingSurfaceDetailed", std::vector(0)); + + for (const auto &surface : surfaces) { + const auto surface_name = surface.value("name", ""); + A(variables, surface_name); + } + } + + A::A(Variables &variables, const std::string_view surface_name) + : OutputVariable(variables, std::string(surface_name) + "_A", units::UnitType::m2, units::UnitType::m2), + surface_num_( + [surface_name](EnergyPlus::EnergyPlusData &data) { return energyplus::SurfaceNum(data, surface_name); }) + { + metadata_.set_name("ScalarVariable"); + metadata_.append_attribute("name") = name_.c_str(); + metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); + metadata_.append_attribute("description") = "Area of the surface that is exposed to the thermal zone"; + metadata_.append_attribute("causality") = "calculatedParameter"; + metadata_.append_attribute("variability") = "fixed"; + metadata_.append_attribute("initial") = "calculated"; + + auto real = metadata_.append_child("Real"); + real.append_attribute("quantity") = "Area"; + real.append_attribute("relativeQuantity") = "false"; + real.append_attribute("unit") = units::toString(mo_unit_).c_str(); + } + + void A::Update(EnergyPlus::EnergyPlusData &energyplus_data) + { + SetValue(energyplus::SurfaceArea(energyplus_data, surface_num_.get(energyplus_data)), spawn::units::UnitSystem::EP); + } + + void QFrontFlow::create(const Input &input, Variables &variables) + { + const auto surfaces = + input.spawnjson.value("model", json::object()).value("buildingSurfaceDetailed", std::vector(0)); + + for (const auto &surface : surfaces) { + const auto surface_name = surface.value("name", ""); + QFrontFlow(variables, surface_name); + } + } + + QFrontFlow::QFrontFlow(Variables &variables, const std::string_view surface_name) + : OutputVariable(variables, std::string(surface_name) + "_QFront_flow", units::UnitType::W, units::UnitType::W), + surface_num_( + [surface_name](EnergyPlus::EnergyPlusData &data) { return energyplus::SurfaceNum(data, surface_name); }) + { + metadata_.set_name("ScalarVariable"); + metadata_.append_attribute("name") = name_.c_str(); + metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); + metadata_.append_attribute("description") = + "Net heat flow rate from the thermal zone to the front-facing surface, consisting of convective heat flow," + " absorbed solar radiation," + " absorbed infrared radiation minus emitted infrared radiation."; + metadata_.append_attribute("causality") = "output"; + metadata_.append_attribute("variability") = "continuous"; + metadata_.append_attribute("initial") = "calculated"; + + auto real = metadata_.append_child("Real"); + real.append_attribute("quantity") = "Power"; + real.append_attribute("relativeQuantity") = "false"; + real.append_attribute("unit") = units::toString(mo_unit_).c_str(); + } + + void QFrontFlow::Update(EnergyPlus::EnergyPlusData &energyplus_data) + { + SetValue(energyplus::SurfaceInsideHeatFlow(energyplus_data, surface_num_.get(energyplus_data)), + spawn::units::UnitSystem::EP); + } + + void QBackFlow::create(const Input &input, Variables &variables) + { + const auto surfaces = + input.spawnjson.value("model", json::object()).value("buildingSurfaceDetailed", std::vector(0)); + + for (const auto &surface : surfaces) { + const auto surface_name = surface.value("name", ""); + QBackFlow(variables, surface_name); + } + } + + QBackFlow::QBackFlow(Variables &variables, std::string_view surface_name) + : OutputVariable(variables, std::string(surface_name) + "_QBack_flow", units::UnitType::W, units::UnitType::W), + surface_num_( + [surface_name](EnergyPlus::EnergyPlusData &data) { return energyplus::SurfaceNum(data, surface_name); }) + { + metadata_.set_name("ScalarVariable"); + metadata_.append_attribute("name") = name_.c_str(); + metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); + metadata_.append_attribute("description") = + "Net heat flow rate to the back-facing surface. If coupled to another thermal zone or the outside, this " + "consist of convective heat flow, absorbed solar radiation, absorbed infrared radiation minus emitted " + "infrared radiation. If coupled to the ground, this consists of the heat flow rate from the ground."; + metadata_.append_attribute("causality") = "output"; + metadata_.append_attribute("variability") = "continuous"; + metadata_.append_attribute("initial") = "calculated"; + + auto real = metadata_.append_child("Real"); + real.append_attribute("quantity") = "Power"; + real.append_attribute("relativeQuantity") = "false"; + real.append_attribute("unit") = units::toString(mo_unit_).c_str(); + } + + void QBackFlow::Update(EnergyPlus::EnergyPlusData &energyplus_data) + { + SetValue(energyplus::SurfaceOutsideHeatFlow(energyplus_data, surface_num_.get(energyplus_data)), + spawn::units::UnitSystem::EP); + } + + void TFront::create(const Input &input, Variables &variables) + { + const auto surfaces = + input.spawnjson.value("model", json::object()).value("buildingSurfaceDetailed", std::vector(0)); + + for (const auto &surface : surfaces) { + const auto surface_name = surface.value("name", ""); + TFront(variables, surface_name); + } + } + + TFront::TFront(Variables &variables, const std::string_view surface_name) + : InputVariable(variables, std::string(surface_name) + "_TFront", units::UnitType::C, units::UnitType::K), + surface_num_( + [surface_name](EnergyPlus::EnergyPlusData &data) { return energyplus::SurfaceNum(data, surface_name); }) + { + metadata_.set_name("ScalarVariable"); + metadata_.append_attribute("name") = name_.c_str(); + metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); + metadata_.append_attribute("description") = "Temperature of the front-facing surface."; + metadata_.append_attribute("causality") = "input"; + metadata_.append_attribute("variability") = "continuous"; + + auto real = metadata_.append_child("Real"); + real.append_attribute("quantity") = "ThermodynamicTemperature"; + real.append_attribute("relativeQuantity") = "false"; + real.append_attribute("unit") = units::toString(mo_unit_).c_str(); + } + + void TFront::Update(EnergyPlus::EnergyPlusData &energyplus_data) + { + if (value_) { + energyplus::SetInsideSurfaceTemperature(energyplus_data, surface_num_.get(energyplus_data), *value_); + } + } + + void TBack::create(const Input &input, Variables &variables) + { + const auto surfaces = + input.spawnjson.value("model", json::object()).value("buildingSurfaceDetailed", std::vector(0)); + + for (const auto &surface : surfaces) { + const auto surface_name = surface.value("name", ""); + TBack(variables, surface_name); + } + } + + TBack::TBack(Variables &variables, const std::string_view surface_name) + : InputVariable(variables, std::string(surface_name) + "_TBack", units::UnitType::C, units::UnitType::K), + surface_num_( + [surface_name](EnergyPlus::EnergyPlusData &data) { return energyplus::SurfaceNum(data, surface_name); }) + { + metadata_.set_name("ScalarVariable"); + metadata_.append_attribute("name") = name_.c_str(); + metadata_.append_attribute("valueReference") = std::to_string(value_reference_).c_str(); + metadata_.append_attribute("description") = "Temperature of the back-facing surface."; + metadata_.append_attribute("causality") = "input"; + metadata_.append_attribute("variability") = "continuous"; + + auto real = metadata_.append_child("Real"); + real.append_attribute("quantity") = "ThermodynamicTemperature"; + real.append_attribute("relativeQuantity") = "false"; + real.append_attribute("unit") = units::toString(mo_unit_).c_str(); + } + + void TBack::Update(EnergyPlus::EnergyPlusData &energyplus_data) + { + if (value_) { + energyplus::SetOutsideSurfaceTemperature(energyplus_data, surface_num_.get(energyplus_data), *value_); + } + } +} // namespace construction void CreateVariables(const Input &input, Variables &variables) { zone::V::create(input, variables); - // zone::AFlo::create(input, energyplus_data, variables); - // zone::MSenFac::create(input, energyplus_data, variables); - // zone::QConSenFlow::create(input, energyplus_data, variables); - // zone::QLatFlow::create(input, energyplus_data, variables); - // zone::QPeoFlow::create(input, energyplus_data, variables); - // zone::TRad::create(input, energyplus_data, variables); - // zone::QCooSenFlow::create(input, energyplus_data, variables); - // zone::QCooLatFlow::create(input, energyplus_data, variables); - // zone::TOutCoo::create(input, energyplus_data, variables); - // zone::XOutCoo::create(input, energyplus_data, variables); - // zone::MOutCooFlow::create(input, energyplus_data, variables); - // zone::TCoo::create(input, energyplus_data, variables); - // zone::QHeaFlow::create(input, energyplus_data, variables); - // zone::TOutHea::create(input, energyplus_data, variables); - // zone::XOutHea::create(input, energyplus_data, variables); - // zone::MOutHeaFlow::create(input, energyplus_data, variables); - // zone::THea::create(input, energyplus_data, variables); - // zone::MInletsFlow::create(input, energyplus_data, variables); - // zone::TAveInlet::create(input, energyplus_data, variables); - // zone::T::create(input, energyplus_data, variables); - // zone::X::create(input, energyplus_data, variables); - // zone::QGaiRadFlow::create(input, energyplus_data, variables); - // other::Sensor::create(input, energyplus_data, variables); - // other::Actuator::create(input, energyplus_data, variables); - // other::Schedule::create(input, energyplus_data, variables); - // surface::A::create(input, energyplus_data, variables); - // surface::QFlow::create(input, energyplus_data, variables); - // surface::T::create(input, energyplus_data, variables); - // construction::A::create(input, energyplus_data, variables); - // construction::QFrontFlow::create(input, energyplus_data, variables); - // construction::QBackFlow::create(input, energyplus_data, variables); - // construction::TFront::create(input, energyplus_data, variables); - // construction::TBack::create(input, energyplus_data, variables); + zone::AFlo::create(input, variables); + zone::MSenFac::create(input, variables); + zone::QConSenFlow::create(input, variables); + zone::QLatFlow::create(input, variables); + zone::QPeoFlow::create(input, variables); + zone::TRad::create(input, variables); + zone::QCooSenFlow::create(input, variables); + zone::QCooLatFlow::create(input, variables); + zone::TOutCoo::create(input, variables); + zone::XOutCoo::create(input, variables); + zone::MOutCooFlow::create(input, variables); + zone::TCoo::create(input, variables); + zone::QHeaFlow::create(input, variables); + zone::TOutHea::create(input, variables); + zone::XOutHea::create(input, variables); + zone::MOutHeaFlow::create(input, variables); + zone::THea::create(input, variables); + zone::MInletsFlow::create(input, variables); + zone::TAveInlet::create(input, variables); + zone::T::create(input, variables); + zone::X::create(input, variables); + zone::QGaiRadFlow::create(input, variables); + other::Sensor::create(input, variables); + other::Actuator::create(input, variables); + other::Schedule::create(input, variables); + surface::A::create(input, variables); + surface::QFlow::create(input, variables); + surface::T::create(input, variables); + construction::A::create(input, variables); + construction::QFrontFlow::create(input, variables); + construction::QBackFlow::create(input, variables); + construction::TFront::create(input, variables); + construction::TBack::create(input, variables); } } // namespace spawn::variable diff --git a/energyplus_coroutine/variables.hpp b/energyplus_coroutine/variables.hpp index edcb14dd..461ccbaa 100644 --- a/energyplus_coroutine/variables.hpp +++ b/energyplus_coroutine/variables.hpp @@ -2,17 +2,12 @@ #define Variables_hh_INCLUDED #include "units.hpp" -#include #include #include #include -#include #include #include -// See variable documentation here -// https://lbl-srg.github.io/soep/softwareArchitecture.html#coupling-of-the-envelope-model - namespace EnergyPlus { struct EnergyPlusData; } @@ -20,7 +15,7 @@ struct EnergyPlusData; namespace spawn { namespace units { enum class UnitSystem; -} +} // namespace units class Input; class Spawn; @@ -37,8 +32,8 @@ void CreateVariables(const Input &input, Variables &variables); // require a costly lookup. The conanical example is looking up // the zone index given the zone name. // -// CachedValue is used within Variables, because Variables -// are created before we have EnergyPlusData. +// CachedValue is used within Variables to avoid repeated costly lookups +// during the frequent Variable::Update operation. template class CachedValue { using GetterFunction = std::function; @@ -67,7 +62,7 @@ template class CachedValue }; // A Variable is a numercial value that is exchanged between EnergyPlus, -// and something else (probably Modelica), that is running from a different thread. +// and something else (probably Modelica) that is running from a different thread. // The Variable class: // 1. Buffers the numerical value, which could be either an input or an output to EnergyPlus // 2. Stores metadata about the value @@ -118,6 +113,8 @@ class InputVariable : public Variable using Variable::Variable; }; +// Begin defining the specific variables, which are documented here: +// https://lbl-srg.github.io/soep/softwareArchitecture.html#coupling-of-the-envelope-model namespace zone { class V : public OutputVariable { @@ -416,123 +413,125 @@ namespace other { CachedValue actuator_handle_; }; - // class Schedule : public InputVariable - // { - // public: - // static void create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables); - // void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; - // - // private: - // explicit Schedule(std::string_view name, int handle, int value_reference); - // - // int handle_; - // }; + class Schedule : public InputVariable + { + public: + static void create(const Input &input, Variables &variables); + void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; + + private: + explicit Schedule(Variables &variables, + const std::string_view name, + const std::string_view component_name, + const std::string_view component_type, + const std::string_view component_controltype); + + const std::string component_name_; + const std::string component_type_; + const std::string component_controltype_; + CachedValue handle_; + }; } // namespace other -// -// namespace surface { -// class A : public OutputVariable -// { -// public: -// static void create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables); -// void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; -// -// private: -// explicit A(std::string_view surface_name, int surface_num, int value_reference); -// -// std::string surface_name_; -// int surface_num_; -// }; -// -// class QFlow : public OutputVariable -// { -// public: -// static void create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables); -// void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; -// -// private: -// explicit QFlow(std::string_view surface_name, int surface_num, int value_reference); -// -// std::string surface_name_; -// int surface_num_; -// }; -// -// class T : public InputVariable -// { -// public: -// static void create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables); -// void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; -// -// private: -// explicit T(std::string_view surface_name, int surface_num, int value_reference); -// -// int surface_num_; -// }; -// } // namespace surface -// -// namespace construction { -// class A : public OutputVariable -// { -// public: -// static void create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables); -// void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; -// -// private: -// explicit A(std::string_view surface_name, int surface_num, int value_reference); -// -// std::string surface_name_; -// int surface_num_; -// }; -// -// class QFrontFlow : public OutputVariable -// { -// public: -// static void create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables); -// void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; -// -// private: -// explicit QFrontFlow(std::string_view surface_name, int surface_num, int value_reference); -// -// std::string surface_name_; -// int surface_num_; -// }; -// -// class QBackFlow : public OutputVariable -// { -// public: -// static void create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables); -// void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; -// -// private: -// explicit QBackFlow(std::string_view surface_name, int surface_num, int value_reference); -// -// std::string surface_name_; -// int surface_num_; -// }; -// -// class TFront : public InputVariable -// { -// public: -// static void create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables); -// void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; -// -// private: -// explicit TFront(std::string_view surface_name, int surface_num, int value_reference); -// -// int surface_num_; -// }; -// -// class TBack : public InputVariable -// { -// public: -// static void create(const Input &input, EnergyPlus::EnergyPlusData &energyplus_data, Variables &variables); -// void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; -// -// private: -// explicit TBack(std::string_view surface_name, int surface_num, int value_reference); -// -// int surface_num_; -// }; -// } // namespace construction + +namespace surface { + class A : public OutputVariable + { + public: + static void create(const Input &input, Variables &variables); + void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; + + private: + explicit A(Variables &variables, const std::string_view surface_name); + + CachedValue surface_num_; + }; + + class QFlow : public OutputVariable + { + public: + static void create(const Input &input, Variables &variables); + void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; + + private: + explicit QFlow(Variables &variables, std::string_view surface_name); + + CachedValue surface_num_; + }; + + class T : public InputVariable + { + public: + static void create(const Input &input, Variables &variables); + void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; + + private: + explicit T(Variables &variables, const std::string_view surface_name); + + CachedValue surface_num_; + }; +} // namespace surface + +namespace construction { + class A : public OutputVariable + { + public: + static void create(const Input &input, Variables &variables); + void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; + + private: + explicit A(Variables &variables, const std::string_view surface_name); + + CachedValue surface_num_; + }; + + class QFrontFlow : public OutputVariable + { + public: + static void create(const Input &input, Variables &variables); + void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; + + private: + explicit QFrontFlow(Variables &variables, const std::string_view surface_name); + + CachedValue surface_num_; + }; + + class QBackFlow : public OutputVariable + { + public: + static void create(const Input &input, Variables &variables); + void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; + + private: + explicit QBackFlow(Variables &variables, const std::string_view surface_name); + + CachedValue surface_num_; + }; + + class TFront : public InputVariable + { + public: + static void create(const Input &input, Variables &variables); + void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; + + private: + explicit TFront(Variables &variables, const std::string_view surface_name); + + CachedValue surface_num_; + }; + + class TBack : public InputVariable + { + public: + static void create(const Input &input, Variables &variables); + void Update(EnergyPlus::EnergyPlusData &energyplus_data) final; + + private: + explicit TBack(Variables &variables, const std::string_view surface_name); + + CachedValue surface_num_; + }; +} // namespace construction } // namespace spawn::variable