diff --git a/openstudiocore/src/model/CoilHeatingGas.cpp b/openstudiocore/src/model/CoilHeatingGas.cpp index 93adfcc6fcd..80db4cdeb5c 100644 --- a/openstudiocore/src/model/CoilHeatingGas.cpp +++ b/openstudiocore/src/model/CoilHeatingGas.cpp @@ -44,7 +44,7 @@ #include "Node_Impl.hpp" #include "AirLoopHVAC.hpp" #include "AirLoopHVAC_Impl.hpp" -#include +#include #include #include "../utilities/core/Compare.hpp" #include "../utilities/core/Assert.hpp" @@ -133,7 +133,7 @@ namespace detail{ return result; } - double CoilHeatingGas_Impl::gasBurnerEfficiency() + double CoilHeatingGas_Impl::gasBurnerEfficiency() const { return this->getDouble(OS_Coil_Heating_GasFields::GasBurnerEfficiency).get(); } @@ -143,7 +143,7 @@ namespace detail{ this->setDouble(OS_Coil_Heating_GasFields::GasBurnerEfficiency,val); } - double CoilHeatingGas_Impl::parasiticElectricLoad() + double CoilHeatingGas_Impl::parasiticElectricLoad() const { return this->getDouble(OS_Coil_Heating_GasFields::ParasiticElectricLoad).get(); } @@ -153,7 +153,7 @@ namespace detail{ this->setDouble(OS_Coil_Heating_GasFields::ParasiticElectricLoad,val); } - double CoilHeatingGas_Impl::parasiticGasLoad() + double CoilHeatingGas_Impl::parasiticGasLoad() const { return this->getDouble(OS_Coil_Heating_GasFields::ParasiticGasLoad).get(); } @@ -455,21 +455,21 @@ CoilHeatingGas::CoilHeatingGas(const Model& model, setParasiticElectricLoad(0); setParasiticGasLoad(0); } - -CoilHeatingGas::CoilHeatingGas(const Model& model) - : StraightComponent(CoilHeatingGas::iddObjectType(),model) -{ - OS_ASSERT(getImpl()); - - auto schedule = model.alwaysOnDiscreteSchedule(); - setAvailableSchedule(schedule); - - setGasBurnerEfficiency(0.8); - setString(openstudio::OS_Coil_Heating_GasFields::NominalCapacity,"AutoSize"); - setParasiticElectricLoad(0); - setParasiticGasLoad(0); -} - + +CoilHeatingGas::CoilHeatingGas(const Model& model) + : StraightComponent(CoilHeatingGas::iddObjectType(),model) +{ + OS_ASSERT(getImpl()); + + auto schedule = model.alwaysOnDiscreteSchedule(); + setAvailableSchedule(schedule); + + setGasBurnerEfficiency(0.8); + setString(openstudio::OS_Coil_Heating_GasFields::NominalCapacity,"AutoSize"); + setParasiticElectricLoad(0); + setParasiticGasLoad(0); +} + CoilHeatingGas::CoilHeatingGas(std::shared_ptr p) : StraightComponent(p) {} @@ -491,7 +491,7 @@ bool CoilHeatingGas::setAvailableSchedule(Schedule & schedule ) return getImpl()->setAvailabilitySchedule( schedule ); } -double CoilHeatingGas::gasBurnerEfficiency() +double CoilHeatingGas::gasBurnerEfficiency() const { return getImpl()->gasBurnerEfficiency(); } @@ -501,7 +501,7 @@ void CoilHeatingGas::setGasBurnerEfficiency(double val) getImpl()->setGasBurnerEfficiency(val); } -double CoilHeatingGas::parasiticElectricLoad() +double CoilHeatingGas::parasiticElectricLoad() const { return getImpl()->parasiticElectricLoad(); } @@ -511,7 +511,7 @@ void CoilHeatingGas::setParasiticElectricLoad(double val) getImpl()->setParasiticElectricLoad(val); } -double CoilHeatingGas::parasiticGasLoad() +double CoilHeatingGas::parasiticGasLoad() const { return getImpl()->parasiticGasLoad(); } diff --git a/openstudiocore/src/model/CoilHeatingGas.hpp b/openstudiocore/src/model/CoilHeatingGas.hpp index d5cd2c2688b..1192b4f8b7b 100644 --- a/openstudiocore/src/model/CoilHeatingGas.hpp +++ b/openstudiocore/src/model/CoilHeatingGas.hpp @@ -82,19 +82,19 @@ class MODEL_API CoilHeatingGas : public StraightComponent { bool setAvailableSchedule(Schedule& schedule); /** Returns the value of the GasBurnerEfficiency field. **/ - double gasBurnerEfficiency(); + double gasBurnerEfficiency() const; /** Sets the value of the GasBurnerEfficiency field. **/ void setGasBurnerEfficiency(double value); /** Returns the value of the ParasiticElectricLoad field. **/ - double parasiticElectricLoad(); + double parasiticElectricLoad() const; /** Sets the value of the ParasiticElectricLoad field. **/ void setParasiticElectricLoad(double value); /** Returns the value of the ParasiticGasLoad field. **/ - double parasiticGasLoad(); + double parasiticGasLoad() const; /** Sets the value of the ParasiticGasLoad field. **/ void setParasiticGasLoad(double value); diff --git a/openstudiocore/src/model/CoilHeatingGas_Impl.hpp b/openstudiocore/src/model/CoilHeatingGas_Impl.hpp index fd25bd30a5e..1148c6b6045 100644 --- a/openstudiocore/src/model/CoilHeatingGas_Impl.hpp +++ b/openstudiocore/src/model/CoilHeatingGas_Impl.hpp @@ -84,19 +84,19 @@ namespace detail { bool setAvailabilitySchedule(Schedule& schedule); // Get GasBurnerEfficiency - double gasBurnerEfficiency(); + double gasBurnerEfficiency() const; // Set GasBurnerEfficiency void setGasBurnerEfficiency(double val); // Get ParasiticElectricLoad - double parasiticElectricLoad(); + double parasiticElectricLoad() const; // Set parasiticElectricLoad void setParasiticElectricLoad(double val); // Get ParasiticGasLoad - double parasiticGasLoad(); + double parasiticGasLoad() const; // Set parasiticGasLoad void setParasiticGasLoad(double val); diff --git a/openstudiocore/src/model/FanConstantVolume.cpp b/openstudiocore/src/model/FanConstantVolume.cpp index 1a25366eef0..3ea6f5c7989 100644 --- a/openstudiocore/src/model/FanConstantVolume.cpp +++ b/openstudiocore/src/model/FanConstantVolume.cpp @@ -142,7 +142,7 @@ namespace detail { } - double FanConstantVolume_Impl::fanEfficiency() + double FanConstantVolume_Impl::fanEfficiency() const { return this->getDouble(OS_Fan_ConstantVolumeFields::FanEfficiency,true).get(); } @@ -152,7 +152,7 @@ namespace detail { this->setDouble(OS_Fan_ConstantVolumeFields::FanEfficiency,val); } - double FanConstantVolume_Impl::pressureRise() + double FanConstantVolume_Impl::pressureRise() const { return this->getDouble(OS_Fan_ConstantVolumeFields::PressureRise,true).get(); } @@ -162,7 +162,7 @@ namespace detail { this->setDouble(OS_Fan_ConstantVolumeFields::PressureRise,val); } - double FanConstantVolume_Impl::motorEfficiency() + double FanConstantVolume_Impl::motorEfficiency() const { return this->getDouble(OS_Fan_ConstantVolumeFields::MotorEfficiency,true).get(); } @@ -172,7 +172,7 @@ namespace detail { this->setDouble(OS_Fan_ConstantVolumeFields::MotorEfficiency,val); } - double FanConstantVolume_Impl::motorInAirstreamFraction() + double FanConstantVolume_Impl::motorInAirstreamFraction() const { return this->getDouble(OS_Fan_ConstantVolumeFields::MotorInAirstreamFraction,true).get(); } @@ -182,7 +182,7 @@ namespace detail { this->setDouble(OS_Fan_ConstantVolumeFields::MotorInAirstreamFraction,val); } - std::string FanConstantVolume_Impl::endUseSubcategory() + std::string FanConstantVolume_Impl::endUseSubcategory() const { return this->getString(OS_Fan_ConstantVolumeFields::EndUseSubcategory).get(); } @@ -487,7 +487,7 @@ bool FanConstantVolume::setAvailabilitySchedule(Schedule& s) return getImpl()->setAvailabilitySchedule(s); } -double FanConstantVolume::fanEfficiency() +double FanConstantVolume::fanEfficiency() const { return getImpl()->fanEfficiency(); } @@ -497,7 +497,7 @@ void FanConstantVolume::setFanEfficiency(double val) getImpl()->setFanEfficiency(val); } -double FanConstantVolume::pressureRise() +double FanConstantVolume::pressureRise() const { return getImpl()->pressureRise(); } @@ -507,7 +507,7 @@ void FanConstantVolume::setPressureRise(double val) getImpl()->setPressureRise(val); } -double FanConstantVolume::motorEfficiency() +double FanConstantVolume::motorEfficiency() const { return getImpl()->motorEfficiency(); } @@ -517,7 +517,7 @@ void FanConstantVolume::setMotorEfficiency(double val) getImpl()->setMotorEfficiency(val); } -double FanConstantVolume::motorInAirstreamFraction() +double FanConstantVolume::motorInAirstreamFraction() const { return getImpl()->motorInAirstreamFraction(); } @@ -527,7 +527,7 @@ void FanConstantVolume::setMotorInAirstreamFraction(double val) getImpl()->setMotorInAirstreamFraction(val); } -std::string FanConstantVolume::endUseSubcategory() +std::string FanConstantVolume::endUseSubcategory() const { return getImpl()->endUseSubcategory(); } diff --git a/openstudiocore/src/model/FanConstantVolume.hpp b/openstudiocore/src/model/FanConstantVolume.hpp index 7278b8f033f..9c28d34636c 100644 --- a/openstudiocore/src/model/FanConstantVolume.hpp +++ b/openstudiocore/src/model/FanConstantVolume.hpp @@ -59,19 +59,19 @@ class MODEL_API FanConstantVolume : public StraightComponent { Schedule availabilitySchedule() const; /** Returns the value of the FanEfficiency field. **/ - double fanEfficiency(); + double fanEfficiency() const; /** Returns the value of the PressureRise field. **/ - double pressureRise(); + double pressureRise() const; /** Returns the value of the MotorEfficiency field. **/ - double motorEfficiency(); + double motorEfficiency() const; /** Returns the value of the MotorInAirStreamFraction field. **/ - double motorInAirstreamFraction(); + double motorInAirstreamFraction() const; /** Returns the value of the EndUseSubcategory field. **/ - std::string endUseSubcategory(); + std::string endUseSubcategory() const; //@} /** @name Setters */ diff --git a/openstudiocore/src/model/FanConstantVolume_Impl.hpp b/openstudiocore/src/model/FanConstantVolume_Impl.hpp index 27f3e7c8fdc..53fe8bbc27f 100644 --- a/openstudiocore/src/model/FanConstantVolume_Impl.hpp +++ b/openstudiocore/src/model/FanConstantVolume_Impl.hpp @@ -90,31 +90,31 @@ namespace detail { bool setAvailabilitySchedule(Schedule& s); // Get FanEfficiency - double fanEfficiency(); + double fanEfficiency() const; // Set fanEfficiency void setFanEfficiency(double val); // Get PressureRise - double pressureRise(); + double pressureRise() const; // Set PressureRise void setPressureRise(double val); // Get MotorEfficiency - double motorEfficiency(); + double motorEfficiency() const; // Set MotorEfficiency void setMotorEfficiency(double val); // Get MotorInAirstreamFraction - double motorInAirstreamFraction(); + double motorInAirstreamFraction() const; // Set MotorInAirstreamFraction void setMotorInAirstreamFraction(double val); // Get EndUseSubcategory - std::string endUseSubcategory(); + std::string endUseSubcategory() const; // Set EndUseSubcategory void setEndUseSubcategory(std::string val); diff --git a/openstudiocore/src/sdd/ForwardTranslator.cpp b/openstudiocore/src/sdd/ForwardTranslator.cpp index 11ebe4c6702..81b7964be7d 100644 --- a/openstudiocore/src/sdd/ForwardTranslator.cpp +++ b/openstudiocore/src/sdd/ForwardTranslator.cpp @@ -156,6 +156,8 @@ namespace openstudio { namespace sdd { ForwardTranslator::ForwardTranslator() + : m_autoHardSize(false), + m_autoEfficiency(false) { m_logSink.setLogLevel(Warn); m_logSink.setChannelRegex(boost::regex("openstudio\\.sdd\\.ForwardTranslator")); diff --git a/openstudiocore/src/sdd/ForwardTranslator.hpp b/openstudiocore/src/sdd/ForwardTranslator.hpp index 5118d3a6691..d5925ef23f0 100644 --- a/openstudiocore/src/sdd/ForwardTranslator.hpp +++ b/openstudiocore/src/sdd/ForwardTranslator.hpp @@ -53,6 +53,10 @@ namespace model { class SubSurface; class ShadingSurface; class AirLoopHVAC; + class FanConstantVolume; + class CoilCoolingDXSingleSpeed; + class CoilHeatingGas; + class AirLoopHVACOutdoorAirSystem; } namespace sdd { @@ -100,6 +104,10 @@ namespace sdd { boost::optional translateShadingSurface(const openstudio::model::ShadingSurface& shadingSurface, const openstudio::Transformation& transformation, QDomDocument& doc); boost::optional translateThermalZone(const openstudio::model::ThermalZone& thermalZone, QDomDocument& doc); boost::optional translateAirLoopHVAC(const openstudio::model::AirLoopHVAC& airLoop, QDomDocument& doc); + boost::optional translateFanConstantVolume(const openstudio::model::FanConstantVolume& fan, QDomElement & airSegElement, QDomDocument& doc); + boost::optional translateCoilCoolingDXSingleSpeed(const openstudio::model::CoilCoolingDXSingleSpeed& coil, QDomElement & airSegElement, QDomDocument& doc); + boost::optional translateCoilHeatingGas(const openstudio::model::CoilHeatingGas& coil, QDomElement & airSegElement, QDomDocument& doc); + boost::optional translateAirLoopHVACOutdoorAirSystem(const openstudio::model::AirLoopHVACOutdoorAirSystem& oasys, QDomElement & airSysElement, QDomDocument& doc); std::map m_translatedObjects; @@ -120,6 +128,9 @@ namespace sdd { ProgressBar* m_progressBar; + bool m_autoHardSize; + bool m_autoEfficiency; + REGISTER_LOGGER("openstudio.sdd.ForwardTranslator"); }; diff --git a/openstudiocore/src/sdd/MapHVAC.cpp b/openstudiocore/src/sdd/MapHVAC.cpp index 55a81c07609..6d0231e137c 100644 --- a/openstudiocore/src/sdd/MapHVAC.cpp +++ b/openstudiocore/src/sdd/MapHVAC.cpp @@ -28,9 +28,12 @@ #include "../model/AirLoopHVACZoneSplitter.hpp" #include "../model/AirLoopHVACZoneSplitter_Impl.hpp" #include "../model/AirLoopHVACOutdoorAirSystem.hpp" +#include "../model/AirLoopHVACOutdoorAirSystem_Impl.hpp" #include "../model/ControllerOutdoorAir.hpp" #include "../model/FanConstantVolume.hpp" +#include "../model/FanConstantVolume_Impl.hpp" #include "../model/FanVariableVolume.hpp" +#include "../model/FanVariableVolume_Impl.hpp" #include "../model/FanOnOff.hpp" #include "../model/FanOnOff_Impl.hpp" #include "../model/FanZoneExhaust.hpp" @@ -40,9 +43,11 @@ #include "../model/CoilCoolingWaterToAirHeatPumpEquationFit.hpp" #include "../model/CoilCoolingWaterToAirHeatPumpEquationFit_Impl.hpp" #include "../model/CoilCoolingDXSingleSpeed.hpp" +#include "../model/CoilCoolingDXSingleSpeed_Impl.hpp" #include "../model/CoilCoolingDXTwoSpeed.hpp" #include "../model/CoilCoolingDXMultiSpeed.hpp" #include "../model/CoilHeatingGas.hpp" +#include "../model/CoilHeatingGas_Impl.hpp" #include "../model/CoilHeatingElectric.hpp" #include "../model/CoilHeatingDXSingleSpeed.hpp" #include "../model/ControllerWaterCoil.hpp" @@ -7018,12 +7023,188 @@ boost::optional ForwardTranslator::translateAirLoopHVAC(const model clRstSupLowElement.appendChild(doc.createTextNode(QString::number(clRstSupLow))); m_translatedObjects[tempSPM->handle()] = clgCtrlElement; + } else { + LOG(Error,spm.briefDescription() << " does not currently map into SDD format.") + // TODO Handle other SPMs } break; } } + // Translate supply components + + auto airSegElement = doc.createElement("AirSeg"); + result.appendChild(airSegElement); + + auto airSegNameElement = doc.createElement("Name"); + airSegNameElement.appendChild(doc.createTextNode(QString::fromStdString(name + " Supply AirSeg"))); + airSegElement.appendChild(airSegNameElement); + + auto airSegTypeElement = doc.createElement("Type"); + airSegTypeElement.appendChild(doc.createTextNode("Supply")); + airSegElement.appendChild(airSegTypeElement); + + for( auto & comp : airLoop.supplyComponents() ) { + if( auto fan = comp.optionalCast() ) { + translateFanConstantVolume(fan.get(),airSegElement,doc); + } else if ( auto coil = comp.optionalCast() ) { + translateCoilCoolingDXSingleSpeed(coil.get(),airSegElement,doc); + } else if ( auto coil = comp.optionalCast() ) { + translateCoilHeatingGas(coil.get(),airSegElement,doc); + } else if ( auto oasys = comp.optionalCast() ) { + translateAirLoopHVACOutdoorAirSystem(oasys.get(),result,doc); + } else { + // TODO Handle other supply component types + LOG(Warn,comp.briefDescription() << " does not currently map into SDD format.") + } + } + + return result; +} + +boost::optional ForwardTranslator::translateAirLoopHVACOutdoorAirSystem(const openstudio::model::AirLoopHVACOutdoorAirSystem& oasys, QDomElement & airSysElement, QDomDocument& doc) +{ + auto result = doc.createElement("OACtrl"); + airSysElement.appendChild(result); + m_translatedObjects[oasys.handle()] = result; + + return result; +} + +boost::optional ForwardTranslator::translateCoilHeatingGas(const openstudio::model::CoilHeatingGas& coil, QDomElement & airSegElement, QDomDocument& doc) +{ + auto result = doc.createElement("CoilClg"); + airSegElement.appendChild(result); + m_translatedObjects[coil.handle()] = result; + + // Type + auto typeElement = doc.createElement("Type"); + result.appendChild(typeElement); + typeElement.appendChild(doc.createTextNode("Furnace")); + + // FuelSrc + auto fuelSrcElement = doc.createElement("FuelSrc"); + result.appendChild(fuelSrcElement); + fuelSrcElement.appendChild(doc.createTextNode("NaturalGas")); + + // CapTotGrossRtd + if( coil.isNominalCapacityAutosized() ) { + m_autoHardSize = true; + } else if( auto value = coil.nominalCapacity() ) { + auto capTotGrossRtdElement = doc.createElement("CapTotGrossRtd"); + result.appendChild(capTotGrossRtdElement); + capTotGrossRtdElement.appendChild(doc.createTextNode(QString::number(convert(value.get(),"W","Btu/h").get()))); + } + + // FurnThrmlEff + auto furnThrmlEffElement = doc.createElement("FurnThrmlEff"); + result.appendChild(furnThrmlEffElement); + furnThrmlEffElement.appendChild(doc.createTextNode(QString::number(convert(coil.gasBurnerEfficiency(),"W","Btu/h").get()))); + + return result; +} + +boost::optional ForwardTranslator::translateCoilCoolingDXSingleSpeed(const openstudio::model::CoilCoolingDXSingleSpeed& coil, QDomElement & airSegElement, QDomDocument& doc) +{ + auto result = doc.createElement("CoilClg"); + airSegElement.appendChild(result); + m_translatedObjects[coil.handle()] = result; + + // Type + auto typeElement = doc.createElement("Type"); + result.appendChild(typeElement); + typeElement.appendChild(doc.createTextNode("DirectExpansion")); + + // NumClgStages + auto numClgStagesElement = doc.createElement("NumClgStages"); + result.appendChild(numClgStagesElement); + numClgStagesElement.appendChild(doc.createTextNode("1")); + + // CapTotGrossRtd + if( coil.isRatedTotalCoolingCapacityAutosized() ) { + m_autoHardSize = true; + } else if( auto value = coil.ratedTotalCoolingCapacity() ) { + auto capTotGrossRtdElement = doc.createElement("CapTotGrossRtd"); + result.appendChild(capTotGrossRtdElement); + capTotGrossRtdElement.appendChild(doc.createTextNode(QString::number(convert(value.get(),"W","Btu/h").get()))); + } + + // DXEER + if( auto cop = coil.ratedCOP() ) { + auto r = 0.12; + auto eer = (cop.get() * (1 - r) - r) * 3.413; + + auto dxEERElement = doc.createElement("DXEER"); + result.appendChild(dxEERElement); + dxEERElement.appendChild(doc.createTextNode(QString::number(eer))); + } else { + m_autoEfficiency = true; + } + + // CndsrType + auto cndsrTypeElement = doc.createElement("CndsrType"); + result.appendChild(cndsrTypeElement); + cndsrTypeElement.appendChild(doc.createTextNode("Air")); + + return result; +} + +boost::optional ForwardTranslator::translateFanConstantVolume(const openstudio::model::FanConstantVolume& fan, QDomElement & airSegElement, QDomDocument& doc) +{ + auto result = doc.createElement("Fan"); + airSegElement.appendChild(result); + m_translatedObjects[fan.handle()] = result; + + // CtrlMthd + auto ctrlMthdElement = doc.createElement("CtrlMthd"); + result.appendChild(ctrlMthdElement); + ctrlMthdElement.appendChild(doc.createTextNode("ConstantVolume")); + + // Class - Centrifugal | Axial + // TODO Define a way to deterimine or specify + auto classElement = doc.createElement("Class"); + result.appendChild(classElement); + classElement.appendChild(doc.createTextNode("Axial")); + + // ModelingMthd + auto modelingMthdElement = doc.createElement("ModelingMthd"); + result.appendChild(modelingMthdElement); + modelingMthdElement.appendChild(doc.createTextNode("StaticPressure")); + + // FlowCap + if( fan.isMaximumFlowRateAutosized() ) { + m_autoHardSize = true; + } else if( auto value = fan.maximumFlowRate() ) { + auto flowCapElement = doc.createElement("FlowCap"); + result.appendChild(flowCapElement); + flowCapElement.appendChild(doc.createTextNode(QString::number(convert(value.get(),"m^3/s","cfm").get()))); + } + + // FlowEff + auto flowEffElement = doc.createElement("FlowEff"); + result.appendChild(flowEffElement); + flowEffElement.appendChild(doc.createTextNode(QString::number(fan.fanEfficiency()))); + + // TotStaticPress + auto totStaticPressElement = doc.createElement("TotStaticPress"); + result.appendChild(totStaticPressElement); + // Convert in PA to WC + totStaticPressElement.appendChild(doc.createTextNode(QString::number(fan.pressureRise() / 249.0889))); + + // MtrEff + auto mtrEffElement = doc.createElement("MtrEff"); + result.appendChild(mtrEffElement); + mtrEffElement.appendChild(doc.createTextNode(QString::number(fan.motorEfficiency()))); + + // MtrPos + auto mtrPosElement = doc.createElement("MtrfPos"); + result.appendChild(mtrPosElement); + if( fan.motorInAirstreamFraction() >= 0.5 ) { + mtrPosElement.appendChild(doc.createTextNode("InAirStream")); + } else { + mtrPosElement.appendChild(doc.createTextNode("NotInAirStream")); + } return result;