diff --git a/doc/Adding_Model_Object_to_OpenStudio.docx b/doc/Adding_Model_Object_to_OpenStudio.docx index 5e38e47cba2..1aabac5b648 100644 Binary files a/doc/Adding_Model_Object_to_OpenStudio.docx and b/doc/Adding_Model_Object_to_OpenStudio.docx differ diff --git a/openstudiocore/resources/energyplus/ProposedEnergy+.idd b/openstudiocore/resources/energyplus/ProposedEnergy+.idd index 6f29663ce4c..861669f8030 100644 --- a/openstudiocore/resources/energyplus/ProposedEnergy+.idd +++ b/openstudiocore/resources/energyplus/ProposedEnergy+.idd @@ -52456,6 +52456,8 @@ ElectricLoadCenter:Distribution, \note Controls timing and magnitude of discharging storage \note Required field if Storage Operation Scheme is set to TrackChargeDischargeSchedules. \note Schedule values should be fractions from 0.0 to 1.0, inclusive. + \type object-list + \object-list ScheduleNames N6, \field Storage Control Utility Demand Target \note Target utility service demand power for discharge control. Storage draws are adjusted upwards for conversion losses. \note Required field for FacilityDemandLeveling storage operation scheme diff --git a/openstudiocore/resources/model/OpenStudio.idd b/openstudiocore/resources/model/OpenStudio.idd index f113bdb228f..cb8605ecfe9 100644 --- a/openstudiocore/resources/model/OpenStudio.idd +++ b/openstudiocore/resources/model/OpenStudio.idd @@ -24765,6 +24765,291 @@ OS:SolarCollector:FlatPlate:PhotovoltaicThermal, \group Electric Load Center-Generator Specifications +OS:Generator:MicroTurbine, + \memo MicroTurbine generators are small combustion turbines (e.g., 25kW to 500kW). The model + \memo calculates electrical power output, fuel use, standby and ancillary power. + \memo Energy recovery from exhaust air can be used to heat water. + \min-fields 12 + A1, \field Handle + \type handle + \required-field + A2, \field Name + \required-field + \type alpha + \reference GeneratorNames + \reference MicroTurbineGeneratorNames + A3, \field Availability Schedule Name + \note Availability schedule name for this generator. Schedule value > 0 means the generator is available. + \note If this field is blank, the generator is always available. + \type object-list + \object-list ScheduleNames + N1, \field Reference Electrical Power Output + \required-field + \type real + \units W + \minimum> 0.0 + N2, \field Minimum Full Load Electrical Power Output + \type real + \units W + \minimum 0.0 + \default 0.0 + N3, \field Maximum Full Load Electrical Power Output + \type real + \units W + \minimum> 0.0 + \note If left blank, Maximum Full Load Electrical Power Output will be set + \note equal to the Reference Electrical Power Output. + N4, \field Reference Electrical Efficiency Using Lower Heating Value + \required-field + \type real + \minimum> 0.0 + \maximum 1.0 + \note Electric power output divided by fuel energy input (LHV basis) + \note at reference conditions. + N5, \field Reference Combustion Air Inlet Temperature + \type real + \units C + \default 15.0 + N6, \field Reference Combustion Air Inlet Humidity Ratio + \type real + \units kgWater/kgDryAir + \minimum> 0.0 + \default 0.00638 + N7, \field Reference Elevation + \type real + \units m + \minimum -300.0 + \default 0.0 + A4, \field Electrical Power Function of Temperature and Elevation Curve Name + \required-field + \type object-list + \object-list BiquadraticCurves + \object-list BiVariateTables + \note curve = a + b*T + c*T**2 + d*Elev + e*Elev**2 + f*T*Elev + \note T = combustion air inlet temperature (C) + \note Elev = elevation (m) + A5, \field Electrical Efficiency Function of Temperature Curve Name + \required-field + \type object-list + \object-list QuadraticCubicCurves + \note Quadratic curve = a + b*T + c*T**2 + \note Cubic curve = a + b*T + c*T**2 + d*T**3 + \note T = combustion air inlet temperature (C) + A6, \field Electrical Efficiency Function of Part Load Ratio Curve Name + \required-field + \type object-list + \object-list QuadraticCubicCurves + \note Quadratic curve = a + b*PLR + c*PLR**2 + \note Cubic curve = a + b*PLR + c*PLR**2 + d*PLR**3 + \note PLR = ratio of Generator Load to steady state Electrical Power Output at + \note current operating conditions + A7, \field Fuel Type + \type choice + \key NaturalGas + \key PropaneGas + \default NaturalGas + N8, \field Fuel Higher Heating Value + \type real + \units kJ/kg + \default 50000 + \minimum> 0.0 + N9, \field Fuel Lower Heating Value + \type real + \units kJ/kg + \default 45450 + \minimum> 0.0 + N10, \field Standby Power + \type real + \units W + \default 0.0 + \minimum 0.0 + \note Electric power consumed when the generator is available but not being called + \note by the Electric Load Center. + N11, \field Ancillary Power + \type real + \units W + \default 0.0 + \minimum 0.0 + \note Electric power consumed by ancillary equipment (e.g., external fuel pressurization pump). + \note Set to zero if Reference Electrical Power Output is the 'net' value (ancillary power + \note already deducted). Input value is positive, but indicates negative electric generation. + A8, \field Ancillary Power Function of Fuel Input Curve Name + \type object-list + \object-list QuadraticCurves + \object-list UniVariateTables + \note Quadratic curve = a + b*mdot + c*mdot**2 + \note mdot = fuel mass flow rate (kg/s) + \note If left blank, model assumes ancillary power defined in previous field is constant + \note whenever the generator is operating. + A9, \field Generator MicroTurbine Heat Recovery Name + \type object-list + \object-list MicroTurbineHeatRecoveryNames + \note Reference an optional OpenStudio specific object for the HeatRecovery Module itself + A10, \field Combustion Air Inlet Node Name + \type object-list + \object-list ConnectionNames + \note Must be an outdoor air node. + A11, \field Combustion Air Outlet Node Name + \type object-list + \object-list ConnectionNames + N12, \field Reference Exhaust Air Mass Flow Rate + \type real + \units kg/s + \minimum> 0.0 + A12, \field Exhaust Air Flow Rate Function of Temperature Curve Name + \type object-list + \object-list QuadraticCubicCurves + \object-list UniVariateTables + \note Quadratic curve = a + b*T + c*T**2 + \note Cubic curve = a + b*T + c*T**2 + d*T**3 + \note T = combustion air inlet temperature (C) + \note If field is left blank, model assumes this modifier equals 1 for entire simulation. + A13, \field Exhaust Air Flow Rate Function of Part Load Ratio Curve Name + \type object-list + \object-list QuadraticCubicCurves + \object-list UniVariateTables + \note Quadratic curve = a + b*PLR + c*PLR**2 + \note Cubic curve = a + b*PLR + c*PLR**2 + d*PLR**3 + \note PLR = ratio of Generator Load to steady state Electrical Power Output at + \note current operating conditions. + \note If field is left blank, model assumes this modifier equals 1 for entire simulation. + N13, \field Nominal Exhaust Air Outlet Temperature + \type real + \note Exhaust air outlet temperature at reference conditions. + A14, \field Exhaust Air Temperature Function of Temperature Curve Name + \type object-list + \object-list QuadraticCubicCurves + \object-list UniVariateTables + \note Quadratic curve = a + b*T + c*T**2 + \note Cubic curve = a + b*T + c*T**2 + d*T**3 + \note T = combustion air inlet temperature (C) + \note If field is left blank, model assumes this modifier equals 1 for entire simulation. + A15; \field Exhaust Air Temperature Function of Part Load Ratio Curve Name + \type object-list + \object-list QuadraticCubicCurves + \object-list UniVariateTables + \note Quadratic curve = a + b*PLR + c*PLR**2 + \note Cubic curve = a + b*PLR + c*PLR**2 + d*PLR**3 + \note PLR = ratio of Generator Load to steady state Electrical Power Output at + \note current operating conditions. + \note If field is left blank, model assumes this modifier equals 1 for entire simulation. + +OS:Generator:MicroTurbine:HeatRecovery, + \memo MicroTurbine generators are small combustion turbines (e.g., 25kW to 500kW). The model + \memo calculates electrical power output, fuel use, standby and ancillary power. + \memo Energy recovery from exhaust air can be used to heat water. + \memo this class is purely for OpenStudio to separate + \memo the HeatRecovery (StraightComponent) from the Generator:MicroTurbine(Generator) + \min-fields 12 + A1, \field Handle + \type handle + \required-field + A2, \field Name + \required-field + \type alpha + \reference MicroTurbineHeatRecoveryNames + \reference ConnectionObject + A3, \field Heat Recovery Water Inlet Node Name + \type object-list + \required-field + \object-list ConnectionNames + A4, \field Heat Recovery Water Outlet Node Name + \type object-list + \required-field + \object-list ConnectionNames + N1 , \field Reference Thermal Efficiency Using Lower Heat Value + \type real + \minimum 0.0 + \maximum 1.0 + \default 0.0 + \note Reference thermal efficiency (heat recovery to water) based on the + \note Lower Heating Value (LHV) of the fuel. + N2 , \field Reference Inlet Water Temperature + \type real + \required-field + \units C + A5 , \field Heat Recovery Water Flow Operating Mode + \type choice + \required-field + \key PlantControl + \key InternalControl + \default PlantControl + \note PlantControl means the heat recovery water flow rate is determined by the plant, + \note but the user needs to supply a heat recovery water flow rate. + \note InternalControl means the heat recovery water flow rate is controlled by this generator. + \note If 'InternalControl' is selected, then the user needs to supply a reference heat + \note recovery water flow rate and optionally the name of a heat recovery flow rate modifier curve. + N6 , \field Reference Heat Recovery Water Flow Rate + \type real + \required-field + \units m3/s + \ip-units gal/min + \minimum> 0.0 + A6 , \field Heat Recovery Water Flow Rate Function of Temperature and Power Curve Name + \type object-list + \object-list BiquadraticCurves + \object-list BiVariateTables + \note curve = a + b*T + c*T**2 + d*Pnet + e*Pnet + f*T*Pnet + \note T = heat recovery inlet water temperature + \note Pnet = net power output = electric power output - ancillary power + \note If left blank, model assumes the heat recovery water flow rate is constant whenever the + \note generator is operating, at the Reference HR Water Flow Rate defined in the previous field. + A7 , \field Thermal Efficiency Function of Temperature and Elevation Curve Name + \type object-list + \object-list BicubicBiquadraticCurves + \object-list BiVariateTables + \note Bicubic curve = a + b*T + c*T**2 + d*Elev + e*Elev**2 + f*T*Elev + g*T**3 + h*Elev**3 + i*T**2*Elev + j*T*Elev**2 + \note Biquadratic curve = a + b*T + c*T**2 + d*Elev + e*Elev**2 + f*T*Elev + \note T = combustion air inlet temperature (C) + \note Elev = elevation (m) + \note If field is left blank, model assumes this modifier equals 1 for entire simulation. + A8 , \field Heat Recovery Rate Function of Part Load Ratio Curve Name + \type object-list + \object-list QuadraticCubicCurves + \object-list UniVariateTables + \note Quadratic curve = a + b*PLR + c*PLR**2 + \note Cubic curve = a + b*PLR + c*PLR**2 + d*PLR**3 + \note PLR = ratio of Generator Load to steady state Electrical Power Output at + \note current operating conditions + \note If field is left blank, model assumes this modifier equals 1 for entire simulation. + A9 , \field Heat Recovery Rate Function of Inlet Water Temperature Curve Name + \type object-list + \object-list QuadraticCurves + \object-list UniVariateTables + \note Quadratic curve = a + b*T + c*T**2 + \note T = inlet water temperature (C) + \note If field is left blank, model assumes this modifier equals 1 for entire simulation. + A10, \field Heat Recovery Rate Function of Water Flow Rate Curve Name + \type object-list + \object-list QuadraticCurves + \object-list UniVariateTables + \note Quadratic curve = a + b*Flow + c*Flow**2 + \note Flow = flow rate of water through the heat exchanger (m3/s) + \note If field is left blank, model assumes this modifier equals 1 for entire simulation. + N7, \field Minimum Heat Recovery Water Flow Rate + \type real + \units m3/s + \ip-units gal/min + \minimum 0.0 + \default 0.0 + N8, \field Maximum Heat Recovery Water Flow Rate + \type real + \required-field + \units m3/s + \ip-units gal/min + \minimum 0.0 + \default 0.0 + \note Eplus defaults to 0 but here it would be moot to have a Heat + \note Recovery module with a max flow of 0 so it is a required field + N9, \field Maximum Heat Recovery Water Temperature + \type real + \units C + N10; \field Rated Thermal to Electrical Power Ratio + \type real + \minimum> 0.0 + \note Required field when generator is used by an ElectricLoadCenter:Distribution object with Generator Operation Scheme set to FollowThermal or FollowThermalLimitElectrical + \note Will default to 'Reference Thermal Efficiency Using Lower Heat Value' divided by 'Reference Electrical Efficiency Using Lower Heating Value' + OS:Generator:Photovoltaic, \memo Describes an array of photovoltaic (PV) modules. PV performance is taken from the \memo referenced PhotovoltaicPerformance:* object. Array tilt, azimuth, and gross area @@ -24810,7 +25095,7 @@ OS:Generator:Photovoltaic, \note If this field is blank, the generator is always available. \type object-list \object-list ScheduleNames - + OS:PhotovoltaicPerformance:Simple, \memo Describes a simple model of photovoltaics that may be useful for early phase \memo design analysis. In this model the user has direct access to the efficiency with @@ -25032,6 +25317,56 @@ OS:ElectricLoadCenter:Inverter:LookUpTable, \minimum 0 \maximum 1.0 +OS:ElectricLoadCenter:Storage:Simple, + \memo Used to model storage of electricity in an electric load center. This is a simple + \memo model that does not attempt to represent any of the characteristics of a real + \memo storage device such as a battery. The type of power, AC or DC, depends on + \memo the configuration chosen as the Electrical Buss Type in the + \memo ElectricLoadCenter:Distribution object. + A1 , \field Handle + \type handle + \required-field + A2, \field Name + \reference ElecStorageList + A3, \field Availability Schedule Name + \note Availability schedule name for this system. Schedule value > 0 means the system is available. + \note If this field is blank, the system is always available. + \type object-list + \object-list ScheduleNames + A4, \field Zone Name + \note Enter name of zone to receive storage losses as heat + \note if blank then storage is assumed to be outdoors + \type object-list + \object-list ThermalZoneNames + N1 , \field Radiative Fraction for Zone Heat Gains + \maximum 1.0 + \minimum 0.0 + \default 0.0 + \note This field contains the fraction of storage losses that enter the zone as long-wave thermal radiation. + \note This should be a factor between 0.0 and 1.0. The balance of the losses are convective. + \note This field is not used if the previous field for 'Zone Name' is left blank. + N2, \field Nominal Energetic Efficiency for Charging + \maximum 1.0 + \minimum 0.0 + \default 1.0 + N3, \field Nominal Discharging Energetic Efficiency + \maximum 1.0 + \minimum 0.0 + \default 1.0 + N4, \field Maximum Storage Capacity + \required-field + \units J + N5, \field Maximum Power for Discharging + \required-field + \units W + \minimum 0.0 + N6, \field Maximum Power for Charging + \required-field + \units W + \minimum 0.0 + N7; \field Initial State of Charge + \units J + OS:ElectricLoadCenter:Distribution, \memo a list of meters that can be reported are available after a run on \memo the meter dictionary file (.mdd) if the Output:VariableDictionary has been requested. @@ -25046,10 +25381,16 @@ OS:ElectricLoadCenter:Distribution, \object-list ModelObjectLists A4 , \field Generator Operation Scheme Type \note required if Generator List is entered. - \memo Keys DemandLimit, TrackElectrical, TrackSchedule, TrackMeter, FollowThermal and FollowThermalLimitElectrical disabled for now + \note Determines how generators are to be controlled \type choice - \default Baseload \key Baseload + \key DemandLimit + \key TrackElectrical + \key TrackSchedule + \key TrackMeter + \key FollowThermal + \key FollowThermalLimitElectrical + \default Baseload N1 , \field Demand Limit Scheme Purchased Electric Demand Limit \type real \units W @@ -25058,15 +25399,19 @@ OS:ElectricLoadCenter:Distribution, \type object-list \object-list ScheduleNames A6 , \field Track Meter Scheme Meter Name + \type alpha \note required when Generator Operation Scheme Type=TrackMeter - \type external-list - \external-list autoRDDmeter + \memo type external list + \memo external list autoRDDmeter A7 , \field Electrical Buss Type \type choice - \memo Keys AlternatingCurrent, AlternatingCurrentWithStorage, DirectCurrentWithInverterDCStorage, and DirectCurrentWithInverterACStorage disabled for now + \key AlternatingCurrent + \key AlternatingCurrentWithStorage \key DirectCurrentWithInverter + \key DirectCurrentWithInverterDCStorage + \key DirectCurrentWithInverterACStorage \default DirectCurrentWithInverter - A8 , \field Inverter Object Name + A8 , \field Inverter Name \note required when Electrical Buss Type=DirectCurrentWithInverter, DirectCurrentWithInverterDCStorage, \note or DirectCurrentWithInverterACStorage \type object-list @@ -25076,10 +25421,141 @@ OS:ElectricLoadCenter:Distribution, \note or DirectCurrentWithInverterACStorage \type object-list \object-list ElecStorageList - A10; \field Transformer Object Name + A10, \field Transformer Object Name \note required when power needs to be output from on-site generation to the grid via transformer \type object-list - \object-list TransformerNames + \object-list TransformerNames + A11, \field Storage Operation Scheme + \note Select method to govern how storage charge and discharge is controlled + \type choice + \key TrackFacilityElectricDemandStoreExcessOnSite + \note TrackFacilityElectricDemandStoreExcessOnSite indicates that storage control will follow the facility power demand + \note while accounting for any on-site generation. Only excess on site generation gets stored (legacy behavior). + \default TrackFacilityElectricDemandStoreExcessOnSite + \key TrackMeterDemandStoreExcessOnSite + \note TrackMeterDemandStoreExcessOnSite indicates that storage discharge control will follow an electric meter named in the field called Storage Control Track Meter Name. This scheme is similiar + \note to TrackFacilityElectricDemandStoreExcessOnSite except that instead of the main facility electric meter, the control is based off of a user-selected meter. + \key TrackChargeDischargeSchedules + \note TrackChargeDischargeSchedules indicates that control will follow the charging and discharging power and schedules defined in the fields called Maximum Storage Charge Grid Supply Power, + \note Storage Charge Grid Supply Power Fraction Schedule Name, Design Storage Discharge Grid Export Power, and Storage Discharge Grid Export Fraction Schedule Name. + \key FacilityDemandLeveling + \note FacilityDemandLeveling indicates that storage control will attempt to control the facility's power demand drawn from the utility service to a prescribed level. + \note The target utility demand is entered in the fields called Storage Control Utility Demand Limit and Storage Control Utility Demand Limit Fraction Schedule Name + \note This scheme first accounts for any on-site generation and during times of high use will discharge storage to reduce facility grid demand to meet the target level + \note and during times of low use will charge storage from the grid to increase facility grid demand to meet the target level. + A12, \field Storage Control Track Meter Name + \note required when Storage Operation Scheme is set to TrackMeterDemandStoreExcessOnSite. + \type alpha + \memo type external-list + \memo external-list autoRDDmeter + A13, \field Storage Converter Object Name + \note Name of an ElectricLoadCenter:Storage:Converter used to convert AC to DC when charging DC storage from grid supply. + \note A converter is expected when using Storage Operation Schemes FacilityDemandLeveling or TrackChargeDischargeSchedules + \note A single bidirectional device will reference both an inverter object (DC to AC) and a converter object (AC to DC). + \type object-list + \object-list ConverterList + N2 , \field Maximum Storage State of Charge Fraction + \note Fraction of storage capacity used as upper limit for controlling charging, for all storage operation schemes. + \type real + \default 1.0 + N3 , \field Minimum Storage State of Charge Fraction + \note Fraction of storage capacity used as lower limit for controlling discharging, for all storage operation schemes. + \type real + \default 0.0 + N4 , \field Design Storage Control Charge Power + \note Maximum rate that electric power can be charged into storage. + \note Storage charging adjusted downward for conversion losses. + \note Rate is modified by fractional values in the schedule named in the next field. + \note Required field when using Storage Operation Schemes FacilityDemandLeveling or TrackChargeDischargeSchedules. + \type real + \units W + A14, \field Storage Charge Power Fraction Schedule Name + \note Controls timing and magnitude of charging storage. + \note Required field if Storage Operation Scheme is set to TrackChargeDischargeSchedules. + \note Schedule values should be fractions from 0.0 to 1.0, inclusive. + \type object-list + \object-list ScheduleNames + N5 , \field Design Storage Control Discharge Power + \note Maximum rate that electric power can be discharged from storage. + \note Rate is modified by fractional values in the schedule named in the next field. + \note Required field when using Storage Operation Schemes FacilityDemandLeveling or TrackChargeDischargeSchedules. + \type real + \units W + A15, \field Storage Discharge Power Fraction Schedule Name + \note Controls timing and magnitude of discharging storage + \note Required field if Storage Operation Scheme is set to TrackChargeDischargeSchedules. + \note Schedule values should be fractions from 0.0 to 1.0, inclusive. + \type object-list + \object-list ScheduleNames + N6, \field Storage Control Utility Demand Target + \note Target utility service demand power for discharge control. Storage draws are adjusted upwards for conversion losses. + \note Required field for FacilityDemandLeveling storage operation scheme + \type real + \units W + A16; \field Storage Control Utility Demand Target Fraction Schedule Name + \note Modifies the target utility service demand power over time. + \note Schedule values should be fractions from -1.0 to 1.0, inclusive. + \note if omitted a schedule value of 1.0 is used. Negative values indicate export to grid + \note Schedule is used if Storage Operation Scheme is set to FacilityDemandLeveling. + \type object-list + \object-list ScheduleNames + +OS:ElectricLoadCenter:Storage:Converter, + \memo This model is for converting AC to DC for grid-supplied charging of DC storage + \min-fields 4 + A1 , \field Handle + \type handle + \required-field + A2 , \field Name + \reference ConverterList + A3 , \field Availability Schedule Name + \note Availability schedule name for this system. Schedule value > 0 means the system is available. + \note If this field is blank, the converter is always available. + \type object-list + \object-list ScheduleNames + A4 , \field Power Conversion Efficiency Method + \type choice + \key SimpleFixed + \default SimpleFixed + \note SimpleFixed indicates power conversion losses are based on Simple Fixed Efficiency + \key FunctionOfPower + \note FunctionOfPower indicates power conversion losses are a function of normalized power using a curve or table. + N1 , \field Simple Fixed Efficiency + \note Constant efficiency for conversion of AC to DC at all power levels. + \note Field is only used when Power Conversion Efficiency Method is set to SimpleFixed. + \type real + \minimum> 0.0 + \maximum 1.0 + \default 0.95 + N2, \field Design Maximum Continuous Input Power + \note Required field when Power Conversion Efficiency Method is set to FunctionOfPower. + \type real + \units W + A5 , \field Efficiency Function of Power Curve Name + \note Curve or table with a single independent variable that describes efficiency as a function of normalized power. + \note The "x" input for curve or table is the ratio of current input power divided by design power in the previous field + \note Required field when Power Conversion Efficiency Method is set to FunctionOfPower. + \type object-list + \object-list UniVariateCurves + \object-list UniVariateTables + N3 , \field Ancillary Power Consumed In Standby + \note Optional standby power consumed when converter is available but no power is being conditioned. + \type real + \units W + \default 0.0 + A6 , \field Zone Name + \note enter name of zone to receive converter losses as heat + \note if blank then converter is assumed to be outdoors + \type object-list + \object-list ZoneNames + N4 ; \field Radiative Fraction + \note fraction of zone heat gains treated as thermal radiation + \note Only used if a Zone Name is entered. + \minimum 0.0 + \maximum 1.0 + \default 0.0 + \memo This field was defaulted to 0.0 here, because the E+ doc says that if omitted, + \memo all zone heat gains will be convective \group OpenStudio Economics @@ -25747,8 +26223,8 @@ OS:OutputControl:ReportingTolerances, \minimum 0 \maximum 10 -OS:Meter, - \memo each OS:Meter command picks meters to be put onto the standard output file (.eso) and +OS:Output:Meter, + \memo each OS:Output:Meter command picks meters to be put onto the standard output file (.eso) and \memo meter file (.mtr). Not all meters are reported in every simulation. A list of \memo a list of meters that can be reported are available after a run on \memo the meter dictionary file (.mdd). @@ -25828,3 +26304,61 @@ OS:Output:Variable, \type object-list \object-list ScheduleNames +OS:Meter:Custom, + \extensible:2 + \memo Used to allow users to combine specific variables and/or meters into + \memo "custom" meter configurations. To access these meters by name, one must + \memo first run a simulation to generate the RDD/MDD files and names. + A1, \field Handle + \type handle + \required-field + A2, \field Name + \required-field + A3, \field Fuel Type + \type choice + \key Electricity + \key NaturalGas + \key PropaneGas + \key FuelOil#1 + \key FuelOil#2 + \key Coal + \key Diesel + \key Gasoline + \key Water + \key Generic + \key OtherFuel1 + \key OtherFuel2 + A4, \field Key Name + \begin-extensible + A5; \field Output Variable or Meter Name + +OS:Meter:CustomDecrement, + \extensible:2 - repeat last two fields, remembering to remove ; from "inner" fields. + \memo Used to allow users to combine specific variables and/or meters into + \memo "custom" meter configurations. To access these meters by name, one must + \memo first run a simulation to generate the RDD/MDD files and names. + A1, \field Handle + \type handle + \required-field + A2, \field Name + \required-field + A3, \field Fuel Type + \type choice + \key Electricity + \key NaturalGas + \key PropaneGas + \key FuelOil#1 + \key FuelOil#2 + \key Coal + \key Diesel + \key Gasoline + \key Water + \key Generic + \key OtherFuel1 + \key OtherFuel2 + A4, \field Source Meter Name + \required-field + A5, \field Key Name + \begin-extensible + A6; \field Output Variable or Meter Name + diff --git a/openstudiocore/ruby/openstudio.rb b/openstudiocore/ruby/openstudio.rb index 7d780022d27..928b3b60b06 100644 --- a/openstudiocore/ruby/openstudio.rb +++ b/openstudiocore/ruby/openstudio.rb @@ -198,6 +198,38 @@ # "typedefs" for backwards compatibility module OpenStudio + +# support for deprecated names +class IdfObject + def to_Meter + return to_OutputMeter + end +end + +module Model + +# support for deprecated names +class Model + def getMeter(handle) + return getOutputMeter(handle) + end + def getMeters + return getOutputMeters + end + def getMeterByName(name) + return getOutputMeterByName(name) + end + def getMetersByName(name) + return getOutputMetersByName(name) + end +end + +# support for name deprecated as of 1.12.1 +class Meter < OutputMeter +end + +end # module Model + module Ruleset # support for name deprecated as of 0.10.1 diff --git a/openstudiocore/ruby/openstudio_dev.rb b/openstudiocore/ruby/openstudio_dev.rb index 6f2ecada0cc..dfee2b88b95 100644 --- a/openstudiocore/ruby/openstudio_dev.rb +++ b/openstudiocore/ruby/openstudio_dev.rb @@ -113,7 +113,6 @@ require 'openstudiomodeleditor' require 'openstudioanalysis' require 'openstudiolib' -require 'openstudioosversion' require 'openstudioisomodel' require 'openstudiosdd' @@ -182,6 +181,38 @@ # "typedefs" for backwards compatibility module OpenStudio + +# support for deprecated names +class IdfObject + def to_Meter + return to_OutputMeter + end +end + +module Model + +# support for deprecated names +class Model + def getMeter(handle) + return getOutputMeter(handle) + end + def getMeters + return getOutputMeters + end + def getMeterByName(name) + return getOutputMeterByName(name) + end + def getMetersByName(name) + return getOutputMetersByName(name) + end +end + +# support for name deprecated as of 1.12.1 +class Meter < OutputMeter +end + +end # module Model + module Ruleset # support for name deprecated as of 0.10.1 diff --git a/openstudiocore/src/energyplus/CMakeLists.txt b/openstudiocore/src/energyplus/CMakeLists.txt index 67971db58f2..ad6a07684e4 100644 --- a/openstudiocore/src/energyplus/CMakeLists.txt +++ b/openstudiocore/src/energyplus/CMakeLists.txt @@ -118,6 +118,7 @@ set(${target_name}_src ForwardTranslator/ForwardTranslateElectricLoadCenterDistribution.cpp ForwardTranslator/ForwardTranslateElectricLoadCenterInverterLookUpTable.cpp ForwardTranslator/ForwardTranslateElectricLoadCenterInverterSimple.cpp + ForwardTranslator/ForwardTranslateElectricLoadCenterStorageSimple.cpp ForwardTranslator/ForwardTranslateEvaporativeCoolerDirectResearchSpecial.cpp ForwardTranslator/ForwardTranslateEvaporativeCoolerIndirectResearchSpecial.cpp ForwardTranslator/ForwardTranslateEvaporativeFluidCoolerSingleSpeed.cpp @@ -134,6 +135,7 @@ set(${target_name}_src ForwardTranslator/ForwardTranslateGasEquipment.cpp ForwardTranslator/ForwardTranslateGasMixture.cpp ForwardTranslator/ForwardTranslateGeneratorPhotovoltaic.cpp + ForwardTranslator/ForwardTranslateGeneratorMicroTurbine.cpp ForwardTranslator/ForwardTranslateGroundHeatExchangerHorizontalTrench.cpp ForwardTranslator/ForwardTranslateGroundHeatExchangerVertical.cpp ForwardTranslator/ForwardTranslateHeaderedPumpsConstantSpeed.cpp @@ -158,11 +160,13 @@ set(${target_name}_src ForwardTranslator/ForwardTranslateLuminaire.cpp ForwardTranslator/ForwardTranslateMaterialPropertyGlazingSpectralData.cpp ForwardTranslator/ForwardTranslateMasslessOpaqueMaterial.cpp - ForwardTranslator/ForwardTranslateMeter.cpp + ForwardTranslator/ForwardTranslateMeterCustom.cpp + ForwardTranslator/ForwardTranslateMeterCustomDecrement.cpp ForwardTranslator/ForwardTranslateNode.cpp ForwardTranslator/ForwardTranslateOtherEquipment.cpp ForwardTranslator/ForwardTranslateOutsideSurfaceConvectionAlgorithm.cpp ForwardTranslator/ForwardTranslateOutputControlReportingTolerances.cpp + ForwardTranslator/ForwardTranslateOutputMeter.cpp ForwardTranslator/ForwardTranslateOutputVariable.cpp ForwardTranslator/ForwardTranslatePeople.cpp ForwardTranslator/ForwardTranslatePhotovoltaicPerformanceEquivalentOneDiode.cpp @@ -354,12 +358,14 @@ set(${target_name}_src ReverseTranslator/ReverseTranslateDaylightingControls.cpp ReverseTranslator/ReverseTranslateDesignSpecificationOutdoorAir.cpp ReverseTranslator/ReverseTranslateElectricEquipment.cpp + ReverseTranslator/ReverseTranslateElectricLoadCenterStorageSimple.cpp ReverseTranslator/ReverseTranslateEvaporativeCoolerDirectResearchSpecial.cpp ReverseTranslator/ReverseTranslateEvaporativeFluidCoolerSingleSpeed.cpp ReverseTranslator/ReverseTranslateExteriorLights.cpp ReverseTranslator/ReverseTranslateFanConstantVolume.cpp ReverseTranslator/ReverseTranslateFenestrationSurfaceDetailed.cpp ReverseTranslator/ReverseTranslateGasEquipment.cpp + ReverseTranslator/ReverseTranslateGeneratorMicroTurbine.cpp ReverseTranslator/ReverseTranslateGroundHeatExchangerVertical.cpp ReverseTranslator/ReverseTranslateHeatBalanceAlgorithm.cpp ReverseTranslator/ReverseTranslateHotWaterEquipment.cpp @@ -368,6 +374,8 @@ set(${target_name}_src ReverseTranslator/ReverseTranslateMaterial.cpp ReverseTranslator/ReverseTranslateMaterialAirGap.cpp ReverseTranslator/ReverseTranslateMaterialNoMass.cpp + ReverseTranslator/ReverseTranslateMeterCustom.cpp + ReverseTranslator/ReverseTranslateMeterCustomDecrement.cpp ReverseTranslator/ReverseTranslateOtherEquipment.cpp ReverseTranslator/ReverseTranslateOutputIlluminanceMap.cpp ReverseTranslator/ReverseTranslateOutputMeter.cpp diff --git a/openstudiocore/src/energyplus/ForwardTranslator.cpp b/openstudiocore/src/energyplus/ForwardTranslator.cpp index 19a2af4fd3b..1cee3b294d6 100644 --- a/openstudiocore/src/energyplus/ForwardTranslator.cpp +++ b/openstudiocore/src/energyplus/ForwardTranslator.cpp @@ -259,6 +259,16 @@ Workspace ForwardTranslator::translateModelPrivate( model::Model & model, bool f } } } + + // remove orphan Generator:MicroTurbine + for (auto& chp : model.getConcreteModelObjects()){ + if (!chp.electricLoadCenterDistribution()){ + LOG(Warn, "GeneratorMicroTurbine " << chp.name().get() << " is not referenced by any ElectricLoadCenterDistribution, it will not be translated."); + chp.remove(); + continue; + } + } + // remove orphan photovoltaics for (auto& pv : model.getConcreteModelObjects()){ @@ -369,8 +379,8 @@ Workspace ForwardTranslator::translateModelPrivate( model::Model & model, bool f std::vector utilityBills = model.getConcreteModelObjects(); for (UtilityBill utilityBill : utilityBills){ // these meters and variables will be translated later - Meter consumptionMeter = utilityBill.consumptionMeter(); - boost::optional peakDemandMeter = utilityBill.peakDemandMeter(); + OutputMeter consumptionMeter = utilityBill.consumptionMeter(); + boost::optional peakDemandMeter = utilityBill.peakDemandMeter(); } } @@ -1307,6 +1317,12 @@ boost::optional ForwardTranslator::translateAndMapModelObject(ModelOb retVal = translateElectricLoadCenterInverterSimple(temp); break; } + case openstudio::IddObjectType::OS_ElectricLoadCenter_Storage_Simple: + { + model::ElectricLoadCenterStorageSimple temp = modelObject.cast(); + retVal = translateElectricLoadCenterStorageSimple(temp); + break; + } case openstudio::IddObjectType::OS_EvaporativeCooler_Direct_ResearchSpecial : { model::EvaporativeCoolerDirectResearchSpecial evap = modelObject.cast(); @@ -1384,6 +1400,13 @@ boost::optional ForwardTranslator::translateAndMapModelObject(ModelOb retVal = translateFluidCoolerTwoSpeed(fluidCoolerTwoSpeed); break; } + case openstudio::IddObjectType::OS_Generator_MicroTurbine: + { + // Will also translate the Generator:MicroTurbine:HeatRecovery if there is one + model::GeneratorMicroTurbine temp = modelObject.cast(); + retVal = translateGeneratorMicroTurbine(temp); + break; + } case openstudio::IddObjectType::OS_Generator_Photovoltaic: { model::GeneratorPhotovoltaic temp = modelObject.cast(); @@ -1650,10 +1673,16 @@ boost::optional ForwardTranslator::translateAndMapModelObject(ModelOb retVal = translateRoofVegetation(material); break; } - case openstudio::IddObjectType::OS_Meter : + case openstudio::IddObjectType::OS_Meter_Custom : + { + model::MeterCustom meterCustom = modelObject.cast(); + retVal = translateMeterCustom(meterCustom); + break; + } + case openstudio::IddObjectType::OS_Meter_CustomDecrement : { - model::Meter meter = modelObject.cast(); - retVal = translateMeter(meter); + model::MeterCustomDecrement meterCustomDecrement = modelObject.cast(); + retVal = translateMeterCustomDecrement(meterCustomDecrement); break; } case openstudio::IddObjectType::OS_ModelObjectList : @@ -1774,6 +1803,12 @@ boost::optional ForwardTranslator::translateAndMapModelObject(ModelOb retVal = translateOutputControlReportingTolerances(outputControl); break; } + case openstudio::IddObjectType::OS_Output_Meter : + { + model::OutputMeter meter = modelObject.cast(); + retVal = translateOutputMeter(meter); + break; + } case openstudio::IddObjectType::OS_Output_Variable : { model::OutputVariable outputVariable = modelObject.cast(); @@ -2879,16 +2914,20 @@ std::vector ForwardTranslator::iddObjectsToTranslateInitializer() result.push_back(IddObjectType::OS_Refrigeration_TranscriticalSystem); result.push_back(IddObjectType::OS_ElectricLoadCenter_Distribution); + result.push_back(IddObjectType::OS_Generator_MicroTurbine); result.push_back(IddObjectType::OS_Generator_Photovoltaic); result.push_back(IddObjectType::OS_PhotovoltaicPerformance_EquivalentOneDiode); result.push_back(IddObjectType::OS_PhotovoltaicPerformance_Simple); result.push_back(IddObjectType::OS_ElectricLoadCenter_Inverter_LookUpTable); result.push_back(IddObjectType::OS_ElectricLoadCenter_Inverter_Simple); + result.push_back(IddObjectType::OS_ElectricLoadCenter_Storage_Simple); // put these down here so they have a chance to be translated with their "parent" result.push_back(IddObjectType::OS_LifeCycleCost); - result.push_back(IddObjectType::OS_Meter); + result.push_back(IddObjectType::OS_Output_Meter); + result.push_back(IddObjectType::OS_Meter_Custom); + result.push_back(IddObjectType::OS_Meter_CustomDecrement); result.push_back(IddObjectType::OS_Output_Variable); return result; diff --git a/openstudiocore/src/energyplus/ForwardTranslator.hpp b/openstudiocore/src/energyplus/ForwardTranslator.hpp index 53ce39cfcfe..3e6cb475a09 100644 --- a/openstudiocore/src/energyplus/ForwardTranslator.hpp +++ b/openstudiocore/src/energyplus/ForwardTranslator.hpp @@ -142,6 +142,7 @@ class ElectricEquipment; class ElectricLoadCenterDistribution; class ElectricLoadCenterInverterLookUpTable; class ElectricLoadCenterInverterSimple; +class ElectricLoadCenterStorageSimple; class EvaporativeCoolerDirectResearchSpecial; class EvaporativeCoolerIndirectResearchSpecial; class EvaporativeFluidCoolerSingleSpeed; @@ -157,6 +158,7 @@ class FluidCoolerTwoSpeed; class Gas; class GasEquipment; class GasMixture; +class GeneratorMicroTurbine; class GeneratorPhotovoltaic; class GroundHeatExchangerHorizontalTrench; class GroundHeatExchangerVertical; @@ -182,11 +184,13 @@ class Lights; class Luminaire; class MaterialPropertyGlazingSpectralData; class MasslessOpaqueMaterial; -class Meter; +class MeterCustom; +class MeterCustomDecrement; class Node; class OtherEquipment; class OutsideSurfaceConvectionAlgorithm; class OutputControlReportingTolerances; +class OutputMeter; class OutputVariable; class People; class PhotovoltaicPerformanceEquivalentOneDiode; @@ -633,6 +637,8 @@ class ENERGYPLUS_API ForwardTranslator { boost::optional translateElectricLoadCenterInverterLookUpTable( model::ElectricLoadCenterInverterLookUpTable & modelObject ); boost::optional translateElectricLoadCenterInverterSimple( model::ElectricLoadCenterInverterSimple & modelObject ); + + boost::optional translateElectricLoadCenterStorageSimple( model::ElectricLoadCenterStorageSimple & modelObject ); boost::optional translateEvaporativeFluidCoolerSingleSpeed( model::EvaporativeFluidCoolerSingleSpeed & modelObject ); @@ -664,6 +670,8 @@ class ENERGYPLUS_API ForwardTranslator { boost::optional translateGasMixture( model::GasMixture & modelObject ); + boost::optional translateGeneratorMicroTurbine( model::GeneratorMicroTurbine & modelObject ); + boost::optional translateGeneratorPhotovoltaic( model::GeneratorPhotovoltaic & modelObject ); boost::optional translateGroundHeatExchangerHorizontalTrench( model::GroundHeatExchangerHorizontalTrench & modelObject ); @@ -713,8 +721,10 @@ class ENERGYPLUS_API ForwardTranslator { boost::optional translateMaterialPropertyGlazingSpectralData( model::MaterialPropertyGlazingSpectralData & modelObject ); boost::optional translateMasslessOpaqueMaterial( model::MasslessOpaqueMaterial & modelObject ); - - boost::optional translateMeter( model::Meter & modelObject ); + + boost::optional translateMeterCustom( model::MeterCustom & modelObject ); + + boost::optional translateMeterCustomDecrement( model::MeterCustomDecrement & modelObject ); boost::optional translateNode( model::Node & modelObject ); @@ -724,6 +734,8 @@ class ENERGYPLUS_API ForwardTranslator { boost::optional translateOutputControlReportingTolerances( model::OutputControlReportingTolerances & modelObject ); + boost::optional translateOutputMeter( model::OutputMeter & modelObject ); + boost::optional translateOutputVariable( model::OutputVariable & modelObject ); boost::optional translatePeople( model::People & modelObject ); diff --git a/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateElectricLoadCenterDistribution.cpp b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateElectricLoadCenterDistribution.cpp index 9805fb32a22..d1b46f45acd 100644 --- a/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateElectricLoadCenterDistribution.cpp +++ b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateElectricLoadCenterDistribution.cpp @@ -23,6 +23,8 @@ #include "../../model/ElectricLoadCenterDistribution.hpp" #include "../../model/ElectricLoadCenterDistribution_Impl.hpp" #include "../../model/Inverter.hpp" +#include "../../model/ElectricalStorage.hpp" +//#include "../../model/ElectricLoadCenterStorageConverter.hpp" #include "../../model/Generator.hpp" #include "../../model/Schedule.hpp" @@ -43,7 +45,9 @@ namespace energyplus { boost::optional ForwardTranslator::translateElectricLoadCenterDistribution(model::ElectricLoadCenterDistribution & modelObject) { - boost::optional d; + boost::optional optD; + std::string s; + boost::optional optS; boost::optional schedule; IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::ElectricLoadCenter_Distribution, modelObject); @@ -56,29 +60,17 @@ boost::optional ForwardTranslator::translateElectricLoadCenterDistrib idfObject.setString(ElectricLoadCenter_DistributionFields::GeneratorOperationSchemeType, modelObject.generatorOperationSchemeType()); - //idfObject.setDouble(ElectricLoadCenter_DistributionFields::DemandLimitSchemePurchasedElectricDemandLimit, modelObject.demandLimitSchemePurchasedElectricDemandLimit()); - - //idfObject.setString(ElectricLoadCenter_DistributionFields::TrackScheduleNameSchemeScheduleName, modelObject.trackScheduleNameSchemeSchedule()); - - //idfObject.setString(ElectricLoadCenter_DistributionFields::TrackMeterSchemeMeterName, modelObject.trackMeterSchemeMeter()); - - idfObject.setString(ElectricLoadCenter_DistributionFields::ElectricalBussType, modelObject.electricalBussType()); + if (optD = modelObject.demandLimitSchemePurchasedElectricDemandLimit()) { + idfObject.setDouble(ElectricLoadCenter_DistributionFields::GeneratorDemandLimitSchemePurchasedElectricDemandLimit, optD.get()); + } - boost::optional inverter = modelObject.inverter(); - if (inverter){ - boost::optional inverterIdf = translateAndMapModelObject(*inverter); - if (inverterIdf){ - idfObject.setString(ElectricLoadCenter_DistributionFields::InverterName, inverterIdf->name().get()); - } + if (schedule = modelObject.trackScheduleSchemeSchedule()) { + idfObject.setString(ElectricLoadCenter_DistributionFields::GeneratorTrackScheduleNameSchemeScheduleName, schedule->name().get()); } - //boost::optional storage = modelObject.storage(); - //if (storage){ - // boost::optional storageIdf = translateAndMapModelObject(storage); - // if (storageIdf){ - // idfObject.setString(ElectricLoadCenter_DistributionFields::ElectricalStorageObjectName, storageIdf->name().get()); - // } - //} + if ( optS = modelObject.trackMeterSchemeMeterName() ) { + idfObject.setString(ElectricLoadCenter_DistributionFields::GeneratorTrackMeterSchemeMeterName, (*optS) ); + } //boost::optional transformer = modelObject.transformer(); //if (transformer){ @@ -88,38 +80,222 @@ boost::optional ForwardTranslator::translateElectricLoadCenterDistrib // } //} - for (auto& generator : modelObject.generators()){ + for (auto& generator : modelObject.generators()) { boost::optional generatorIdf = translateAndMapModelObject(generator); - if (generatorIdf){ + if (generatorIdf) { IdfExtensibleGroup generatorGroup = generatorsIdf.pushExtensibleGroup(); generatorGroup.setString(ElectricLoadCenter_GeneratorsExtensibleFields::GeneratorName, generatorIdf->name().get()); - + generatorGroup.setString(ElectricLoadCenter_GeneratorsExtensibleFields::GeneratorObjectType, generator.generatorObjectType()); - - d = generator.ratedElectricPowerOutput(); - if (d){ - generatorGroup.setDouble(ElectricLoadCenter_GeneratorsExtensibleFields::GeneratorRatedElectricPowerOutput, *d); + + optD = generator.ratedElectricPowerOutput(); + if (optD) { + generatorGroup.setDouble(ElectricLoadCenter_GeneratorsExtensibleFields::GeneratorRatedElectricPowerOutput, *optD); } - + schedule = generator.availabilitySchedule(); - if (schedule){ + if (schedule) { boost::optional scheduleIdf = translateAndMapModelObject(*schedule); - if (scheduleIdf){ + if (scheduleIdf) { generatorGroup.setString(ElectricLoadCenter_GeneratorsExtensibleFields::GeneratorAvailabilityScheduleName, scheduleIdf->name().get()); } } - d = generator.ratedThermalToElectricalPowerRatio(); - if (d){ - generatorGroup.setDouble(ElectricLoadCenter_GeneratorsExtensibleFields::GeneratorRatedThermaltoElectricalPowerRatio, *d); + optD = generator.ratedThermaltoElectricalPowerRatio(); + if (optD) { + generatorGroup.setDouble(ElectricLoadCenter_GeneratorsExtensibleFields::GeneratorRatedThermaltoElectricalPowerRatio, *optD); } - } else{ + } else { LOG(Warn, "Could not translate generator '" << generator.name().get() << "' on ElectricLoadCenter:Distribution '" << idfObject.name().get() << "'") } } + // NEW + + // Logic based on Electrical Buss Type to translate or not translate inverters, storage + std::string bussType = modelObject.electricalBussType(); + + // Translate the buss Type already + idfObject.setString(ElectricLoadCenter_DistributionFields::ElectricalBussType, bussType); + + /// Inverter and Buss Type + boost::optional inverter = modelObject.inverter(); + bool bussWithInverter = (bussType == "DirectCurrentWithInverter" || + bussType == "DirectCurrentWithInverterDCStorage" || + bussType == "DirectCurrentWithInverterACStorage"); + + // Case 1: There is an inverter and a Buss with inverter: all good + if (inverter && bussWithInverter) { + boost::optional inverterIdf = translateAndMapModelObject(*inverter); + if (inverterIdf) { + idfObject.setString(ElectricLoadCenter_DistributionFields::InverterName, inverterIdf->name().get()); + } + + // Case 2: if there's an inverter, but the buss is not compatible, we issue a Warning and don't translate the inverter + } else if (inverter && !bussWithInverter) { + LOG(Warn, modelObject.briefDescription() << ": Your Electric Buss Type '" << bussType + << "' is not compatible with inverter objects. The inverter object '" + << inverter->name().get() << " will not be translated'"); + + // Case 3: if there is a buss that expects an inverter, but not inverter: this is bad, it'll throw a fatal in E+ + } else if (bussWithInverter && !inverter) { + LOG(Error, modelObject.briefDescription() << ": Your Electric Buss Type '" << bussType + << "' Requires an inverter but you didn't specify one"); + } + // Case 4: there's no inverter and a buss type without inverter: nothing needs to be done + + + /// Storage & Buss Type + boost::optional electricalStorage = modelObject.electricalStorage(); + bool bussWithStorage = (bussType == "AlternatingCurrentWithStorage" || + bussType == "DirectCurrentWithInverterDCStorage" || + bussType == "DirectCurrentWithInverterACStorage"); + + // Case 1: There is a Storage object and a Buss with Storage: all good + if (electricalStorage && bussWithStorage) { + + // Translate the storage object itself + boost::optional storageIdf = translateAndMapModelObject(*electricalStorage); + if (storageIdf) { + idfObject.setString(ElectricLoadCenter_DistributionFields::ElectricalStorageObjectName, storageIdf->name().get()); + } + + // Storage Operation Scheme, defaults to TrackFacilityElectricDemandStoreExcessOnSite + std::string storageOperationScheme = modelObject.storageOperationScheme(); + + if (!modelObject.isStorageOperationSchemeDefaulted()) { + idfObject.setString(ElectricLoadCenter_DistributionFields::StorageOperationScheme, storageOperationScheme); + } + + // For all storageOperationScheme, we need to translate the Min/Max Storage SOC + // Maximum Storage State of Charge Fraction, defaults + idfObject.setDouble(ElectricLoadCenter_DistributionFields::MaximumStorageStateofChargeFraction, modelObject.maximumStorageStateofChargeFraction()); + + // Minimum Storage State of Charge Fraction, defaults + idfObject.setDouble(ElectricLoadCenter_DistributionFields::MinimumStorageStateofChargeFraction, modelObject.minimumStorageStateofChargeFraction()); + + /// Further testing based on storageOperationScheme + if (storageOperationScheme == "TrackMeterDemandStoreExcessOnSite") { + // Storage Control Track Meter Name, required if operation = TrackMeterDemandStoreExcessOnSite or it'll produce a fatal + if (optS = modelObject.storageControlTrackMeterName()) { + idfObject.setString(ElectricLoadCenter_DistributionFields::StorageControlTrackMeterName, (*optS)); + } else { + LOG(Error, modelObject.briefDescription() << ": You set the Storage Operation Scheme to " << storageOperationScheme + << " but you didn't specify the required 'Storage Control Track Meter Name'"); + } + + } else if (storageOperationScheme == "TrackChargeDischargeSchedules") { + // Storage Converter Object Name + //boost::optional storageConverter = modelObject.storageConverter(); + //if (storageConverter) { + // // If the buss is compatible, we translate the invert + // boost::optional storageConverterIdf = translateAndMapModelObject(*storageConverter); + // if (storageConverterIdf) { + // idfObject.setString(ElectricLoadCenter_DistributionFields + // ::StorageConverterObjectName, storageConverterIdf->name().get()); + // } + //} else { + // LOG(Error, modelObject.briefDescription() << ": You set the Storage Operation Scheme to " << storageOperationScheme + // << " but you didn't specify the required 'Storage Converter Object Name'"); + //} + + // Design Storage Control Charge Power + if (optD = modelObject.designStorageControlChargePower()) { + idfObject.setDouble(ElectricLoadCenter_DistributionFields::DesignStorageControlChargePower, optD.get()); + } else { + LOG(Error, modelObject.briefDescription() << ": You set the Storage Operation Scheme to " << storageOperationScheme + << " but you didn't specify the required 'Design Storage Control Charge Power'"); + } + + // Design Storage Control Discharge Power + if (optD = modelObject.designStorageControlDischargePower()) { + idfObject.setDouble(ElectricLoadCenter_DistributionFields::DesignStorageControlDischargePower, optD.get()); + } else { + LOG(Error, modelObject.briefDescription() << ": You set the Storage Operation Scheme to " << storageOperationScheme + << " but you didn't specify the required 'Design Storage Control Discharge Power'"); + } + + // Storage Charge Power Fraction Schedule Name + if (schedule = modelObject.storageChargePowerFractionSchedule()) { + idfObject.setString(ElectricLoadCenter_DistributionFields::StorageChargePowerFractionScheduleName, schedule->name().get()); + } else { + LOG(Error, modelObject.briefDescription() << ": You set the Storage Operation Scheme to " << storageOperationScheme + << " but you didn't specify the required 'Storage Charge Power Fraction Schedule Name'"); + } + + // Discharge Power Fraction Schedule Name + if (schedule = modelObject.storageDischargePowerFractionSchedule()) { + idfObject.setString(ElectricLoadCenter_DistributionFields::StorageDischargePowerFractionScheduleName, schedule->name().get()); + } else { + LOG(Error, modelObject.briefDescription() << ": You set the Storage Operation Scheme to " << storageOperationScheme + << " but you didn't specify the required 'Storage Discharge Power Fraction Schedule Name'"); + } + + } else if (storageOperationScheme == "FacilityDemandLeveling") { + // Storage Converter Object Name + //boost::optional storageConverter = modelObject.storageConverter(); + //if (storageConverter) { + // // If the buss is compatible, we translate the invert + // boost::optional storageConverterIdf = translateAndMapModelObject(*storageConverter); + // if (storageConverterIdf) { + // idfObject.setString(ElectricLoadCenter_DistributionFields + // ::StorageConverterObjectName, storageConverterIdf->name().get()); + // } + //} else { + // LOG(Error, modelObject.briefDescription() << ": You set the Storage Operation Scheme to " << storageOperationScheme + // << " but you didn't specify the required 'Storage Converter Object Name'"); + //} + + // Design Storage Control Charge Power + if (optD = modelObject.designStorageControlChargePower()) { + idfObject.setDouble(ElectricLoadCenter_DistributionFields::DesignStorageControlChargePower, optD.get()); + } else { + LOG(Error, modelObject.briefDescription() << ": You set the Storage Operation Scheme to " << storageOperationScheme + << " but you didn't specify the required 'Design Storage Control Charge Power'"); + } + + // Design Storage Control Discharge Power + if (optD = modelObject.designStorageControlDischargePower()) { + idfObject.setDouble(ElectricLoadCenter_DistributionFields::DesignStorageControlDischargePower, optD.get()); + } else { + LOG(Error, modelObject.briefDescription() << ": You set the Storage Operation Scheme to " << storageOperationScheme + << " but you didn't specify the required 'Design Storage Control Discharge Power'"); + } + + // Storage Control Utility Demand Target + if (optD = modelObject.storageControlUtilityDemandTarget()) { + idfObject.setDouble(ElectricLoadCenter_DistributionFields::StorageControlUtilityDemandTarget, optD.get()); + } else { + LOG(Error, modelObject.briefDescription() << ": You set the Storage Operation Scheme to " << storageOperationScheme + << " but you didn't specify the required 'Storage Control Utility Demand Target'"); + } + + // Storage Control Utility Demand Target Fraction Schedule Name + // This defaults to always 1.0 if omitted + idfObject.setString(ElectricLoadCenter_DistributionFields::StorageControlUtilityDemandTargetFractionScheduleName, + modelObject.storageControlUtilityDemandTargetFractionSchedule().name().get()); + + + } // end if (storageOperationScheme) + + // Case 2: if there's a Storage object, but the buss is not compatible, we issue a Warning and don't translate Any of the storage objects + } else if (electricalStorage && !bussWithStorage) { + LOG(Warn, modelObject.briefDescription() << ": Your Electric Buss Type '" << bussType + << "' is not compatible with storage objects. No storage objects will be translated including the Battery itself:'" + << electricalStorage->name().get() << "'"); + + // Case 3: if there is a buss that expects Storage, but no Storage: this is bad, it'll throw a fatal in E+ + } else if (bussWithStorage && !electricalStorage) { + LOG(Error, modelObject.briefDescription() << ": Your Electric Buss Type '" << bussType + << "' Requires an electrical Storage object but you didn't specify one"); + } + // Case 4: there's no inverter and a buss type without inverter: nothing needs to be done + + + + return idfObject; } diff --git a/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateElectricLoadCenterStorageSimple.cpp b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateElectricLoadCenterStorageSimple.cpp new file mode 100644 index 00000000000..a7ea48bb154 --- /dev/null +++ b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateElectricLoadCenterStorageSimple.cpp @@ -0,0 +1,110 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include "../ForwardTranslator.hpp" + +#include "../../model/Model.hpp" +#include "../../model/ElectricLoadCenterStorageSimple.hpp" +#include "../../model/ElectricLoadCenterStorageSimple_Impl.hpp" + +#include "../../model/Schedule.hpp" +#include "../../model/Schedule_Impl.hpp" +#include "../../model/ThermalZone.hpp" +#include "../../model/ThermalZone_Impl.hpp" + +#include +#include "../../utilities/idd/IddEnums.hpp" +#include + +using namespace openstudio::model; + +using namespace std; + +namespace openstudio { + +namespace energyplus { + +boost::optional ForwardTranslator::translateElectricLoadCenterStorageSimple(model::ElectricLoadCenterStorageSimple & modelObject) +{ + IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::ElectricLoadCenter_Storage_Simple, modelObject); + + if (modelObject.name()) { + idfObject.setString(ElectricLoadCenter_Storage_SimpleFields::Name, modelObject.name().get()); + } + + // Availability Schedule, defaults to model.alwaysOnDiscrete + if (modelObject.availabilitySchedule().name()) { + idfObject.setString(ElectricLoadCenter_Storage_SimpleFields::AvailabilityScheduleName, modelObject.availabilitySchedule().name().get()); + } + + // ZoneName + if (modelObject.thermalZone() && modelObject.thermalZone().get().name()) { + idfObject.setString(ElectricLoadCenter_Storage_SimpleFields::ZoneName, modelObject.thermalZone().get().name().get()); + } + + // Radiative Fraction, defaults (double) + { + double value = modelObject.radiativeFractionforZoneHeatGains(); + idfObject.setDouble(ElectricLoadCenter_Storage_SimpleFields::RadiativeFractionforZoneHeatGains, value); + } + + // nominalEnergeticEfficiencyforCharging, defaults + { + double value = modelObject.nominalEnergeticEfficiencyforCharging(); + idfObject.setDouble(ElectricLoadCenter_Storage_SimpleFields::NominalEnergeticEfficiencyforCharging, value); + } + + // nominalEnergeticEfficiencyforDischarging, defaults + { + double value = modelObject.nominalDischargingEnergeticEfficiency(); + idfObject.setDouble(ElectricLoadCenter_Storage_SimpleFields::NominalDischargingEnergeticEfficiency, value); + } + + // maximumStorageCapacity, required, assigned in ctor + { + double value = modelObject.maximumStorageCapacity(); + idfObject.setDouble(ElectricLoadCenter_Storage_SimpleFields::MaximumStorageCapacity, value); + } + + // maximumPowerforDischarging, required, assigned in ctor + { + double value = modelObject.maximumPowerforDischarging(); + idfObject.setDouble(ElectricLoadCenter_Storage_SimpleFields::MaximumPowerforDischarging, value); + } + + // maximumPowerforCharging, required, assigned in ctor + { + double value = modelObject.maximumPowerforCharging(); + idfObject.setDouble(ElectricLoadCenter_Storage_SimpleFields::MaximumPowerforCharging, value); + } + + // initialStateofCharge + { + double value = modelObject.initialStateofCharge(); + idfObject.setDouble(ElectricLoadCenter_Storage_SimpleFields::InitialStateofCharge, value); + } + + + return idfObject; +} + +} // energyplus + +} // openstudio + diff --git a/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateGeneratorMicroTurbine.cpp b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateGeneratorMicroTurbine.cpp new file mode 100644 index 00000000000..117ad67878f --- /dev/null +++ b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateGeneratorMicroTurbine.cpp @@ -0,0 +1,315 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include "../ForwardTranslator.hpp" + +#include "../../model/Model.hpp" + +#include "../../model/GeneratorMicroTurbine.hpp" +#include "../../model/GeneratorMicroTurbine_Impl.hpp" + +#include "../../model/StraightComponent.hpp" +#include "../../model/StraightComponent_Impl.hpp" +#include "../../model/Node.hpp" // Is this needed? +#include "../../model/Node_Impl.hpp" +#include "../../model/Curve.hpp" +#include "../../model/Curve_Impl.hpp" + +#include "../../model/GeneratorMicroTurbineHeatRecovery.hpp" +#include "../../model/GeneratorMicroTurbineHeatRecovery_Impl.hpp" + +#include +#include "../../utilities/idd/IddEnums.hpp" +#include + +using namespace openstudio::model; + +using namespace std; + +namespace openstudio { + +namespace energyplus { + +boost::optional ForwardTranslator::translateGeneratorMicroTurbine(model::GeneratorMicroTurbine & modelObject) +{ + IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::Generator_MicroTurbine, modelObject); + + + //get the GeneratorMicroTurbineHeatRecovery as an optional straight component, if exists cast it to optional GeneratorMicroTurbineHeatRecovery + // if cast is successful, get the object of class GeneratorMicroTurbineHeatRecovery + boost::optional generatorOptionalMicroTurbineHeatRecovery = modelObject.generatorMicroTurbineHeatRecovery(); + // If there is a Heat Recovery Object + if (generatorOptionalMicroTurbineHeatRecovery) { + // Get it + GeneratorMicroTurbineHeatRecovery generatorMCHPHX = *generatorOptionalMicroTurbineHeatRecovery; + + // HeatRecoveryWaterInletNodeName + // Inlet Node Name + if ( auto temp = generatorMCHPHX.inletModelObject() ) + { + auto s = temp->name(); + if(s) + { + idfObject.setString(openstudio::Generator_MicroTurbineFields::HeatRecoveryWaterInletNodeName,*s); + } + } + + //HeatRecoveryWaterOutletNodeName + if ( auto temp = generatorMCHPHX.outletModelObject() ) { + auto s = temp->name(); + if (s) { + idfObject.setString(openstudio::Generator_MicroTurbineFields::HeatRecoveryWaterOutletNodeName, *s); + } + } + + //ReferenceThermalEfficiencyUsingLowerHeatValue + { + auto value = generatorMCHPHX.referenceThermalEfficiencyUsingLowerHeatValue(); + idfObject.setDouble(Generator_MicroTurbineFields::ReferenceThermalEfficiencyUsingLowerHeatValue, value); + } + + //ReferenceInletWaterTemperature (double) + idfObject.setDouble(Generator_MicroTurbineFields::ReferenceInletWaterTemperature, generatorMCHPHX.referenceInletWaterTemperature()); + + + //HeatRecoveryWaterFlowOperatingMode + { + auto value = generatorMCHPHX.heatRecoveryWaterFlowOperatingMode(); + idfObject.setString(Generator_MicroTurbineFields::HeatRecoveryWaterFlowOperatingMode,value); + } + + //ReferenceHeatRecoveryWaterFlowRate (double) + idfObject.setDouble(Generator_MicroTurbineFields::ReferenceHeatRecoveryWaterFlowRate, generatorMCHPHX.referenceHeatRecoveryWaterFlowRate()); + + + //HeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve + if( auto curve = generatorMCHPHX.heatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve() ) { + if( auto _curve = translateAndMapModelObject(curve.get()) ) { + idfObject.setString(Generator_MicroTurbineFields::HeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurveName,_curve->name().get()); + } + } + + //ThermalEfficiencyFunctionofTemperatureandElevationCurve + if( auto curve = generatorMCHPHX.thermalEfficiencyFunctionofTemperatureandElevationCurve() ) { + if( auto _curve = translateAndMapModelObject(curve.get()) ) { + idfObject.setString(Generator_MicroTurbineFields::ThermalEfficiencyFunctionofTemperatureandElevationCurveName,_curve->name().get()); + } + } + + //HeatRecoveryRateFunctionofPartLoadRatioCurve + if( auto curve = generatorMCHPHX.heatRecoveryRateFunctionofPartLoadRatioCurve() ) { + if( auto _curve = translateAndMapModelObject(curve.get()) ) { + idfObject.setString(Generator_MicroTurbineFields::HeatRecoveryRateFunctionofPartLoadRatioCurveName,_curve->name().get()); + } + } + + //HeatRecoveryRateFunctionofInletWaterTemperatureCurve + if( auto curve = generatorMCHPHX.heatRecoveryRateFunctionofInletWaterTemperatureCurve() ) { + if( auto _curve = translateAndMapModelObject(curve.get()) ) { + idfObject.setString(Generator_MicroTurbineFields::HeatRecoveryRateFunctionofInletWaterTemperatureCurveName,_curve->name().get()); + } + } + + //HeatRecoveryRateFunctionofWaterFlowRateCurve + if( auto curve = generatorMCHPHX.heatRecoveryRateFunctionofWaterFlowRateCurve() ) { + if( auto _curve = translateAndMapModelObject(curve.get()) ) { + idfObject.setString(Generator_MicroTurbineFields::HeatRecoveryRateFunctionofWaterFlowRateCurveName,_curve->name().get()); + } + } + + //MinimumHeatRecoveryWaterFlowRate + { + auto value = generatorMCHPHX.minimumHeatRecoveryWaterFlowRate(); + idfObject.setDouble(Generator_MicroTurbineFields::MinimumHeatRecoveryWaterFlowRate,value); + } + + //MaximumHeatRecoveryWaterFlowRate + { + auto value = generatorMCHPHX.maximumHeatRecoveryWaterFlowRate(); + idfObject.setDouble(Generator_MicroTurbineFields::MaximumHeatRecoveryWaterFlowRate,value); + } + + //MaximumHeatRecoveryWaterTemperature + if( auto value = generatorMCHPHX.maximumHeatRecoveryWaterTemperature() ) + { + idfObject.setDouble(Generator_MicroTurbineFields::MaximumHeatRecoveryWaterTemperature,value.get()); + } + } + + + /// Doubles, non optional + //ReferenceElectricalPowerOutput + idfObject.setDouble(Generator_MicroTurbineFields::ReferenceElectricalPowerOutput, modelObject.referenceElectricalPowerOutput()); + + //ReferenceElectricalEfficiencyUsingLowerHeatingValue + idfObject.setDouble(Generator_MicroTurbineFields::ReferenceElectricalEfficiencyUsingLowerHeatingValue, modelObject.referenceElectricalEfficiencyUsingLowerHeatingValue()); + + + /// Doubles, optional + //MinimumFullLoadElectricalPowerOutput + { + auto value = modelObject.minimumFullLoadElectricalPowerOutput(); + idfObject.setDouble(Generator_MicroTurbineFields::MinimumFullLoadElectricalPowerOutput,value); + } + + //MaximumFullLoadElectricalPowerOutput + { + auto value = modelObject.maximumFullLoadElectricalPowerOutput(); + idfObject.setDouble(Generator_MicroTurbineFields::MaximumFullLoadElectricalPowerOutput,value); + } + + //ReferenceCombustionAirInletTemperature + { + auto value = modelObject.referenceCombustionAirInletTemperature(); + idfObject.setDouble(Generator_MicroTurbineFields::ReferenceCombustionAirInletTemperature,value); + } + + //ReferenceCombustionAirInletHumidityRatio + { + auto value = modelObject.referenceCombustionAirInletHumidityRatio(); + idfObject.setDouble(Generator_MicroTurbineFields::ReferenceCombustionAirInletHumidityRatio,value); + } + + //ReferenceElevation + { + auto value = modelObject.referenceElevation(); + idfObject.setDouble(Generator_MicroTurbineFields::ReferenceElevation,value); + } + + //FuelHigherHeatingValue + { + auto value = modelObject.fuelHigherHeatingValue(); + idfObject.setDouble(Generator_MicroTurbineFields::FuelHigherHeatingValue,value); + } + + //FuelLowerHeatingValue + { + auto value = modelObject.fuelLowerHeatingValue(); + idfObject.setDouble(Generator_MicroTurbineFields::FuelLowerHeatingValue,value); + } + + //StandbyPower + { + auto value = modelObject.standbyPower(); + idfObject.setDouble(Generator_MicroTurbineFields::StandbyPower,value); + } + + //AncillaryPower + { + auto value = modelObject.ancillaryPower(); + idfObject.setDouble(Generator_MicroTurbineFields::AncillaryPower,value); + } + + //ReferenceExhaustAirMassFlowRate + if( auto value = modelObject.referenceExhaustAirMassFlowRate() ) + { + idfObject.setDouble(Generator_MicroTurbineFields::ReferenceExhaustAirMassFlowRate,value.get()); + } + + //NominalExhaustAirOutletTemperature + if( auto value = modelObject.nominalExhaustAirOutletTemperature() ) + { + idfObject.setDouble(Generator_MicroTurbineFields::NominalExhaustAirOutletTemperature,value.get()); + } + + /// Choice + //FuelType + { + auto s = modelObject.fuelType(); + idfObject.setString(Generator_MicroTurbineFields::FuelType,s); + } + + + /// Nodes + + // Will leave blank to assume outside air conditions + //CombustionAirInletNodeName + idfObject.setString(Generator_MicroTurbineFields::CombustionAirInletNodeName,""); + + //CombustionAirOutletNodeName + idfObject.setString(Generator_MicroTurbineFields::CombustionAirOutletNodeName,""); + + /// Curves, Not Optional + //ElectricalPowerFunctionofTemperatureandElevationCurve + { + auto curve = modelObject.electricalPowerFunctionofTemperatureandElevationCurve(); + if( auto _curve = translateAndMapModelObject(curve) ) { + idfObject.setString(Generator_MicroTurbineFields::ElectricalPowerFunctionofTemperatureandElevationCurveName, _curve->name().get()); + } + } + + //ElectricalEfficiencyFunctionofTemperatureCurve + { + auto curve = modelObject.electricalEfficiencyFunctionofTemperatureCurve(); + if( auto _curve = translateAndMapModelObject(curve) ) { + idfObject.setString(Generator_MicroTurbineFields::ElectricalEfficiencyFunctionofTemperatureCurveName, _curve->name().get()); + } + } + + //ElectricalEfficiencyFunctionofPartLoadRatioCurve + { + auto curve = modelObject.electricalEfficiencyFunctionofPartLoadRatioCurve(); + if( auto _curve = translateAndMapModelObject(curve) ) { + idfObject.setString(Generator_MicroTurbineFields::ElectricalEfficiencyFunctionofPartLoadRatioCurveName, _curve->name().get()); + } + } + /// Curves, Optional + + //AncillaryPowerFunctionofFuelInputCurve + if( auto curve = modelObject.ancillaryPowerFunctionofFuelInputCurve() ) { + if( auto _curve = translateAndMapModelObject(curve.get()) ) { + idfObject.setString(Generator_MicroTurbineFields::AncillaryPowerFunctionofFuelInputCurveName, _curve->name().get()); + } + } + + //ExhaustAirFlowRateFunctionofTemperatureCurve + if( auto curve = modelObject.exhaustAirFlowRateFunctionofTemperatureCurve() ) { + if( auto _curve = translateAndMapModelObject(curve.get()) ) { + idfObject.setString(Generator_MicroTurbineFields::ExhaustAirFlowRateFunctionofTemperatureCurveName, _curve->name().get()); + } + } + + //ExhaustAirFlowRateFunctionofPartLoadRatioCurve + if( auto curve = modelObject.exhaustAirFlowRateFunctionofPartLoadRatioCurve() ) { + if( auto _curve = translateAndMapModelObject(curve.get()) ) { + idfObject.setString(Generator_MicroTurbineFields::ExhaustAirFlowRateFunctionofPartLoadRatioCurveName,_curve->name().get()); + } + } + + //ExhaustAirTemperatureFunctionofTemperatureCurve + if( auto curve = modelObject.exhaustAirTemperatureFunctionofTemperatureCurve() ) { + if( auto _curve = translateAndMapModelObject(curve.get()) ) { + idfObject.setString(Generator_MicroTurbineFields::ExhaustAirTemperatureFunctionofTemperatureCurveName, _curve->name().get()); + } + } + + //ExhaustAirTemperatureFunctionofPartLoadRatioCurve + if( auto curve = modelObject.exhaustAirTemperatureFunctionofPartLoadRatioCurve() ) { + if( auto _curve = translateAndMapModelObject(curve.get()) ) { + idfObject.setString(Generator_MicroTurbineFields::ExhaustAirTemperatureFunctionofPartLoadRatioCurveName, _curve->name().get()); + } + } + + return idfObject; +} + +} // energyplus + +} // openstudio + diff --git a/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateMeterCustom.cpp b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateMeterCustom.cpp new file mode 100644 index 00000000000..6ad3ddeb158 --- /dev/null +++ b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateMeterCustom.cpp @@ -0,0 +1,94 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include "../ForwardTranslator.hpp" + +#include "../../model/Model.hpp" +#include "../../model/MeterCustom.hpp" +#include "../../model/MeterCustom_Impl.hpp" + +#include "../../utilities/core/Logger.hpp" +#include "../../utilities/core/Assert.hpp" + +#include "../../utilities/idf/IdfExtensibleGroup.hpp" +#include + +#include "../../utilities/idd/IddEnums.hpp" +#include +#include + + +using namespace openstudio::model; + +// I don't think I'm using this +//using namespace std; + +// I don't know if I need this +using namespace openstudio::model; + +namespace openstudio { + +namespace energyplus { + +boost::optional ForwardTranslator::translateMeterCustom( MeterCustom & modelObject ) +{ + + boost::optional s; + boost::optional value; + + IdfObject idfObject(IddObjectType::Meter_Custom); + + m_idfObjects.push_back(idfObject); + + s = modelObject.name(); + if( s ) + { + idfObject.setName(*s); + } + + // FuelType + if( (s = modelObject.fuelType()) ) + { + idfObject.setString(Meter_CustomFields::FuelType,s.get()); + } + + // Handle the (Key Name, Output Variable or Meter Name) pairs + std::vector< std::pair > keyVarGroups = modelObject.keyVarGroups(); + + if( !keyVarGroups.empty() ) + { + for( const auto & keyVarGroup : keyVarGroups ) + { + IdfExtensibleGroup eg = idfObject.pushExtensibleGroup(); + + eg.setString(Meter_CustomExtensibleFields::KeyName,keyVarGroup.first); + eg.setString(Meter_CustomExtensibleFields::OutputVariableorMeterName,keyVarGroup.second); + } + } + else { + LOG(Error,modelObject.briefDescription() << ": At least one pair of (Key Name, Output Variable or Meter Name) required"); + return boost::none; + } + + return boost::optional(idfObject); +} + +} // energyplus + +} // openstudio \ No newline at end of file diff --git a/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateMeterCustomDecrement.cpp b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateMeterCustomDecrement.cpp new file mode 100644 index 00000000000..11652a318d3 --- /dev/null +++ b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateMeterCustomDecrement.cpp @@ -0,0 +1,98 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include "../ForwardTranslator.hpp" + +#include "../../model/Model.hpp" +#include "../../model/MeterCustomDecrement.hpp" +#include "../../model/MeterCustomDecrement_Impl.hpp" + +#include "../../utilities/core/Logger.hpp" +#include "../../utilities/core/Assert.hpp" + +#include "../../utilities/idf/IdfExtensibleGroup.hpp" +#include + +#include "../../utilities/idd/IddEnums.hpp" +#include +#include + + +using namespace openstudio::model; + +// I don't think I'm using this +//using namespace std; + +// I don't know if I need this +using namespace openstudio::model; + +namespace openstudio { + +namespace energyplus { + +boost::optional ForwardTranslator::translateMeterCustomDecrement( MeterCustomDecrement & modelObject ) +{ + + boost::optional s; + boost::optional value; + + IdfObject idfObject(IddObjectType::Meter_CustomDecrement); + + m_idfObjects.push_back(idfObject); + + s = modelObject.name(); + if( s ) + { + idfObject.setName(*s); + } + + // FuelType + if( (s = modelObject.fuelType()) ) + { + idfObject.setString(Meter_CustomDecrementFields::FuelType,s.get()); + } + + // Source Meter Name + std::string sourceMeterName = modelObject.sourceMeterName(); + idfObject.setString(Meter_CustomDecrementFields::SourceMeterName,sourceMeterName); + + // Handle the (Key Name, Output Variable or Meter Name) pairs + std::vector< std::pair > keyVarGroups = modelObject.keyVarGroups(); + + if( !keyVarGroups.empty() ) + { + for( const auto & keyVarGroup : keyVarGroups ) + { + IdfExtensibleGroup eg = idfObject.pushExtensibleGroup(); + + eg.setString(Meter_CustomDecrementExtensibleFields::KeyName,keyVarGroup.first); + eg.setString(Meter_CustomDecrementExtensibleFields::OutputVariableorMeterName,keyVarGroup.second); + } + } + else { + LOG(Error,modelObject.briefDescription() << ": At least one pair of (Key Name, Output Variable or Meter Name) required"); + return boost::none; + } + + return boost::optional(idfObject); +} + +} // energyplus + +} // openstudio \ No newline at end of file diff --git a/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateMeter.cpp b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateOutputMeter.cpp similarity index 94% rename from openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateMeter.cpp rename to openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateOutputMeter.cpp index 193198c4a69..653f362282f 100644 --- a/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateMeter.cpp +++ b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateOutputMeter.cpp @@ -20,8 +20,8 @@ #include "../ForwardTranslator.hpp" #include "../../model/Model.hpp" -#include "../../model/Meter.hpp" -#include "../../model/Meter_Impl.hpp" +#include "../../model/OutputMeter.hpp" +#include "../../model/OutputMeter_Impl.hpp" #include #include @@ -38,7 +38,7 @@ namespace openstudio { namespace energyplus { -boost::optional ForwardTranslator::translateMeter( Meter & modelObject ) +boost::optional ForwardTranslator::translateOutputMeter( OutputMeter & modelObject ) { boost::optional idfObject; diff --git a/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp index 7fceb42829a..267df10fd1c 100644 --- a/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp +++ b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslatePlantLoop.cpp @@ -55,6 +55,10 @@ #include "../../model/CoolingTowerSingleSpeed_Impl.hpp" #include "../../model/CoolingTowerTwoSpeed.hpp" #include "../../model/CoolingTowerTwoSpeed_Impl.hpp" +#include "../../model/GeneratorMicroTurbine.hpp" +#include "../../model/GeneratorMicroTurbine_Impl.hpp" +#include "../../model/GeneratorMicroTurbineHeatRecovery.hpp" +#include "../../model/GeneratorMicroTurbineHeatRecovery_Impl.hpp" #include "../../model/GroundHeatExchangerVertical.hpp" #include "../../model/GroundHeatExchangerVertical_Impl.hpp" #include "../../model/GroundHeatExchangerHorizontalTrench.hpp" @@ -145,7 +149,7 @@ IdfObject ForwardTranslator::populateBranch( IdfObject & branchIdfObject, { inletNode = straightComponent->inletModelObject()->optionalCast(); outletNode = straightComponent->outletModelObject()->optionalCast(); - //special case for ZoneHVAC:Baseeboard:Convective:Water. In E+, this object appears on both the + //special case for ZoneHVAC:Baseboard:Convective:Water. In E+, this object appears on both the //zonehvac:equipmentlist and the branch. In OpenStudio, this object was broken into 2 objects: //ZoneHVACBaseboardConvectiveWater and CoilHeatingWaterBaseboard. The ZoneHVAC goes onto the zone and //has a child coil that goes onto the plantloop. In order to get the correct translation to E+, we need @@ -253,6 +257,24 @@ IdfObject ForwardTranslator::populateBranch( IdfObject & branchIdfObject, } } } + //special case for Generator:MicroTurbine. + //In OpenStudio, this object was broken into 2 objects: + //GeneratorMicroTurbine and GeneratorMicroTurbineHeatRecovery. + //The GeneratorMicroTurbineHeatRecovery goes onto the plantloop. In order to get the correct translation to E+, we need + //to put the name of the linked GeneratorMicroTurbine onto the branch. + if (boost::optional mchpHR = modelObject.optionalCast() ) + { + if (boost::optional mchp = mchpHR->generatorMicroTurbine()) + { + //translate and map containingZoneHVACBBConvWater + if ( boost::optional idfmchp = this->translateAndMapModelObject(*mchp) ) + { + //Get the name and the idd object from the idf object version of this + objectName = idfmchp->name().get(); + iddType = idfmchp->iddObject().name(); + } + } + } } else if( auto waterToAirComponent = modelObject.optionalCast() ) { diff --git a/openstudiocore/src/energyplus/ReverseTranslator.cpp b/openstudiocore/src/energyplus/ReverseTranslator.cpp index f55872985f7..33ba17a4c93 100644 --- a/openstudiocore/src/energyplus/ReverseTranslator.cpp +++ b/openstudiocore/src/energyplus/ReverseTranslator.cpp @@ -474,6 +474,11 @@ boost::optional ReverseTranslator::translateAndMapWorkspaceObject(c //modelObject = translateExteriorLights(workspaceObject); break; } + case openstudio::IddObjectType::ElectricLoadCenter_Storage_Simple : + { + modelObject = translateElectricLoadCenterStorageSimple(workspaceObject); + break; + } case openstudio::IddObjectType::EvaporativeCooler_Direct_ResearchSpecial : { //modelObject = translateEvaporativeCoolerDirectResearchSpecial(workspaceObject); @@ -491,7 +496,12 @@ boost::optional ReverseTranslator::translateAndMapWorkspaceObject(c } case openstudio::IddObjectType::FenestrationSurface_Detailed : { - modelObject = translateFenestrationSurfaceDetailed(workspaceObject ); + modelObject = translateFenestrationSurfaceDetailed(workspaceObject); + break; + } + case openstudio::IddObjectType::Generator_MicroTurbine : + { + modelObject = translateGeneratorMicroTurbine(workspaceObject); break; } case openstudio::IddObjectType::GlobalGeometryRules : @@ -551,11 +561,13 @@ boost::optional ReverseTranslator::translateAndMapWorkspaceObject(c } case openstudio::IddObjectType::Meter_Custom : { - break; // no-op + modelObject = translateMeterCustom(workspaceObject); + break; } case openstudio::IddObjectType::Meter_CustomDecrement : { - break; // no-op + modelObject = translateMeterCustomDecrement(workspaceObject); + break; } case openstudio::IddObjectType::OtherEquipment : { diff --git a/openstudiocore/src/energyplus/ReverseTranslator.hpp b/openstudiocore/src/energyplus/ReverseTranslator.hpp index 4cf3406f718..8a412aab7c6 100644 --- a/openstudiocore/src/energyplus/ReverseTranslator.hpp +++ b/openstudiocore/src/energyplus/ReverseTranslator.hpp @@ -137,6 +137,8 @@ class ENERGYPLUS_API ReverseTranslator { boost::optional translateElectricEquipment(const WorkspaceObject & workspaceObject); + boost::optional translateElectricLoadCenterStorageSimple(const WorkspaceObject & workspaceObject); + boost::optional translateEvaporativeCoolerDirectResearchSpecial(const WorkspaceObject & workspaceObject); boost::optional translateEvaporativeFluidCoolerSingleSpeed(const WorkspaceObject & workspaceObject); @@ -148,6 +150,8 @@ class ENERGYPLUS_API ReverseTranslator { boost::optional translateFenestrationSurfaceDetailed(const WorkspaceObject & workspaceObject); boost::optional translateGasEquipment(const WorkspaceObject & workspaceObject); + + boost::optional translateGeneratorMicroTurbine(const WorkspaceObject& workspaceObject); boost::optional translateGroundHeatExchangerVertical(const WorkspaceObject & workspaceObject); @@ -164,6 +168,10 @@ class ENERGYPLUS_API ReverseTranslator { boost::optional translateMaterialAirGap(const WorkspaceObject & workspaceObject); boost::optional translateMaterialNoMass(const WorkspaceObject & workspaceObject); + + boost::optional translateMeterCustom(const WorkspaceObject & workspaceObject); + + boost::optional translateMeterCustomDecrement(const WorkspaceObject & workspaceObject); boost::optional translateOtherEquipment(const WorkspaceObject& workspaceObject); diff --git a/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageSimple.cpp b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageSimple.cpp new file mode 100644 index 00000000000..06ca61b0de8 --- /dev/null +++ b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateElectricLoadCenterStorageSimple.cpp @@ -0,0 +1,147 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include "../ReverseTranslator.hpp" + +#include "../../model/ElectricLoadCenterStorageSimple.hpp" +#include "../../model/ElectricLoadCenterStorageSimple_Impl.hpp" + +#include "../../model/Schedule.hpp" +#include "../../model/Schedule_Impl.hpp" +#include "../../model/ThermalZone.hpp" +#include "../../model/ThermalZone_Impl.hpp" + +#include + +#include "../../utilities/idd/IddEnums.hpp" +#include + +using namespace openstudio::model; + +namespace openstudio { + +namespace energyplus { + +OptionalModelObject ReverseTranslator::translateElectricLoadCenterStorageSimple( const WorkspaceObject & workspaceObject ) +{ + + OptionalModelObject result,temp; + OptionalDouble d; + boost::optional owo; + OptionalString optS; + + + // TODO: The availability schedule is in the ElectricLoadCenter:Generators (list) in E+, here it's carried by the generator itself + // Should also get the Rated Thermal To Electrical Power Ratio in the list + + //Generator:MicroTurbine, + // Capstone C65, !- Name + + openstudio::model::ElectricLoadCenterStorageSimple elcStorSimple( m_model ); + + // Name + optS = workspaceObject.name(); + if(optS) + { + elcStorSimple.setName(*optS); + } + + // AvailabilityScheduleName + if( (owo = workspaceObject.getTarget(ElectricLoadCenter_Storage_SimpleFields::AvailabilityScheduleName)) ) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional schedule = mo->optionalCast() ) + { + elcStorSimple.setAvailabilitySchedule(schedule.get()); + } + } + } + + // ZoneName + if( (owo = workspaceObject.getTarget(ElectricLoadCenter_Storage_SimpleFields::ZoneName)) ) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional thermalZone = mo->optionalCast() ) + { + elcStorSimple.setThermalZone(thermalZone.get()); + } + } + } + + // Radiative Fraction, defaults (double) + d = workspaceObject.getDouble(ElectricLoadCenter_Storage_SimpleFields::RadiativeFractionforZoneHeatGains); + if(d) + { + elcStorSimple.setRadiativeFractionforZoneHeatGains(*d); + } + + // nominalEnergeticEfficiencyforCharging, defaults + d = workspaceObject.getDouble(ElectricLoadCenter_Storage_SimpleFields::NominalEnergeticEfficiencyforCharging); + if(d) + { + elcStorSimple.setNominalEnergeticEfficiencyforCharging(*d); + } + + // nominalEnergeticEfficiencyforDischarging, defaults + d = workspaceObject.getDouble(ElectricLoadCenter_Storage_SimpleFields::NominalDischargingEnergeticEfficiency); + if(d) + { + elcStorSimple.setNominalDischargingEnergeticEfficiency(*d); + } + + // maximumStorageCapacity, required, assigned in ctor + d = workspaceObject.getDouble(ElectricLoadCenter_Storage_SimpleFields::MaximumStorageCapacity); + if(d) { + elcStorSimple.setMaximumStorageCapacity(*d); + } else { + LOG(Error, workspaceObject.briefDescription() << " does not have a required maximum Storage Capacity"); + } + + // maximumPowerforDischarging, required, assigned in ctor + d = workspaceObject.getDouble(ElectricLoadCenter_Storage_SimpleFields::MaximumPowerforDischarging); + if(d) { + elcStorSimple.setMaximumPowerforDischarging(*d); + } else { + LOG(Error, workspaceObject.briefDescription() << " does not have a required maximum power for discharging"); + } + + // maximumPowerforCharging, required, assigned in ctor + d = workspaceObject.getDouble(ElectricLoadCenter_Storage_SimpleFields::MaximumPowerforCharging); + if(d) { + elcStorSimple.setMaximumPowerforCharging(*d); + } else { + LOG(Error, workspaceObject.briefDescription() << " does not have a required maximum power for charging"); + } + + // initialStateofCharge + d = workspaceObject.getDouble(ElectricLoadCenter_Storage_SimpleFields::InitialStateofCharge); + if(d) + { + elcStorSimple.setInitialStateofCharge(*d); + } + + result=elcStorSimple; + return result; +} + +} // energyplus + +} // openstudio diff --git a/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateGeneratorMicroTurbine.cpp b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateGeneratorMicroTurbine.cpp new file mode 100644 index 00000000000..568ff3b7eee --- /dev/null +++ b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateGeneratorMicroTurbine.cpp @@ -0,0 +1,526 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include "../ReverseTranslator.hpp" + +#include "../../model/GeneratorMicroTurbine.hpp" +#include "../../model/GeneratorMicroTurbine_Impl.hpp" +#include "../../model/GeneratorMicroTurbineHeatRecovery.hpp" +#include "../../model/GeneratorMicroTurbineHeatRecovery_Impl.hpp" + +#include "../../model/Schedule.hpp" +#include "../../model/Schedule_Impl.hpp" + +#include "../../model/Curve.hpp" +#include "../../model/Curve_Impl.hpp" +#include "../../model/CurveBicubic.hpp" +#include "../../model/CurveBicubic_Impl.hpp" +#include "../../model/CurveBiquadratic.hpp" +#include "../../model/CurveBiquadratic_Impl.hpp" +#include "../../model/CurveCubic.hpp" +#include "../../model/CurveCubic_Impl.hpp" +#include "../../model/CurveQuadratic.hpp" +#include "../../model/CurveQuadratic_Impl.hpp" + +#include +//#include +#include "../../utilities/idd/IddEnums.hpp" +#include + +using namespace openstudio::model; + +namespace openstudio { + +namespace energyplus { + +OptionalModelObject ReverseTranslator::translateGeneratorMicroTurbine( const WorkspaceObject & workspaceObject ) +{ + + OptionalModelObject result,temp; + OptionalDouble d; + boost::optional owo; + OptionalString optS; + + + // TODO: The availability schedule is in the ElectricLoadCenter:Generators (list) in E+, here it's carried by the generator itself + // Should also get the Rated Thermal To Electrical Power Ratio in the list + + //Generator:MicroTurbine, + // Capstone C65, !- Name + + openstudio::model::GeneratorMicroTurbine mchp( m_model ); + + // Name + optS = workspaceObject.name(); + if(optS) + { + mchp.setName(*optS); + } + + + + // 65000, !- Reference Electrical Power Output {W} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceElectricalPowerOutput); + if(d) + { + mchp.setReferenceElectricalPowerOutput(*d); + } + // 29900, !- Minimum Full Load Electrical Power Output {W} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::MinimumFullLoadElectricalPowerOutput); + if(d) + { + mchp.setMinimumFullLoadElectricalPowerOutput(*d); + } + // 65000, !- Maximum Full Load Electrical Power Output {W} setMaximumFullLoadElectricalPowerOutput + d = workspaceObject.getDouble(Generator_MicroTurbineFields::MaximumFullLoadElectricalPowerOutput); + if(d) + { + mchp.setMaximumFullLoadElectricalPowerOutput(*d); + } + + // 0.29, !- Reference Electrical Efficiency Using Lower Heating Value + d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceElectricalEfficiencyUsingLowerHeatingValue); + if(d) + { + mchp.setReferenceElectricalEfficiencyUsingLowerHeatingValue(*d); + } + + // 15.0, !- Reference Combustion Air Inlet Temperature {C} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceCombustionAirInletTemperature); + if(d) + { + mchp.setReferenceCombustionAirInletTemperature(*d); + } + + // 0.00638, !- Reference Combustion Air Inlet Humidity Ratio {kgWater/kgDryAir} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceCombustionAirInletHumidityRatio); + if(d) + { + mchp.setReferenceCombustionAirInletHumidityRatio(*d); + } + + // 0.0, !- Reference Elevation {m} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::MinimumFullLoadElectricalPowerOutput); + if(d) + { + mchp.setMinimumFullLoadElectricalPowerOutput(*d); + } + + // Capstone C65 Power_vs_Temp_Elev, !- Electrical Power Function of Temperature and Elevation Curve Name + // BiquadraticCurves + if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ElectricalPowerFunctionofTemperatureandElevationCurveName)) ) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional curve = mo->optionalCast() ) + { + mchp.setElectricalPowerFunctionofTemperatureandElevationCurve(curve.get()); + } + else + { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Electrical Power Function of Temperature and Elevation Curve Name"); + } + } + } + + // Capstone C65 Efficiency_vs_Temp, !- Electrical Efficiency Function of Temperature Curve Name + // QuadraticCubicCurves + if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ElectricalEfficiencyFunctionofTemperatureCurveName)) ) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional curve = mo->optionalCast() ) + { + mchp.setElectricalEfficiencyFunctionofTemperatureCurve(curve.get()); + } + else if( boost::optional curve = mo->optionalCast() ) + { + mchp.setElectricalEfficiencyFunctionofTemperatureCurve(curve.get()); + } + else + { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Electrical Efficiency Function of Temperature Curve Name"); + } + } + } + + + // Capstone C65 Efficiency_vs_PLR, !- Electrical Efficiency Function of Part Load Ratio Curve Name + // QuadraticCubicCurves + // setElectricalEfficiencyFunctionofPartLoadRatioCurve + if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ElectricalEfficiencyFunctionofPartLoadRatioCurveName)) ) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional curve = mo->optionalCast() ) + { + mchp.setElectricalEfficiencyFunctionofPartLoadRatioCurve(curve.get()); + } + else if( boost::optional curve = mo->optionalCast() ) + { + mchp.setElectricalEfficiencyFunctionofPartLoadRatioCurve(curve.get()); + } + else + { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Electrical Efficiency Function of Part Load Ratio Curve Name"); + } + } + } + + // NaturalGas, !- Fuel Type + optS = workspaceObject.getString(Generator_MicroTurbineFields::FuelType); + if(optS) + { + mchp.setFuelType(*optS); + } + + // 50000, !- Fuel Higher Heating Value {kJ/kg} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::FuelHigherHeatingValue); + if(d) + { + mchp.setFuelHigherHeatingValue(*d); + } + + // 45450, !- Fuel Lower Heating Value {kJ/kg} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::FuelLowerHeatingValue); + if(d) + { + mchp.setFuelLowerHeatingValue(*d); + } + + // 300, !- Standby Power {W} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::StandbyPower); + if(d) + { + mchp.setStandbyPower(*d); + } + + // 4500, !- Ancillary Power {W} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::AncillaryPower); + if(d) + { + mchp.setAncillaryPower(*d); + } + + // , !- Ancillary Power Function of Fuel Input Curve Name + // QuadraticCurves + // mchp.setAncillaryPowerFunctionofFuelInputCurve + if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::AncillaryPowerFunctionofFuelInputCurveName)) ) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional curve = mo->optionalCast() ) + { + mchp.setAncillaryPowerFunctionofFuelInputCurve(curve.get()); + } + else + { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Ancillary Power Function of Fuel Input Curve Name"); + } + } + } + + + // Fields in between (in E+.idd) are moved at the end in the Heat Recovery section + + // Capstone C65 Combustion Air Inlet Node, !- Combustion Air Inlet Node Name + // Capstone C65 Combustion Air Outlet Node, !- Combustion Air Outlet Node Name + + + // 0.489885, !- Reference Exhaust Air Mass Flow Rate {kg/s} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceExhaustAirMassFlowRate); + if(d) + { + mchp.setReferenceExhaustAirMassFlowRate(*d); + } + + // Capstone C65 ExhAirFlowRate_vs_InletTemp, !- Exhaust Air Flow Rate Function of Temperature Curve Name + // QuadraticCubicCurves + // mchp.setExhaustAirFlowRateFunctionofTemperatureCurve + if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ExhaustAirFlowRateFunctionofTemperatureCurveName)) ) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional curve = mo->optionalCast() ) + { + mchp.setExhaustAirFlowRateFunctionofTemperatureCurve(curve.get()); + } + else if( boost::optional curve = mo->optionalCast() ) + { + mchp.setExhaustAirFlowRateFunctionofTemperatureCurve(curve.get()); + } + else + { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Exhaust Air Flow Rate Function of Temperature Curve Name"); + } + } + } + + // Capstone C65 ExhAirFlowRate_vs_PLR, !- Exhaust Air Flow Rate Function of Part Load Ratio Curve Name + // QuadraticCubicCurves + // mchp.setExhaustAirFlowRateFunctionofPartLoadRatioCurve(curve) + if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ExhaustAirFlowRateFunctionofPartLoadRatioCurveName)) ) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional curve = mo->optionalCast() ) + { + mchp.setExhaustAirFlowRateFunctionofPartLoadRatioCurve(curve.get()); + } + else if( boost::optional curve = mo->optionalCast() ) + { + mchp.setExhaustAirFlowRateFunctionofPartLoadRatioCurve(curve.get()); + } + else + { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Exhaust Air Flow Rate Function of Part Load Ratio Curve Name"); + } + } + } + + // 308.9, !- Nominal Exhaust Air Outlet Temperature + d = workspaceObject.getDouble(Generator_MicroTurbineFields::NominalExhaustAirOutletTemperature); + if(d) + { + mchp.setNominalExhaustAirOutletTemperature(*d); + } + + // Capstone C65 ExhaustTemp_vs_InletTemp, !- Exhaust Air Temperature Function of Temperature Curve Name + // QuadraticCubicCurves + // mchp.setExhaustAirTemperatureFunctionofTemperatureCurve(curve) + if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ExhaustAirTemperatureFunctionofTemperatureCurveName)) ) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional curve = mo->optionalCast() ) + { + mchp.setExhaustAirTemperatureFunctionofTemperatureCurve(curve.get()); + } + else if( boost::optional curve = mo->optionalCast() ) + { + mchp.setExhaustAirTemperatureFunctionofTemperatureCurve(curve.get()); + } + else + { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Exhaust Air Temperature Function of Temperature Curve Name"); + } + } + } + + // Capstone C65 ExhaustTemp_vs_PLR; !- Exhaust Air Temperature Function of Part Load Ratio Curve Name + // QuadraticCubicCurves + // mchp.setExhaustAirTemperatureFunctionofPartLoadRatioCurve(curve) + if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ExhaustAirTemperatureFunctionofPartLoadRatioCurveName)) ) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional curve = mo->optionalCast() ) + { + mchp.setExhaustAirTemperatureFunctionofPartLoadRatioCurve(curve.get()); + } + else if( boost::optional curve = mo->optionalCast() ) + { + mchp.setExhaustAirTemperatureFunctionofPartLoadRatioCurve(curve.get()); + } + else + { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Exhaust Air Temperature Function of Part Load Ratio Curve Name"); + } + } + } + + + /// HEAT RECOVERY PORTION + + // Would need to add that to the plantLoop reverse translator + // Capstone C65 Heat Recovery Water Inlet Node, !- Heat Recovery Water Inlet Node Name + // Capstone C65 Heat Recovery Water Outlet Node, !- Heat Recovery Water Outlet Node Name + + + + + // TODO: For now, I trigger the creation is the 'Reference Thermal Efficiency Using Lower Heat Value' is filled. + // TODO: I should trigger it based on the `Rated Thermal To Electrical Power Ratio in the list` in the ElectricLoadCenter:Generators (list) + // TODO: But in order to do that, the ElectricLoadCenter:Distribution & ElectricLoadCenter:Generators need to have a reverse translator + + // 0.4975, !- Reference Thermal Efficiency Using Lower Heat Value + d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceThermalEfficiencyUsingLowerHeatValue); + + if(d) + { + + // Create a GeneratorMicroTurbineHeatRecovery module, and assign it to the MicroTurbine + // I've Set the Name in the constructor + openstudio::model::GeneratorMicroTurbineHeatRecovery mchpHR (m_model, mchp); + + // Assign the Reference Thermal Efficiency Using Lower Heat Value + mchpHR.setReferenceThermalEfficiencyUsingLowerHeatValue(*d); + + + // 60.0, !- Reference Inlet Water Temperature {C} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceInletWaterTemperature); + if(d) + { + mchpHR.setReferenceInletWaterTemperature(*d); + } + + // PlantControl, !- Heat Recovery Water Flow Operating Mode + optS = workspaceObject.getString(Generator_MicroTurbineFields::HeatRecoveryWaterFlowOperatingMode); + if(optS) + { + mchpHR.setHeatRecoveryWaterFlowOperatingMode(*optS); + } + + // 0.00252362, !- Reference Heat Recovery Water Flow Rate {m3/s} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::ReferenceHeatRecoveryWaterFlowRate); + if(d) + { + mchpHR.setReferenceHeatRecoveryWaterFlowRate(*d); + } + + // , !- Heat Recovery Water Flow Rate Function of Temperature and Power Curve Name + // BiquadraticCurves + // mchpHR.setHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve(); + if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::HeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurveName)) ) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional curve = mo->optionalCast() ) + { + mchpHR.setHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve(curve.get()); + } + else + { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Heat Recovery Water Flow Rate Function of Temperature and Power Curve Name"); + } + } + } + + // Capstone C65 ThermalEff_vs_Temp_Elev, !- Thermal Efficiency Function of Temperature and Elevation Curve Name + // BicubicBiquadraticCurves + // mchpHR.setThermalEfficiencyFunctionofTemperatureandElevationCurve(); + if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::ThermalEfficiencyFunctionofTemperatureandElevationCurveName)) ) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional curve = mo->optionalCast() ) + { + mchpHR.setThermalEfficiencyFunctionofTemperatureandElevationCurve(curve.get()); + } + else if( boost::optional curve = mo->optionalCast() ) + { + mchpHR.setThermalEfficiencyFunctionofTemperatureandElevationCurve(curve.get()); + } + else + { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Thermal Efficiency Function of Temperature and Elevation Curve Name"); + } + } + } + + // Capstone C65 HeatRecoveryRate_vs_PLR, !- Heat Recovery Rate Function of Part Load Ratio Curve Name + // QuadraticCubicCurves + // mchpHR.setHeatRecoveryRateFunctionofPartLoadRatioCurve(); + if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::HeatRecoveryRateFunctionofPartLoadRatioCurveName)) ) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional curve = mo->optionalCast() ) + { + mchpHR.setHeatRecoveryRateFunctionofPartLoadRatioCurve(curve.get()); + } + else if( boost::optional curve = mo->optionalCast() ) + { + mchpHR.setHeatRecoveryRateFunctionofPartLoadRatioCurve(curve.get()); + } + else + { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Heat Recovery Rate Function of Part Load Ratio Curve Name"); + } + } + } + + // Capstone C65 HeatRecoveryRate_vs_InletTemp, !- Heat Recovery Rate Function of Inlet Water Temperature Curve Name + // QuadraticCurves + // mchpHR.setHeatRecoveryRateFunctionofInletWaterTemperatureCurve(); + if ((owo = workspaceObject.getTarget(Generator_MicroTurbineFields::HeatRecoveryRateFunctionofInletWaterTemperatureCurveName))) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional curve = mo->optionalCast() ) + { + mchpHR.setHeatRecoveryRateFunctionofInletWaterTemperatureCurve(curve.get()); + } + else + { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Heat Recovery Rate Function of Part Load Ratio Curve Name"); + } + } + } + + // Capstone C65 HeatRecoveryRate_vs_WaterFlow, !- Heat Recovery Rate Function of Water Flow Rate Curve Name + // QuadraticCurves + // mchpHR.setHeatRecoveryRateFunctionofInletWaterFlowRateCurve(); + if( (owo = workspaceObject.getTarget(Generator_MicroTurbineFields::HeatRecoveryRateFunctionofWaterFlowRateCurveName)) ) + { + if( boost::optional mo = translateAndMapWorkspaceObject(owo.get()) ) + { + if( boost::optional curve = mo->optionalCast() ) + { + mchpHR.setHeatRecoveryRateFunctionofWaterFlowRateCurve(curve.get()); + } + else + { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type curve for field Heat Recovery Rate Function of Water Flow Rate Curve Name"); + } + } + } + + // 0.001577263, !- Minimum Heat Recovery Water Flow Rate {m3/s} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::MinimumHeatRecoveryWaterFlowRate); + if(d) + { + mchpHR.setMinimumHeatRecoveryWaterFlowRate(*d); + } + + // 0.003785432, !- Maximum Heat Recovery Water Flow Rate {m3/s} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::MaximumHeatRecoveryWaterFlowRate); + if(d) + { + mchpHR.setMaximumHeatRecoveryWaterFlowRate(*d); + } + + // 82.2, !- Maximum Heat Recovery Water Temperature {C} + d = workspaceObject.getDouble(Generator_MicroTurbineFields::MaximumHeatRecoveryWaterTemperature); + if(d) + { + mchpHR.setMaximumHeatRecoveryWaterTemperature(*d); + } + + + } + + + result=mchp; + return result; +} + +} // energyplus + +} // openstudio diff --git a/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateMeterCustom.cpp b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateMeterCustom.cpp new file mode 100644 index 00000000000..2955acef6f7 --- /dev/null +++ b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateMeterCustom.cpp @@ -0,0 +1,79 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include "../ReverseTranslator.hpp" + +#include "../../model/MeterCustom.hpp" +#include "../../model/MeterCustom_Impl.hpp" + +#include "../../utilities/idf/IdfExtensibleGroup.hpp" + +#include +#include "../../utilities/idd/IddEnums.hpp" +#include + +using namespace openstudio::model; + +namespace openstudio { + +namespace energyplus { + +OptionalModelObject ReverseTranslator::translateMeterCustom( const WorkspaceObject & workspaceObject ) +{ + if( workspaceObject.iddObject().type() != IddObjectType::Meter_Custom ){ + LOG(Error, "WorkspaceObject is not IddObjectType: Meter:Custom"); + return boost::none; + } + + // Create an OS:Meter:Custom object + MeterCustom meterCustom = MeterCustom( m_model ); + + + // Name + boost::optional s = workspaceObject.getString(Meter_CustomFields::Name); + if (s) { + meterCustom.setName(s.get()); + } + + // Fuel Type + s = workspaceObject.getString(Meter_CustomFields::FuelType); + if (s) { + // TODO: JM to DLM: should I also check it's part of the validFuelTypes? + meterCustom.setFuelType(s.get()); + } + + // Get all the (key, var) extensible groups from IDF + std::vector keyVarGroups = workspaceObject.extensibleGroups(); + + // Clean out the (key, var) groups (just in case: the constructor doesn't default any, for now at least!) + meterCustom.removeAllKeyVarGroups(); + + // Push them all to the object + for( const auto & keyVarGroup : keyVarGroups ) + { + meterCustom.pushExtensibleGroup(keyVarGroup.fields()); + } + + return meterCustom; +} + +} // energyplus + +} // openstudio + diff --git a/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateMeterCustomDecrement.cpp b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateMeterCustomDecrement.cpp new file mode 100644 index 00000000000..7282b5fc42b --- /dev/null +++ b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateMeterCustomDecrement.cpp @@ -0,0 +1,91 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include "../ReverseTranslator.hpp" + +#include "../../model/MeterCustomDecrement.hpp" +#include "../../model/MeterCustomDecrement_Impl.hpp" + +#include "../../utilities/idf/IdfExtensibleGroup.hpp" + +#include +#include "../../utilities/idd/IddEnums.hpp" +#include + +using namespace openstudio::model; + +namespace openstudio { + +namespace energyplus { + +OptionalModelObject ReverseTranslator::translateMeterCustomDecrement( const WorkspaceObject & workspaceObject ) +{ + if( workspaceObject.iddObject().type() != IddObjectType::Meter_CustomDecrement ){ + LOG(Error, "WorkspaceObject is not IddObjectType: Meter:CustomDecrement"); + return boost::none; + } + + boost::optional optMeterCustomDecrement; + boost::optional s; + + // Source Meter Name: get it and pass it to the constructor + s = workspaceObject.getString(Meter_CustomDecrementFields::SourceMeterName); + if (s) { + // Create an OS:Meter:CustomDecrement object + optMeterCustomDecrement = MeterCustomDecrement(m_model, s.get()); + } else { + LOG(Error, workspaceObject.briefDescription() << " does not have a Source Meter Name which is required. It will not be translated!"); + } + + MeterCustomDecrement meterCustomDecrement = optMeterCustomDecrement.get(); + + + // Name + s = workspaceObject.getString(Meter_CustomDecrementFields::Name); + if (s) { + meterCustomDecrement.setName(s.get()); + } + + // Fuel Type + s = workspaceObject.getString(Meter_CustomDecrementFields::FuelType); + if (s) { + // TODO: JM to DLM: should I also check it's part of the validFuelTypes? + meterCustomDecrement.setFuelType(s.get()); + } + + + // Get all the (key, var) extensible groups from IDF + std::vector keyVarGroups = workspaceObject.extensibleGroups(); + + // Clean out the (key, var) groups (just in case: the constructor doesn't default any, for now at least!) + meterCustomDecrement.removeAllKeyVarGroups(); + + // Push them all to the object + for( const auto & keyVarGroup : keyVarGroups ) + { + meterCustomDecrement.pushExtensibleGroup(keyVarGroup.fields()); + } + + return meterCustomDecrement; +} + +} // energyplus + +} // openstudio + diff --git a/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeter.cpp b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeter.cpp index d901466c044..073b5af0d1d 100644 --- a/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeter.cpp +++ b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeter.cpp @@ -19,8 +19,8 @@ #include "../ReverseTranslator.hpp" -#include "../../model/Meter.hpp" -#include "../../model/Meter_Impl.hpp" +#include "../../model/OutputMeter.hpp" +#include "../../model/OutputMeter_Impl.hpp" #include @@ -32,7 +32,7 @@ namespace energyplus { OptionalModelObject ReverseTranslator::translateOutputMeter( const WorkspaceObject & workspaceObject ) { - openstudio::model::Meter meter( m_model ); + openstudio::model::OutputMeter meter( m_model ); OptionalString s = workspaceObject.getString(Output_MeterFields::Name); if(s){ diff --git a/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeterCumulative.cpp b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeterCumulative.cpp index 876aadcfaf0..84ed4fb701a 100644 --- a/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeterCumulative.cpp +++ b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeterCumulative.cpp @@ -19,8 +19,8 @@ #include "../ReverseTranslator.hpp" -#include "../../model/Meter.hpp" -#include "../../model/Meter_Impl.hpp" +#include "../../model/OutputMeter.hpp" +#include "../../model/OutputMeter_Impl.hpp" #include #include "../../utilities/idd/IddEnums.hpp" @@ -33,7 +33,7 @@ namespace energyplus { OptionalModelObject ReverseTranslator::translateOutputMeterCumulative( const WorkspaceObject & workspaceObject ) { - openstudio::model::Meter meter( m_model ); + openstudio::model::OutputMeter meter( m_model ); OptionalString s = workspaceObject.getString(Output_Meter_CumulativeFields::Name); if(s){ diff --git a/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeterCumulativeMeterFileOnly.cpp b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeterCumulativeMeterFileOnly.cpp index 1b58a917d5c..2ad46be8293 100644 --- a/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeterCumulativeMeterFileOnly.cpp +++ b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeterCumulativeMeterFileOnly.cpp @@ -19,8 +19,8 @@ #include "../ReverseTranslator.hpp" -#include "../../model/Meter.hpp" -#include "../../model/Meter_Impl.hpp" +#include "../../model/OutputMeter.hpp" +#include "../../model/OutputMeter_Impl.hpp" #include @@ -32,7 +32,7 @@ namespace energyplus { OptionalModelObject ReverseTranslator::translateOutputMeterCumulativeMeterFileOnly( const WorkspaceObject & workspaceObject ) { - openstudio::model::Meter meter( m_model ); + openstudio::model::OutputMeter meter( m_model ); OptionalString s = workspaceObject.getString(Output_Meter_Cumulative_MeterFileOnlyFields::Name); if(s){ diff --git a/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeterMeterFileOnly.cpp b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeterMeterFileOnly.cpp index 7b263e52aa5..9135ab63c49 100644 --- a/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeterMeterFileOnly.cpp +++ b/openstudiocore/src/energyplus/ReverseTranslator/ReverseTranslateOutputMeterMeterFileOnly.cpp @@ -19,8 +19,8 @@ #include "../ReverseTranslator.hpp" -#include "../../model/Meter.hpp" -#include "../../model/Meter_Impl.hpp" +#include "../../model/OutputMeter.hpp" +#include "../../model/OutputMeter_Impl.hpp" #include @@ -32,7 +32,7 @@ namespace energyplus { OptionalModelObject ReverseTranslator::translateOutputMeterMeterFileOnly( const WorkspaceObject & workspaceObject ) { - openstudio::model::Meter meter( m_model ); + openstudio::model::OutputMeter meter( m_model ); OptionalString s = workspaceObject.getString(Output_Meter_MeterFileOnlyFields::Name); if(s){ diff --git a/openstudiocore/src/energyplus/Test/Meter_GTest.cpp b/openstudiocore/src/energyplus/Test/Meter_GTest.cpp index 333720267fd..90c908cd9c1 100644 --- a/openstudiocore/src/energyplus/Test/Meter_GTest.cpp +++ b/openstudiocore/src/energyplus/Test/Meter_GTest.cpp @@ -24,8 +24,8 @@ #include "../ReverseTranslator.hpp" #include "../../model/Model.hpp" -#include "../../model/Meter.hpp" -#include "../../model/Meter_Impl.hpp" +#include "../../model/OutputMeter.hpp" +#include "../../model/OutputMeter_Impl.hpp" #include diff --git a/openstudiocore/src/model/Building.cpp b/openstudiocore/src/model/Building.cpp index 5886541cd02..dcae1538b5d 100644 --- a/openstudiocore/src/model/Building.cpp +++ b/openstudiocore/src/model/Building.cpp @@ -40,8 +40,8 @@ #include "ShadingSurface_Impl.hpp" #include "ShadingSurfaceGroup.hpp" #include "ShadingSurfaceGroup_Impl.hpp" -#include "Meter.hpp" -#include "Meter_Impl.hpp" +#include "OutputMeter.hpp" +#include "OutputMeter_Impl.hpp" #include "Surface.hpp" #include "Surface_Impl.hpp" @@ -97,7 +97,7 @@ namespace detail { std::vector result; // meters - MeterVector meters = this->meters(); + OutputMeterVector meters = this->meters(); result.insert(result.end(),meters.begin(),meters.end()); // building stories @@ -479,11 +479,11 @@ namespace detail { setString(OS_BuildingFields::DefaultScheduleSetName, ""); } - MeterVector Building_Impl::meters() const + OutputMeterVector Building_Impl::meters() const { - MeterVector result; - MeterVector meters = this->model().getConcreteModelObjects(); - for (const Meter& meter : meters){ + OutputMeterVector result; + OutputMeterVector meters = this->model().getConcreteModelObjects(); + for (const OutputMeter& meter : meters){ if (meter.installLocationType() && (InstallLocationType::Building == meter.installLocationType().get().value())){ result.push_back(meter); } @@ -1153,7 +1153,7 @@ void Building::resetDefaultScheduleSet() getImpl()->resetDefaultScheduleSet(); } -MeterVector Building::meters() const +OutputMeterVector Building::meters() const { return getImpl()->meters(); } diff --git a/openstudiocore/src/model/Building.hpp b/openstudiocore/src/model/Building.hpp index 596e49b8c28..8742cb4ee05 100644 --- a/openstudiocore/src/model/Building.hpp +++ b/openstudiocore/src/model/Building.hpp @@ -31,7 +31,7 @@ class Transformation; namespace model { class Facility; -class Meter; +class OutputMeter; class ShadingSurfaceGroup; class Surface; class Space; @@ -156,8 +156,8 @@ class MODEL_API Building : public ParentObject { /// Resets the default schedule set for this space. void resetDefaultScheduleSet(); - /// Returns all Meter objects at the Building level. - std::vector meters() const; + /// Returns all OutputMeter objects at the Building level. + std::vector meters() const; /// Returns the parent Facility object if it exists. boost::optional facility() const; diff --git a/openstudiocore/src/model/Building_Impl.hpp b/openstudiocore/src/model/Building_Impl.hpp index dfca7f7ab34..644ac2addda 100644 --- a/openstudiocore/src/model/Building_Impl.hpp +++ b/openstudiocore/src/model/Building_Impl.hpp @@ -32,7 +32,7 @@ class Transformation; namespace model { class Facility; -class Meter; +class OutputMeter; class ShadingSurfaceGroup; class Surface; class Space; @@ -183,7 +183,7 @@ namespace detail { void resetDefaultScheduleSet(); - std::vector meters() const; + std::vector meters() const; boost::optional facility() const; diff --git a/openstudiocore/src/model/CMakeLists.txt b/openstudiocore/src/model/CMakeLists.txt index 66ce5108fab..f2c946590ca 100644 --- a/openstudiocore/src/model/CMakeLists.txt +++ b/openstudiocore/src/model/CMakeLists.txt @@ -431,6 +431,9 @@ set(${target_name}_src Duct.hpp Duct_Impl.hpp Duct.cpp + ElectricalStorage.hpp + ElectricalStorage_Impl.hpp + ElectricalStorage.cpp ElectricEquipment.hpp ElectricEquipment_Impl.hpp ElectricEquipment.cpp @@ -446,6 +449,9 @@ set(${target_name}_src ElectricLoadCenterInverterSimple.hpp ElectricLoadCenterInverterSimple_Impl.hpp ElectricLoadCenterInverterSimple.cpp + ElectricLoadCenterStorageSimple.hpp + ElectricLoadCenterStorageSimple_Impl.hpp + ElectricLoadCenterStorageSimple.cpp EvaporativeCoolerDirectResearchSpecial.hpp EvaporativeCoolerDirectResearchSpecial_Impl.hpp EvaporativeCoolerDirectResearchSpecial.cpp @@ -509,6 +515,12 @@ set(${target_name}_src Generator.hpp Generator_Impl.hpp Generator.cpp + GeneratorMicroTurbine.hpp + GeneratorMicroTurbine_Impl.hpp + GeneratorMicroTurbine.cpp + GeneratorMicroTurbineHeatRecovery.hpp + GeneratorMicroTurbineHeatRecovery_Impl.hpp + GeneratorMicroTurbineHeatRecovery.cpp GeneratorPhotovoltaic.hpp GeneratorPhotovoltaic_Impl.hpp GeneratorPhotovoltaic.cpp @@ -634,9 +646,12 @@ set(${target_name}_src MaterialPropertyGlazingSpectralData.hpp MaterialPropertyGlazingSpectralData_Impl.hpp MaterialPropertyGlazingSpectralData.cpp - Meter.hpp - Meter_Impl.hpp - Meter.cpp + MeterCustom.hpp + MeterCustom_Impl.hpp + MeterCustom.cpp + MeterCustomDecrement.hpp + MeterCustomDecrement_Impl.hpp + MeterCustomDecrement.cpp Mixer.hpp Mixer_Impl.hpp Mixer.cpp @@ -658,6 +673,9 @@ set(${target_name}_src OutputControlReportingTolerances.hpp OutputControlReportingTolerances_Impl.hpp OutputControlReportingTolerances.cpp + OutputMeter.hpp + OutputMeter_Impl.hpp + OutputMeter.cpp OutputVariable.hpp OutputVariable_Impl.hpp OutputVariable.cpp @@ -1373,12 +1391,11 @@ set(${target_name}_moc LuminaireDefinition_Impl.hpp MasslessOpaqueMaterial_Impl.hpp Material_Impl.hpp - MaterialPropertyGlazingSpectralData_Impl.hpp - Meter_Impl.hpp OpaqueMaterial_Impl.hpp OtherEquipment_Impl.hpp OtherEquipmentDefinition_Impl.hpp OutputControlReportingTolerances_Impl.hpp + OutputMeter_Impl.hpp OutputVariable_Impl.hpp OutsideSurfaceConvectionAlgorithm_Impl.hpp ParentObject_Impl.hpp @@ -1582,6 +1599,7 @@ set(${target_name}_test_src test/ElectricLoadCenterDistribution_GTest.cpp test/ElectricLoadCenterInverterSimple_GTest.cpp test/ElectricLoadCenterInverterLookUpTable_GTest.cpp + test/ElectricLoadCenterStorageSimple_GTest.cpp test/EvaporativeCoolerDirectResearchSpecial_GTest.cpp test/EvaporativeCoolerIndirectResearchSpecial_GTest.cpp test/EvaporativeFluidCoolerSingleSpeed_GTest.cpp @@ -1598,6 +1616,7 @@ set(${target_name}_test_src test/GasMixture_GTest.cpp test/Gas_GTest.cpp test/GeneratorPhotovoltaic_GTest.cpp + test/GeneratorMicroTurbine_GTest.cpp test/GlareSensor_GTest.cpp test/GroundHeatExchangerHorizontalTrench_GTest.cpp test/GroundHeatExchangerVertical_GTest.cpp @@ -1623,7 +1642,8 @@ set(${target_name}_test_src test/MasslessOpaqueMaterial_GTest.cpp test/Material_GTest.cpp test/MaterialPropertyGlazingSpectralData_GTest.cpp - test/Meter_GTest.cpp + test/MeterCustom_GTest.cpp + test/MeterCustomDecrement_GTest.cpp test/ModelFixture.cpp test/ModelFixture.hpp test/ModelObject_GTest.cpp @@ -1634,6 +1654,7 @@ set(${target_name}_test_src test/OpaqueMaterial_GTest.cpp test/OtherEquipment_GTest.cpp test/OutputControlReportingTolerances_GTest.cpp + test/OutputMeter_GTest.cpp test/OutputVariable_GTest.cpp test/ParentObject_GTest.cpp test/People_GTest.cpp diff --git a/openstudiocore/src/model/ConcreteModelObjects.hpp b/openstudiocore/src/model/ConcreteModelObjects.hpp index c9a37c549b9..759fd598561 100644 --- a/openstudiocore/src/model/ConcreteModelObjects.hpp +++ b/openstudiocore/src/model/ConcreteModelObjects.hpp @@ -154,6 +154,7 @@ #include "ElectricLoadCenterDistribution.hpp" #include "ElectricLoadCenterInverterLookUpTable.hpp" #include "ElectricLoadCenterInverterSimple.hpp" +#include "ElectricLoadCenterStorageSimple.hpp" #include "EvaporativeCoolerDirectResearchSpecial.hpp" #include "EvaporativeCoolerIndirectResearchSpecial.hpp" #include "EvaporativeFluidCoolerSingleSpeed.hpp" @@ -172,6 +173,8 @@ #include "GasEquipment.hpp" #include "GasEquipmentDefinition.hpp" #include "GasMixture.hpp" +#include "GeneratorMicroTurbine.hpp" +#include "GeneratorMicroTurbineHeatRecovery.hpp" #include "GeneratorPhotovoltaic.hpp" #include "GenericModelObject.hpp" #include "GlareSensor.hpp" @@ -207,13 +210,15 @@ #include "LuminaireDefinition.hpp" #include "MaterialPropertyGlazingSpectralData.hpp" #include "MasslessOpaqueMaterial.hpp" -#include "Meter.hpp" +#include "MeterCustom.hpp" +#include "MeterCustomDecrement.hpp" #include "ModelObjectList.hpp" #include "Node.hpp" #include "PortList.hpp" #include "OtherEquipment.hpp" #include "OtherEquipmentDefinition.hpp" #include "OutputControlReportingTolerances.hpp" +#include "OutputMeter.hpp" #include "OutputVariable.hpp" #include "OutsideSurfaceConvectionAlgorithm.hpp" #include "People.hpp" @@ -527,6 +532,7 @@ #include "ElectricLoadCenterDistribution_Impl.hpp" #include "ElectricLoadCenterInverterLookUpTable_Impl.hpp" #include "ElectricLoadCenterInverterSimple_Impl.hpp" +#include "ElectricLoadCenterStorageSimple_Impl.hpp" #include "EvaporativeCoolerDirectResearchSpecial_Impl.hpp" #include "EvaporativeCoolerIndirectResearchSpecial_Impl.hpp" #include "EvaporativeFluidCoolerSingleSpeed_Impl.hpp" @@ -545,6 +551,8 @@ #include "GasEquipment_Impl.hpp" #include "GasEquipmentDefinition_Impl.hpp" #include "GasMixture_Impl.hpp" +#include "GeneratorMicroTurbine_Impl.hpp" +#include "GeneratorMicroTurbineHeatRecovery_Impl.hpp" #include "GeneratorPhotovoltaic_Impl.hpp" #include "GenericModelObject_Impl.hpp" #include "GlareSensor_Impl.hpp" @@ -580,13 +588,15 @@ #include "LuminaireDefinition_Impl.hpp" #include "MaterialPropertyGlazingSpectralData_Impl.hpp" #include "MasslessOpaqueMaterial_Impl.hpp" -#include "Meter_Impl.hpp" +#include "MeterCustom_Impl.hpp" +#include "MeterCustomDecrement_Impl.hpp" #include "ModelObjectList_Impl.hpp" #include "Node_Impl.hpp" #include "PortList_Impl.hpp" #include "OtherEquipment_Impl.hpp" #include "OtherEquipmentDefinition_Impl.hpp" #include "OutputControlReportingTolerances_Impl.hpp" +#include "OutputMeter_Impl.hpp" #include "OutputVariable_Impl.hpp" #include "OutsideSurfaceConvectionAlgorithm_Impl.hpp" #include "People_Impl.hpp" diff --git a/openstudiocore/src/model/ElectricLoadCenterDistribution.cpp b/openstudiocore/src/model/ElectricLoadCenterDistribution.cpp index 1d411516bf5..6d4bde1aecb 100644 --- a/openstudiocore/src/model/ElectricLoadCenterDistribution.cpp +++ b/openstudiocore/src/model/ElectricLoadCenterDistribution.cpp @@ -29,10 +29,12 @@ #include "Generator_Impl.hpp" #include "Inverter.hpp" #include "Inverter_Impl.hpp" -//#include "ElecricalStorage.hpp" -//#include "ElecricalStorage_Impl.hpp" +#include "ElectricalStorage.hpp" +#include "ElectricalStorage_Impl.hpp" //#include "Transformer.hpp" //#include "Transformer_Impl.hpp" +//#include "ElectricLoadCenterStorageConverter.hpp" +//#include "ElectricLoadCenterStorageConverter_Impl.hpp" #include "../../model/ScheduleTypeLimits.hpp" #include "../../model/ScheduleTypeRegistry.hpp" @@ -98,6 +100,15 @@ namespace detail { { result.push_back(ScheduleTypeKey("ElectricLoadCenterDistribution","Track Scheme")); } + if (std::find(b, e, OS_ElectricLoadCenter_DistributionFields::StorageChargePowerFractionScheduleName) != e) { + result.push_back(ScheduleTypeKey("ElectricLoadCenterDistribution", "Storage Charge Power Fraction")); + } + if (std::find(b, e, OS_ElectricLoadCenter_DistributionFields::StorageDischargePowerFractionScheduleName) != e) { + result.push_back(ScheduleTypeKey("ElectricLoadCenterDistribution", "Storage Discharge Power Fraction")); + } + if (std::find(b, e, OS_ElectricLoadCenter_DistributionFields::StorageControlUtilityDemandTargetFractionScheduleName) != e) { + result.push_back(ScheduleTypeKey("ElectricLoadCenterDistribution", "Storage Control Utility Demand Target Fraction")); + } return result; } @@ -105,6 +116,13 @@ namespace detail { { std::vector result; result.push_back(generatorModelObjectList()); + if (boost::optional optInverter = inverter()) { + result.push_back(optInverter.get()); + } + if (boost::optional optElectricalStorage = electricalStorage()) { + result.push_back(optElectricalStorage.get()); + } + return result; } @@ -144,17 +162,17 @@ namespace detail { return isEmpty(OS_ElectricLoadCenter_DistributionFields::GeneratorOperationSchemeType); } - //boost::optional ElectricLoadCenterDistribution_Impl::demandLimitSchemePurchasedElectricDemandLimit() const { - // return getDouble(OS_ElectricLoadCenter_DistributionFields::DemandLimitSchemePurchasedElectricDemandLimit,true); - //} + boost::optional ElectricLoadCenterDistribution_Impl::demandLimitSchemePurchasedElectricDemandLimit() const { + return getDouble(OS_ElectricLoadCenter_DistributionFields::DemandLimitSchemePurchasedElectricDemandLimit, false); + } - //boost::optional ElectricLoadCenterDistribution_Impl::trackScheduleSchemeSchedule() const { - // return getObject().getModelObjectTarget(OS_ElectricLoadCenter_DistributionFields::TrackScheduleNameSchemeScheduleName); - //} + boost::optional ElectricLoadCenterDistribution_Impl::trackScheduleSchemeSchedule() const { + return getObject().getModelObjectTarget(OS_ElectricLoadCenter_DistributionFields::TrackScheduleNameSchemeScheduleName); + } - //boost::optional ElectricLoadCenterDistribution_Impl::trackMeterSchemeMeterName() const { - // return getString(OS_ElectricLoadCenter_DistributionFields::TrackMeterSchemeMeterName,true); - //} + boost::optional ElectricLoadCenterDistribution_Impl::trackMeterSchemeMeterName() const { + return getString(OS_ElectricLoadCenter_DistributionFields::TrackMeterSchemeMeterName, true, true); + } std::string ElectricLoadCenterDistribution_Impl::electricalBussType() const { boost::optional value = getString(OS_ElectricLoadCenter_DistributionFields::ElectricalBussType,true); @@ -167,17 +185,106 @@ namespace detail { } boost::optional ElectricLoadCenterDistribution_Impl::inverter() const { - return getObject().getModelObjectTarget(OS_ElectricLoadCenter_DistributionFields::InverterObjectName); + return getObject().getModelObjectTarget(OS_ElectricLoadCenter_DistributionFields::InverterName); } - //boost::optional ElectricLoadCenterDistribution_Impl::electricalStorage() const { - // return getObject().getModelObjectTarget(OS_ElectricLoadCenter_DistributionFields::ElectricalStorageObjectName); - //} + boost::optional ElectricLoadCenterDistribution_Impl::electricalStorage() const { + return getObject().getModelObjectTarget(OS_ElectricLoadCenter_DistributionFields::ElectricalStorageObjectName); + } //boost::optional ElectricLoadCenterDistribution_Impl::transformer() const { // return getObject().getModelObjectTarget(OS_ElectricLoadCenter_DistributionFields::TransformerObjectName); //} + // Storage Operation Scheme, defaults to TrackFacilityElectricDemandStoreExcessOnSite + std::string ElectricLoadCenterDistribution_Impl::storageOperationScheme() const { + boost::optional value = getString(OS_ElectricLoadCenter_DistributionFields::StorageOperationScheme, true); + OS_ASSERT(value); + return value.get(); + } + + bool ElectricLoadCenterDistribution_Impl::isStorageOperationSchemeDefaulted() const { + return isEmpty(OS_ElectricLoadCenter_DistributionFields::StorageOperationScheme); + } + // Storage Control Track Meter Name, required if operation = TrackMeterDemandStoreExcessOnSite + boost::optional ElectricLoadCenterDistribution_Impl::storageControlTrackMeterName() const { + return getString(OS_ElectricLoadCenter_DistributionFields::StorageControlTrackMeterName, true, true); + } + + // Storage Converter Object Name + //boost::optional storageConverter() const; + + // Maximum Storage State of Charge Fraction, required if storage, defaults + double ElectricLoadCenterDistribution_Impl::maximumStorageStateofChargeFraction() const { + boost::optional value = getDouble(OS_ElectricLoadCenter_DistributionFields::MaximumStorageStateofChargeFraction, true); + OS_ASSERT(value); + return value.get(); + } + + bool ElectricLoadCenterDistribution_Impl::isMaximumStorageStateofChargeFractionDefaulted() const { + return isEmpty(OS_ElectricLoadCenter_DistributionFields::MaximumStorageStateofChargeFraction); + } + + // Minimum Storage State of Charge Fraction, required if storage, defaults + double ElectricLoadCenterDistribution_Impl::minimumStorageStateofChargeFraction() const { + boost::optional value = getDouble(OS_ElectricLoadCenter_DistributionFields::MinimumStorageStateofChargeFraction, true); + OS_ASSERT(value); + return value.get(); + } + bool ElectricLoadCenterDistribution_Impl::isMinimumStorageStateofChargeFractionDefaulted() const { + return isEmpty(OS_ElectricLoadCenter_DistributionFields::MinimumStorageStateofChargeFraction); + } + + // Design Storage Control Charge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules + boost::optional ElectricLoadCenterDistribution_Impl::designStorageControlChargePower() const { + return getDouble(OS_ElectricLoadCenter_DistributionFields::DesignStorageControlChargePower, true); + } + + // Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules + // TODO: do I want to default that to daytime? + boost::optional ElectricLoadCenterDistribution_Impl::storageChargePowerFractionSchedule() const { + return getObject().getModelObjectTarget(OS_ElectricLoadCenter_DistributionFields::StorageChargePowerFractionScheduleName); + } + + + // Design Storage Control Discharge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules + boost::optional ElectricLoadCenterDistribution_Impl::designStorageControlDischargePower() const { + return getDouble(OS_ElectricLoadCenter_DistributionFields::DesignStorageControlDischargePower, true); + } + + // Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules + // TODO: do I want to default that to daytime? + boost::optional ElectricLoadCenterDistribution_Impl::storageDischargePowerFractionSchedule() const { + return getObject().getModelObjectTarget(OS_ElectricLoadCenter_DistributionFields::StorageDischargePowerFractionScheduleName); + } + + + // Storage Control Utility Demand Target, required if FacilityDemandLeveling + boost::optional ElectricLoadCenterDistribution_Impl::storageControlUtilityDemandTarget() const { + return getDouble(OS_ElectricLoadCenter_DistributionFields::StorageControlUtilityDemandTarget, true); + } + + + // Storage Control Utility Demand Target Fraction Schedule Name, will be used only if FacilityDemandLeveling, defaults to 1.0 + Schedule ElectricLoadCenterDistribution_Impl::storageControlUtilityDemandTargetFractionSchedule() const { + boost::optional sch = getObject().getModelObjectTarget(OS_ElectricLoadCenter_DistributionFields::StorageControlUtilityDemandTargetFractionScheduleName); + if (sch) { + return sch.get(); + } else { + return this->model().alwaysOnDiscreteSchedule(); + } + } + + bool ElectricLoadCenterDistribution_Impl::isStorageControlUtilityDemandTargetFractionScheduleDefaulted() const { + return isEmpty(OS_ElectricLoadCenter_DistributionFields::StorageControlUtilityDemandTargetFractionScheduleName); + } + + + /// Setters + + + + bool ElectricLoadCenterDistribution_Impl::addGenerator(const Generator& generator) { if (!isElectricalBussTypeDefaulted()){ @@ -243,37 +350,38 @@ namespace detail { OS_ASSERT(result); } - //void ElectricLoadCenterDistribution_Impl::setDemandLimitSchemePurchasedElectricDemandLimit(double demandLimitSchemePurchasedElectricDemandLimit) { - // bool result = setDouble(OS_ElectricLoadCenter_DistributionFields::DemandLimitSchemePurchasedElectricDemandLimit, demandLimitSchemePurchasedElectricDemandLimit); - // OS_ASSERT(result); - //} + bool ElectricLoadCenterDistribution_Impl::setDemandLimitSchemePurchasedElectricDemandLimit(double demandLimitSchemePurchasedElectricDemandLimit) { + bool result = setDouble(OS_ElectricLoadCenter_DistributionFields::DemandLimitSchemePurchasedElectricDemandLimit, demandLimitSchemePurchasedElectricDemandLimit); + OS_ASSERT(result); + return result; + } - //void ElectricLoadCenterDistribution_Impl::resetDemandLimitSchemePurchasedElectricDemandLimit() { - // bool result = setString(OS_ElectricLoadCenter_DistributionFields::DemandLimitSchemePurchasedElectricDemandLimit, ""); - // OS_ASSERT(result); - //} + void ElectricLoadCenterDistribution_Impl::resetDemandLimitSchemePurchasedElectricDemandLimit() { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::DemandLimitSchemePurchasedElectricDemandLimit, ""); + OS_ASSERT(result); + } - //bool ElectricLoadCenterDistribution_Impl::setTrackScheduleSchemeSchedule(Schedule& schedule) { - // bool result = setSchedule(OS_ElectricLoadCenter_DistributionFields::TrackScheduleNameSchemeScheduleName, - // "ElectricLoadCenterDistribution", - // "Track Scheme", - // schedule); - // return result; - //} + bool ElectricLoadCenterDistribution_Impl::setTrackScheduleSchemeSchedule(Schedule& schedule) { + bool result = setSchedule(OS_ElectricLoadCenter_DistributionFields::TrackScheduleNameSchemeScheduleName, + "ElectricLoadCenterDistribution", + "Track Scheme", + schedule); + return result; + } - //void ElectricLoadCenterDistribution_Impl::resetTrackScheduleSchemeSchedule() { - // bool result = setString(OS_ElectricLoadCenter_DistributionFields::TrackScheduleNameSchemeScheduleName, ""); - // OS_ASSERT(result); - //} + void ElectricLoadCenterDistribution_Impl::resetTrackScheduleSchemeSchedule() { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::TrackScheduleNameSchemeScheduleName, ""); + OS_ASSERT(result); + } - //bool ElectricLoadCenterDistribution_Impl::setTrackMeterSchemeMeterName(const std::string& trackMeterSchemeMeterName) { - // return setString(OS_ElectricLoadCenter_DistributionFields::TrackMeterSchemeMeterName, trackMeterSchemeMeterName); - //} + bool ElectricLoadCenterDistribution_Impl::setTrackMeterSchemeMeterName(const std::string& trackMeterSchemeMeterName) { + return setString(OS_ElectricLoadCenter_DistributionFields::TrackMeterSchemeMeterName, trackMeterSchemeMeterName); + } - //void ElectricLoadCenterDistribution_Impl::resetTrackMeterSchemeMeterName() { - // bool result = setString(OS_ElectricLoadCenter_DistributionFields::TrackMeterSchemeMeterName, ""); - // OS_ASSERT(result); - //} + void ElectricLoadCenterDistribution_Impl::resetTrackMeterSchemeMeterName() { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::TrackMeterSchemeMeterName, ""); + OS_ASSERT(result); + } bool ElectricLoadCenterDistribution_Impl::setElectricalBussType(const std::string& electricalBussType) { bool result = setString(OS_ElectricLoadCenter_DistributionFields::ElectricalBussType, electricalBussType); @@ -298,7 +406,7 @@ namespace detail { } // DLM: may have problems with signals here if inverter is temporarily on two load centers - bool result = setPointer(OS_ElectricLoadCenter_DistributionFields::InverterObjectName, inverter.handle()); + bool result = setPointer(OS_ElectricLoadCenter_DistributionFields::InverterName, inverter.handle()); if (result){ @@ -317,20 +425,20 @@ namespace detail { } void ElectricLoadCenterDistribution_Impl::resetInverter() { - bool result = setString(OS_ElectricLoadCenter_DistributionFields::InverterObjectName, ""); + bool result = setString(OS_ElectricLoadCenter_DistributionFields::InverterName, ""); // TODO: update bus type OS_ASSERT(result); } - //bool ElectricLoadCenterDistribution_Impl::setElectricalStorage(const ElectricalStorage& electricalStorage) { - // return setPointer(OS_ElectricLoadCenter_DistributionFields::ElectricalStorageObjectName, electricalStorage.handle()); - //} + bool ElectricLoadCenterDistribution_Impl::setElectricalStorage(const ElectricalStorage& electricalStorage) { + return setPointer(OS_ElectricLoadCenter_DistributionFields::ElectricalStorageObjectName, electricalStorage.handle()); + } - //void ElectricLoadCenterDistribution_Impl::resetElectricalStorage() { - // bool result = setString(OS_ElectricLoadCenter_DistributionFields::ElectricalStorageObjectName, ""); - // OS_ASSERT(result); - //} + void ElectricLoadCenterDistribution_Impl::resetElectricalStorage() { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::ElectricalStorageObjectName, ""); + OS_ASSERT(result); + } //bool ElectricLoadCenterDistribution_Impl::setTransformer(const Transformer& transformer) { // return setPointer(OS_ElectricLoadCenter_DistributionFields::TransformerObjectName, transformer.handle()); @@ -347,6 +455,294 @@ namespace detail { return result.get(); } + // Storage Operation Scheme + bool ElectricLoadCenterDistribution_Impl::setStorageOperationScheme(const std::string& operationScheme) { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::StorageOperationScheme, operationScheme); + OS_ASSERT(result); + return result; + } + + void ElectricLoadCenterDistribution_Impl::resetStorageOperationScheme() { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::StorageOperationScheme, ""); + OS_ASSERT(result); + } + + // Storage Control Track Meter Name, required if operation = TrackMeterDemandStoreExcessOnSite + bool ElectricLoadCenterDistribution_Impl::setStorageControlTrackMeterName(const std::string& meterName) { + return setString(OS_ElectricLoadCenter_DistributionFields::StorageControlTrackMeterName, meterName); + } + + void ElectricLoadCenterDistribution_Impl::resetStorageControlTrackMeterName() { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::StorageControlTrackMeterName, ""); + OS_ASSERT(result); + } + + + // Storage Converter Object Name + //bool ElectricLoadCenterDistribution_Impl::setStorageConverter(const ElectricLoadCenterStorageConverter& converter); + //void ElectricLoadCenterDistribution_Impl::resetStorageConverter(); + + // Maximum Storage State of Charge Fraction, required if storage, defaults + bool ElectricLoadCenterDistribution_Impl::setMaximumStorageStateofChargeFraction(const double maxStateofCharge) { + bool result = setDouble(OS_ElectricLoadCenter_DistributionFields::MaximumStorageStateofChargeFraction, maxStateofCharge); + OS_ASSERT(result); + return result; + } + void ElectricLoadCenterDistribution_Impl::resetMaximumStorageStateofChargeFraction() { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::MaximumStorageStateofChargeFraction, ""); + OS_ASSERT(result); + } + + // Minimum Storage State of Charge Fraction, required if storage, defaults + bool ElectricLoadCenterDistribution_Impl::setMinimumStorageStateofChargeFraction(const double minStateofCharge) { + bool result = setDouble(OS_ElectricLoadCenter_DistributionFields::MinimumStorageStateofChargeFraction, minStateofCharge); + OS_ASSERT(result); + return result; + } + void ElectricLoadCenterDistribution_Impl::resetMinimumStorageStateofChargeFraction() { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::MinimumStorageStateofChargeFraction, ""); + OS_ASSERT(result); + } + + // Design Storage Control Charge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules + bool ElectricLoadCenterDistribution_Impl::setDesignStorageControlChargePower(const double designStorageControlChargePower) { + bool result = setDouble(OS_ElectricLoadCenter_DistributionFields::DesignStorageControlChargePower, designStorageControlChargePower); + OS_ASSERT(result); + return result; + } + void ElectricLoadCenterDistribution_Impl::resetDesignStorageControlChargePower() { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::DesignStorageControlChargePower, ""); + OS_ASSERT(result); + } + + // Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules + // TODO: do I want to default that to daytime? + bool ElectricLoadCenterDistribution_Impl::setStorageChargePowerFractionSchedule(Schedule& schedule) { + bool result = setSchedule(OS_ElectricLoadCenter_DistributionFields::StorageChargePowerFractionScheduleName, + "ElectricLoadCenterDistribution", + "Storage Charge Power Fraction", + schedule); + return result; + } + + void ElectricLoadCenterDistribution_Impl::resetStorageChargePowerFractionSchedule() { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::StorageChargePowerFractionScheduleName, ""); + OS_ASSERT(result); + } + + // Design Storage Control Discharge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules + bool ElectricLoadCenterDistribution_Impl::setDesignStorageControlDischargePower(const double designStorageControlDischargePower) { + bool result = setDouble(OS_ElectricLoadCenter_DistributionFields::DesignStorageControlDischargePower, designStorageControlDischargePower); + OS_ASSERT(result); + return result; + } + void ElectricLoadCenterDistribution_Impl::resetDesignStorageControlDischargePower() { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::DesignStorageControlDischargePower, ""); + OS_ASSERT(result); + } + + + // Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules + // TODO: do I want to default that to daytime? + bool ElectricLoadCenterDistribution_Impl::setStorageDischargePowerFractionSchedule(Schedule& schedule) { + bool result = setSchedule(OS_ElectricLoadCenter_DistributionFields::StorageDischargePowerFractionScheduleName, + "ElectricLoadCenterDistribution", + "Storage Discharge Power Fraction", + schedule); + return result; + } + + void ElectricLoadCenterDistribution_Impl::resetStorageDischargePowerFractionSchedule() { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::StorageDischargePowerFractionScheduleName, ""); + OS_ASSERT(result); + } + + // Storage Control Utility Demand Target, required if FacilityDemandLeveling + bool ElectricLoadCenterDistribution_Impl::setStorageControlUtilityDemandTarget(const double storageControlUtilityDemandTarget) { + bool result = setDouble(OS_ElectricLoadCenter_DistributionFields::StorageControlUtilityDemandTarget, storageControlUtilityDemandTarget); + OS_ASSERT(result); + return result; + } + void ElectricLoadCenterDistribution_Impl::resetStorageControlUtilityDemandTarget() { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::StorageControlUtilityDemandTarget, ""); + OS_ASSERT(result); + } + + // Storage Control Utility Demand Target Fraction Schedule Name, will be used only if FacilityDemandLeveling, defaults to 1.0 + bool ElectricLoadCenterDistribution_Impl::setStorageControlUtilityDemandTargetFractionSchedule(Schedule& schedule) { + bool result = setSchedule(OS_ElectricLoadCenter_DistributionFields::StorageControlUtilityDemandTargetFractionScheduleName, + "ElectricLoadCenterDistribution", + "Storage Control Utility Demand Target Fraction", + schedule); + return result; + } + + void ElectricLoadCenterDistribution_Impl::resetStorageControlUtilityDemandTargetFractionSchedule() { + bool result = setString(OS_ElectricLoadCenter_DistributionFields::StorageControlUtilityDemandTargetFractionScheduleName, ""); + OS_ASSERT(result); + } + + + // Validity Checking + bool ElectricLoadCenterDistribution_Impl::validityCheck() const { + + // Logic based on Electrical Buss Type to translate or not translate inverters, storage + bool result = true; + + std::string bussType = electricalBussType(); + + /// Inverter and Buss Type + boost::optional inv = inverter(); + bool bussWithInverter = (bussType == "DirectCurrentWithInverter" || + bussType == "DirectCurrentWithInverterDCStorage" || + bussType == "DirectCurrentWithInverterACStorage"); + + // Case 1: There is an inverter and a Buss with inverter: all good + if (inv && bussWithInverter) { + LOG(Info, briefDescription() << ": Your Electric Buss Type '" << bussType + << "' is compatible with inverter objects and you do have an inverter '" + << inv->name().get() << "'"); + // Case 2: if there's an inverter, but the buss is not compatible, we issue a Warning and don't translate the inverter + } else if (inv && !bussWithInverter) { + LOG(Warn, briefDescription() << ": Your Electric Buss Type '" << bussType + << "' is not compatible with inverter objects. The inverter object '" + << inv->name().get() << " will not be translated'"); + + // Case 3: if there is a buss that expects an inverter, but not inverter: this is bad, it'll throw a fatal in E+ + } else if (bussWithInverter && !inv) { + result = false; + LOG(Error, briefDescription() << ": Your Electric Buss Type '" << bussType + << "' Requires an inverter but you didn't specify one"); + } + // Case 4: there's no inverter and a buss type without inverter: nothing needs to be done + + + /// Storage & Buss Type + boost::optional elcSto = electricalStorage(); + bool bussWithStorage = (bussType == "AlternatingCurrentWithStorage" || + bussType == "DirectCurrentWithInverterDCStorage" || + bussType == "DirectCurrentWithInverterACStorage"); + + // Case 1: There is a Storage object and a Buss with Storage: all good + if (elcSto && bussWithStorage) { + + LOG(Info, briefDescription() << ": Your Electric Buss Type '" << bussType + << "' is compatible with storage objects and you do have an ELC:Storage:Simple '" + << elcSto->name().get() << "'"); + + // Storage Operation Scheme, defaults to TrackFacilityElectricDemandStoreExcessOnSite + std::string stoOpScheme = storageOperationScheme(); + + if (!isStorageOperationSchemeDefaulted()) { + LOG(Info, "Your Storage Operation Scheme is defaulted to '" << stoOpScheme + << "'"); + } + + // For all storageOperationScheme, we need to translate the Min/Max Storage SOC + // Maximum Storage State of Charge Fraction, defaults + // Nothing to do + + // Minimum Storage State of Charge Fraction, defaults + // Nothing to do + + /// Further testing based on storageOperationScheme + if (stoOpScheme == "TrackMeterDemandStoreExcessOnSite") { + // Storage Control Track Meter Name, required if operation = TrackMeterDemandStoreExcessOnSite or it'll produce a fatal + if (!storageControlTrackMeterName()) { + result = false; + LOG(Error, briefDescription() << ": You set the Storage Operation Scheme to " << stoOpScheme + << " but you didn't specify the required 'Storage Control Track Meter Name'"); + } + + } else if (stoOpScheme == "TrackChargeDischargeSchedules") { + // Storage Converter Object Name + //boost::optional storageConverter = storageConverter(); + //if (!storageConverter) { + // result = false; + // LOG(Error, briefDescription() << ": You set the Storage Operation Scheme to " << stoOpScheme + // << " but you didn't specify the required 'Storage Converter Object Name'"); + //} + + // Design Storage Control Charge Power + if (!designStorageControlChargePower()) { + result = false; + LOG(Error, briefDescription() << ": You set the Storage Operation Scheme to " << stoOpScheme + << " but you didn't specify the required 'Design Storage Control Charge Power'"); + } + + // Design Storage Control Discharge Power + if (!designStorageControlDischargePower()) { + result = false; + LOG(Error, briefDescription() << ": You set the Storage Operation Scheme to " << stoOpScheme + << " but you didn't specify the required 'Design Storage Control Discharge Power'"); + } + + // Storage Charge Power Fraction Schedule Name + if (!storageChargePowerFractionSchedule()) { + result = false; + LOG(Error, briefDescription() << ": You set the Storage Operation Scheme to " << stoOpScheme + << " but you didn't specify the required 'Storage Charge Power Fraction Schedule Name'"); + } + + // Discharge Power Fraction Schedule Name + if (!storageDischargePowerFractionSchedule()) { + result = false; + LOG(Error, briefDescription() << ": You set the Storage Operation Scheme to " << stoOpScheme + << " but you didn't specify the required 'Storage Discharge Power Fraction Schedule Name'"); + } + + } else if (stoOpScheme == "FacilityDemandLeveling") { + // Storage Converter Object Name + //boost::optional storageConverter = storageConverter(); + //if (!storageConverter) { + // result = false; + // LOG(Error, briefDescription() << ": You set the Storage Operation Scheme to " << stoOpScheme + // << " but you didn't specify the required 'Storage Converter Object Name'"); + //} + + // Design Storage Control Charge Power + if (!designStorageControlChargePower()) { + result = false; + LOG(Error, briefDescription() << ": You set the Storage Operation Scheme to " << stoOpScheme + << " but you didn't specify the required 'Design Storage Control Charge Power'"); + } + + // Design Storage Control Discharge Power + if (!designStorageControlDischargePower()) { + result = false; + LOG(Error, briefDescription() << ": You set the Storage Operation Scheme to " << stoOpScheme + << " but you didn't specify the required 'Design Storage Control Discharge Power'"); + } + + // Storage Control Utility Demand Target + if (!storageControlUtilityDemandTarget()) { + result = false; + LOG(Error, briefDescription() << ": You set the Storage Operation Scheme to " << stoOpScheme + << " but you didn't specify the required 'Storage Control Utility Demand Target'"); + } + + + } // end if (storageOperationScheme) + // Case 2: if there's a Storage object, but the buss is not compatible, we issue a Warning and don't translate Any of the storage objects + } else if (elcSto && !bussWithStorage) { + LOG(Warn, briefDescription() << ": Your Electric Buss Type '" << bussType + << "' is not compatible with storage objects. No storage objects will be translated including the Battery itself:'" + << elcSto->name().get() << "'"); + + // Case 3: if there is a buss that expects Storage, but no Storage: this is bad, it'll throw a fatal in E+ + } else if (bussWithStorage && !elcSto) { + LOG(Error, briefDescription() << ": Your Electric Buss Type '" << bussType + << "' Requires an electrical Storage object but you didn't specify one"); + } + // Case 4: there's no inverter and a buss type without inverter: nothing needs to be done + + + return result; + + } + + + } // detail ElectricLoadCenterDistribution::ElectricLoadCenterDistribution(const Model& model) @@ -373,6 +769,14 @@ std::vector ElectricLoadCenterDistribution::electricalBussTypeValue OS_ElectricLoadCenter_DistributionFields::ElectricalBussType); } +std::vector ElectricLoadCenterDistribution::storageOperationSchemeValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), + OS_ElectricLoadCenter_DistributionFields::StorageOperationScheme); +} + + + + std::vector ElectricLoadCenterDistribution::generators() const { return getImpl()->generators(); } @@ -385,17 +789,17 @@ bool ElectricLoadCenterDistribution::isGeneratorOperationSchemeTypeDefaulted() c return getImpl()->isGeneratorOperationSchemeTypeDefaulted(); } -//boost::optional ElectricLoadCenterDistribution::demandLimitSchemePurchasedElectricDemandLimit() const { -// return getImpl()->demandLimitSchemePurchasedElectricDemandLimit(); -//} +boost::optional ElectricLoadCenterDistribution::demandLimitSchemePurchasedElectricDemandLimit() const { + return getImpl()->demandLimitSchemePurchasedElectricDemandLimit(); +} -//boost::optional ElectricLoadCenterDistribution::trackScheduleSchemeSchedule() const { -// return getImpl()->trackScheduleSchemeSchedule(); -//} +boost::optional ElectricLoadCenterDistribution::trackScheduleSchemeSchedule() const { + return getImpl()->trackScheduleSchemeSchedule(); +} -//boost::optional ElectricLoadCenterDistribution::trackMeterSchemeMeterName() const { -// return getImpl()->trackMeterSchemeMeterName(); -//} +boost::optional ElectricLoadCenterDistribution::trackMeterSchemeMeterName() const { + return getImpl()->trackMeterSchemeMeterName(); +} std::string ElectricLoadCenterDistribution::electricalBussType() const { return getImpl()->electricalBussType(); @@ -409,14 +813,89 @@ boost::optional ElectricLoadCenterDistribution::inverter() const { return getImpl()->inverter(); } -//boost::optional ElectricLoadCenterDistribution::elecricalStorage() const { -// return getImpl()->elecricalStorage(); -//} +boost::optional ElectricLoadCenterDistribution::electricalStorage() const { + return getImpl()->electricalStorage(); +} //boost::optional ElectricLoadCenterDistribution::transformer() const { // return getImpl()->transformer(); //} +// New + +// Storage Operation Scheme, defaults to TrackFacilityElectricDemandStoreExcessOnSite +std::string ElectricLoadCenterDistribution::storageOperationScheme() const { + return getImpl()->storageOperationScheme(); +} +bool ElectricLoadCenterDistribution::isStorageOperationSchemeDefaulted() const { + return getImpl()->isStorageOperationSchemeDefaulted(); +} + +// Storage Control Track Meter Name, required if operation = TrackMeterDemandStoreExcessOnSite +boost::optional ElectricLoadCenterDistribution::storageControlTrackMeterName() const { + return getImpl()->storageControlTrackMeterName(); +} + +// Storage Converter Object Name +//boost::optional ElectricLoadCenterDistribution::storageConverterObjectName() const { +// return getImpl()->storageConverterObjectName(); +//} + +// Maximum Storage State of Charge Fraction, required if storage, defaults +double ElectricLoadCenterDistribution::maximumStorageStateofChargeFraction() const { + return getImpl()->maximumStorageStateofChargeFraction(); +} +bool ElectricLoadCenterDistribution::isMaximumStorageStateofChargeFractionDefaulted() const { + return getImpl()->isMaximumStorageStateofChargeFractionDefaulted(); +} + +// Minimum Storage State of Charge Fraction, required if storage, defaults +double ElectricLoadCenterDistribution::minimumStorageStateofChargeFraction() const { + return getImpl()->minimumStorageStateofChargeFraction(); +} +bool ElectricLoadCenterDistribution::isMinimumStorageStateofChargeFractionDefaulted() const { + return getImpl()->isMinimumStorageStateofChargeFractionDefaulted(); +} + +// Design Storage Control Charge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules +boost::optional ElectricLoadCenterDistribution::designStorageControlChargePower() const { + return getImpl()->designStorageControlChargePower(); +} + +// Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules +// TODO: do I want to default that to daytime? +boost::optional ElectricLoadCenterDistribution::storageChargePowerFractionSchedule() const { + return getImpl()->storageChargePowerFractionSchedule(); +} + +// Design Storage Control Discharge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules +boost::optional ElectricLoadCenterDistribution::designStorageControlDischargePower() const { + return getImpl()->designStorageControlDischargePower(); +} + +// Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules +// TODO: do I want to default that to daytime? +boost::optional ElectricLoadCenterDistribution::storageDischargePowerFractionSchedule() const { + return getImpl()->storageDischargePowerFractionSchedule(); +} + + +// Storage Control Utility Demand Target, required if FacilityDemandLeveling +boost::optional ElectricLoadCenterDistribution::storageControlUtilityDemandTarget() const { + return getImpl()->storageControlUtilityDemandTarget(); +} + + +// Storage Control Utility Demand Target Fraction Schedule Name, will be used only if FacilityDemandLeveling, defaults to 1.0 +Schedule ElectricLoadCenterDistribution::storageControlUtilityDemandTargetFractionSchedule() const { + return getImpl()->storageControlUtilityDemandTargetFractionSchedule(); +} +bool ElectricLoadCenterDistribution::isStorageControlUtilityDemandTargetFractionScheduleDefaulted() const { + return getImpl()->isStorageControlUtilityDemandTargetFractionScheduleDefaulted(); +} + + + bool ElectricLoadCenterDistribution::addGenerator(const Generator& generator){ return getImpl()->addGenerator(generator); } @@ -437,37 +916,37 @@ void ElectricLoadCenterDistribution::resetGeneratorOperationSchemeType() { getImpl()->resetGeneratorOperationSchemeType(); } -//void ElectricLoadCenterDistribution::setDemandLimitSchemePurchasedElectricDemandLimit(double demandLimitSchemePurchasedElectricDemandLimit) { -// getImpl()->setDemandLimitSchemePurchasedElectricDemandLimit(demandLimitSchemePurchasedElectricDemandLimit); -//} +bool ElectricLoadCenterDistribution::setDemandLimitSchemePurchasedElectricDemandLimit(double demandLimitSchemePurchasedElectricDemandLimit) { + return getImpl()->setDemandLimitSchemePurchasedElectricDemandLimit(demandLimitSchemePurchasedElectricDemandLimit); +} -//void ElectricLoadCenterDistribution::resetDemandLimitSchemePurchasedElectricDemandLimit() { -// getImpl()->resetDemandLimitSchemePurchasedElectricDemandLimit(); -//} +void ElectricLoadCenterDistribution::resetDemandLimitSchemePurchasedElectricDemandLimit() { + getImpl()->resetDemandLimitSchemePurchasedElectricDemandLimit(); +} -//bool ElectricLoadCenterDistribution::setTrackScheduleSchemeSchedule(Schedule& schedule) { -// return getImpl()->setTrackScheduleSchemeSchedule(schedule); -//} +bool ElectricLoadCenterDistribution::setTrackScheduleSchemeSchedule(Schedule& schedule) { + return getImpl()->setTrackScheduleSchemeSchedule(schedule); +} -//void ElectricLoadCenterDistribution::resetTrackScheduleSchemeSchedule() { -// getImpl()->resetTrackScheduleSchemeSchedule(); -//} +void ElectricLoadCenterDistribution::resetTrackScheduleSchemeSchedule() { + getImpl()->resetTrackScheduleSchemeSchedule(); +} -//bool ElectricLoadCenterDistribution::setTrackMeterSchemeMeterName(const std::string& trackMeterSchemeMeterName) { -// return getImpl()->setTrackMeterSchemeMeterName(trackMeterSchemeMeterName); -//} +bool ElectricLoadCenterDistribution::setTrackMeterSchemeMeterName(const std::string& trackMeterSchemeMeterName) { + return getImpl()->setTrackMeterSchemeMeterName(trackMeterSchemeMeterName); +} -//void ElectricLoadCenterDistribution::resetTrackMeterSchemeMeterName() { -// getImpl()->resetTrackMeterSchemeMeterName(); -//} +void ElectricLoadCenterDistribution::resetTrackMeterSchemeMeterName() { + getImpl()->resetTrackMeterSchemeMeterName(); +} -//bool ElectricLoadCenterDistribution::setElectricalBussType(const std::string& electricalBussType) { -// return getImpl()->setElectricalBussType(electricalBussType); -//} +bool ElectricLoadCenterDistribution::setElectricalBussType(const std::string& electricalBussType) { + return getImpl()->setElectricalBussType(electricalBussType); +} -//void ElectricLoadCenterDistribution::resetElectricalBussType() { -// getImpl()->resetElectricalBussType(); -//} +void ElectricLoadCenterDistribution::resetElectricalBussType() { + getImpl()->resetElectricalBussType(); +} bool ElectricLoadCenterDistribution::setInverter(const Inverter& inverter) { return getImpl()->setInverter(inverter); @@ -477,13 +956,13 @@ void ElectricLoadCenterDistribution::resetInverter() { getImpl()->resetInverter(); } -//bool ElectricLoadCenterDistribution::setElecricalStorage(const ElecricalStorage& elecricalStorage) { -// return getImpl()->setElectricalStorageObject(elecricalStorage); -//} +bool ElectricLoadCenterDistribution::setElectricalStorage(const ElectricalStorage& electricalStorage) { + return getImpl()->setElectricalStorage(electricalStorage); +} -//void ElectricLoadCenterDistribution::resetElecricalStorage() { -// getImpl()->resetElecricalStorage(); -//} +void ElectricLoadCenterDistribution::resetElectricalStorage() { + getImpl()->resetElectricalStorage(); +} //bool ElectricLoadCenterDistribution::setTransformer(const Transformer& transformer) { // return getImpl()->setTransformer(transformer); @@ -493,6 +972,108 @@ void ElectricLoadCenterDistribution::resetInverter() { // getImpl()->resetTransformer(); //} +// Storage Operation Scheme +bool ElectricLoadCenterDistribution::setStorageOperationScheme(const std::string& operationScheme) { + return getImpl()->setStorageOperationScheme(operationScheme); +} +void ElectricLoadCenterDistribution::resetStorageOperationScheme() { + getImpl()->resetStorageOperationScheme(); +} + +// Storage Control Track Meter Name, required if operation = TrackMeterDemandStoreExcessOnSite +bool ElectricLoadCenterDistribution::setStorageControlTrackMeterName(const std::string& meterName) { + return getImpl()->setStorageControlTrackMeterName(meterName); +} +void ElectricLoadCenterDistribution::resetStorageControlTrackMeterName() { + getImpl()->resetStorageControlTrackMeterName(); +} + +// Storage Converter Object Name +//bool ElectricLoadCenterDistribution::setStorageConverter(const ElectricLoadCenterStorageConverter& converter) { +// return getImpl()->setStorageConverter(converter); +//} +//void ElectricLoadCenterDistribution::resetStorageConverter() { +// getImpl()->resetStorageConverter(); +//} + +// Maximum Storage State of Charge Fraction, required if storage, defaults +bool ElectricLoadCenterDistribution::setMaximumStorageStateofChargeFraction(const double maxStateofCharge) { + return getImpl()->setMaximumStorageStateofChargeFraction(maxStateofCharge); +} +void ElectricLoadCenterDistribution::resetMaximumStorageStateofChargeFraction() { + getImpl()->resetMaximumStorageStateofChargeFraction(); +} + + +// Minimum Storage State of Charge Fraction, required if storage, defaults +bool ElectricLoadCenterDistribution::setMinimumStorageStateofChargeFraction(const double minStateofCharge) { + return getImpl()->setMinimumStorageStateofChargeFraction(minStateofCharge); +} +void ElectricLoadCenterDistribution::resetMinimumStorageStateofChargeFraction() { + getImpl()->resetMinimumStorageStateofChargeFraction(); +} + + +// Design Storage Control Charge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules +bool ElectricLoadCenterDistribution::setDesignStorageControlChargePower(const double designStorageControlChargePower) { + return getImpl()->setDesignStorageControlChargePower(designStorageControlChargePower); +} +void ElectricLoadCenterDistribution::resetDesignStorageControlChargePower() { + getImpl()->resetDesignStorageControlChargePower(); +} + + +// Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules +// TODO: do I want to default that to daytime? +bool ElectricLoadCenterDistribution::setStorageChargePowerFractionSchedule(Schedule& schedule) { + return getImpl()->setStorageChargePowerFractionSchedule(schedule); +} +void ElectricLoadCenterDistribution::resetStorageChargePowerFractionSchedule() { + getImpl()->resetStorageChargePowerFractionSchedule(); +} + + +// Design Storage Control Discharge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules +bool ElectricLoadCenterDistribution::setDesignStorageControlDischargePower(const double designStorageControlDischargePower) { + return getImpl()->setDesignStorageControlDischargePower(designStorageControlDischargePower); +} +void ElectricLoadCenterDistribution::resetDesignStorageControlDischargePower() { + getImpl()->resetDesignStorageControlDischargePower(); +} + + +// Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules +// TODO: do I want to default that to daytime? +bool ElectricLoadCenterDistribution::setStorageDischargePowerFractionSchedule(Schedule& schedule) { + return getImpl()->setStorageDischargePowerFractionSchedule(schedule); +} +void ElectricLoadCenterDistribution::resetStorageDischargePowerFractionSchedule() { + getImpl()->resetStorageDischargePowerFractionSchedule(); +} + + +// Storage Control Utility Demand Target, required if FacilityDemandLeveling +bool ElectricLoadCenterDistribution::setStorageControlUtilityDemandTarget(const double storageControlUtilityDemandTarget) { + return getImpl()->setStorageControlUtilityDemandTarget(storageControlUtilityDemandTarget); +} +void ElectricLoadCenterDistribution::resetStorageControlUtilityDemandTarget() { + getImpl()->resetStorageControlUtilityDemandTarget(); +} + + +// Storage Control Utility Demand Target Fraction Schedule Name, will be used only if FacilityDemandLeveling, defaults to 1.0 +bool ElectricLoadCenterDistribution::setStorageControlUtilityDemandTargetFractionSchedule(Schedule& schedule) { + return getImpl()->setStorageControlUtilityDemandTargetFractionSchedule(schedule); +} +void ElectricLoadCenterDistribution::resetStorageControlUtilityDemandTargetFractionSchedule() { + getImpl()->resetStorageControlUtilityDemandTargetFractionSchedule(); +} + +bool ElectricLoadCenterDistribution::validityCheck() const { + return getImpl()->validityCheck(); +} + + /// @cond ElectricLoadCenterDistribution::ElectricLoadCenterDistribution(std::shared_ptr impl) : ParentObject(impl) diff --git a/openstudiocore/src/model/ElectricLoadCenterDistribution.hpp b/openstudiocore/src/model/ElectricLoadCenterDistribution.hpp index 5fa3883df30..bec4ef775e3 100644 --- a/openstudiocore/src/model/ElectricLoadCenterDistribution.hpp +++ b/openstudiocore/src/model/ElectricLoadCenterDistribution.hpp @@ -30,8 +30,9 @@ namespace model { class Schedule; class Generator; class Inverter; -//class ElectricalStorage; +class ElectricalStorage; //class Transformer; +//class ElectricLoadCenterConverter; namespace detail { @@ -62,6 +63,8 @@ class MODEL_API ElectricLoadCenterDistribution : public ParentObject { static std::vector electricalBussTypeValues(); + static std::vector storageOperationSchemeValues(); + /** @name Getters */ //@{ @@ -72,11 +75,11 @@ class MODEL_API ElectricLoadCenterDistribution : public ParentObject { bool isGeneratorOperationSchemeTypeDefaulted() const; - //boost::optional demandLimitSchemePurchasedElectricDemandLimit() const; + boost::optional demandLimitSchemePurchasedElectricDemandLimit() const; - //boost::optional trackScheduleSchemeSchedule() const; + boost::optional trackScheduleSchemeSchedule() const; - //boost::optional trackMeterSchemeMeterName() const; + boost::optional trackMeterSchemeMeterName() const; std::string electricalBussType() const; @@ -84,10 +87,55 @@ class MODEL_API ElectricLoadCenterDistribution : public ParentObject { boost::optional inverter() const; - //boost::optional electricalStorage() const; + boost::optional electricalStorage() const; //boost::optional transformer() const; + + // New + + // Storage Operation Scheme, defaults to TrackFacilityElectricDemandStoreExcessOnSite + std::string storageOperationScheme() const; + bool isStorageOperationSchemeDefaulted() const; + + // Storage Control Track Meter Name, required if operation = TrackMeterDemandStoreExcessOnSite + boost::optional storageControlTrackMeterName() const; + + // Storage Converter Object Name + //boost::optional storageConverter() const; + + // Maximum Storage State of Charge Fraction, required if storage, defaults + double maximumStorageStateofChargeFraction() const; + bool isMaximumStorageStateofChargeFractionDefaulted() const; + + // Minimum Storage State of Charge Fraction, required if storage, defaults + double minimumStorageStateofChargeFraction() const; + bool isMinimumStorageStateofChargeFractionDefaulted() const; + + // Design Storage Control Charge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules + boost::optional designStorageControlChargePower() const; + + // Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules + // TODO: do I want to default that to daytime? + boost::optional storageChargePowerFractionSchedule() const; + + // Design Storage Control Discharge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules + boost::optional designStorageControlDischargePower() const; + + // Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules + // TODO: do I want to default that to daytime? + boost::optional storageDischargePowerFractionSchedule() const; + + + // Storage Control Utility Demand Target, required if FacilityDemandLeveling + boost::optional storageControlUtilityDemandTarget() const; + + + // Storage Control Utility Demand Target Fraction Schedule Name, will be used only if FacilityDemandLeveling, defaults to 1.0 + Schedule storageControlUtilityDemandTargetFractionSchedule() const; + bool isStorageControlUtilityDemandTargetFractionScheduleDefaulted() const; + + //@} /** @name Setters */ //@{ @@ -102,38 +150,86 @@ class MODEL_API ElectricLoadCenterDistribution : public ParentObject { void resetGeneratorOperationSchemeType(); - //void setDemandLimitSchemePurchasedElectricDemandLimit(double demandLimitSchemePurchasedElectricDemandLimit); + bool setDemandLimitSchemePurchasedElectricDemandLimit(double demandLimitSchemePurchasedElectricDemandLimit); - //void resetDemandLimitSchemePurchasedElectricDemandLimit(); + void resetDemandLimitSchemePurchasedElectricDemandLimit(); - //bool setTrackScheduleSchemeSchedule(Schedule& schedule); + bool setTrackScheduleSchemeSchedule(Schedule& schedule); - //void resetTrackScheduleSchemeSchedule(); + void resetTrackScheduleSchemeSchedule(); - //bool setTrackMeterSchemeMeterName(const std::string& trackMeterSchemeMeterName); + bool setTrackMeterSchemeMeterName(const std::string& trackMeterSchemeMeterName); - //void resetTrackMeterSchemeMeterName(); + void resetTrackMeterSchemeMeterName(); - //bool setElectricalBussType(const std::string& electricalBussType); + bool setElectricalBussType(const std::string& electricalBussType); - //void resetElectricalBussType(); + void resetElectricalBussType(); bool setInverter(const Inverter& inverter); void resetInverter(); - //bool setElectricalStorage(const ElectricalStorage& electricalStorage); + bool setElectricalStorage(const ElectricalStorage& electricalStorage); - //void resetElectricalStorage(); + void resetElectricalStorage(); //bool setTransformer(const Transformer& transformer); //void resetTransformer(); + // Storage Operation Scheme + bool setStorageOperationScheme(const std::string& operationScheme); + void resetStorageOperationScheme(); + + // Storage Control Track Meter Name, required if operation = TrackMeterDemandStoreExcessOnSite + bool setStorageControlTrackMeterName(const std::string& meterName); + void resetStorageControlTrackMeterName(); + + // Storage Converter Object Name + //bool setStorageConverter(const ElectricLoadCenterStorageConverter& converter); + //void resetStorageConverter(); + + // Maximum Storage State of Charge Fraction, required if storage, defaults + bool setMaximumStorageStateofChargeFraction(const double maxStateofCharge); + void resetMaximumStorageStateofChargeFraction(); + + // Minimum Storage State of Charge Fraction, required if storage, defaults + bool setMinimumStorageStateofChargeFraction(const double minStateofCharge); + void resetMinimumStorageStateofChargeFraction(); + + // Design Storage Control Charge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules + bool setDesignStorageControlChargePower(const double designStorageControlChargePower); + void resetDesignStorageControlChargePower(); + + // Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules + // TODO: do I want to default that to daytime? + bool setStorageChargePowerFractionSchedule(Schedule& schedule); + void resetStorageChargePowerFractionSchedule(); + + // Design Storage Control Discharge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules + bool setDesignStorageControlDischargePower(const double designStorageControlDischargePower); + void resetDesignStorageControlDischargePower(); + + // Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules + // TODO: do I want to default that to daytime? + bool setStorageDischargePowerFractionSchedule(Schedule& schedule); + void resetStorageDischargePowerFractionSchedule(); + + // Storage Control Utility Demand Target, required if FacilityDemandLeveling + bool setStorageControlUtilityDemandTarget(const double storageControlUtilityDemandTarget); + void resetStorageControlUtilityDemandTarget(); + + // Storage Control Utility Demand Target Fraction Schedule Name, will be used only if FacilityDemandLeveling, defaults to 1.0 + bool setStorageControlUtilityDemandTargetFractionSchedule(Schedule& schedule); + void resetStorageControlUtilityDemandTargetFractionSchedule(); + //@} /** @name Other */ //@{ + bool validityCheck() const; + //@} protected: diff --git a/openstudiocore/src/model/ElectricLoadCenterDistribution_Impl.hpp b/openstudiocore/src/model/ElectricLoadCenterDistribution_Impl.hpp index 0025209ab18..160ab3505b6 100644 --- a/openstudiocore/src/model/ElectricLoadCenterDistribution_Impl.hpp +++ b/openstudiocore/src/model/ElectricLoadCenterDistribution_Impl.hpp @@ -29,8 +29,9 @@ namespace model { class Schedule; class Generator; class Inverter; -//class ElectricalStorage; +class ElectricalStorage; //class Transformer; +//class ElectricLoadCenterStorageConverter; class ModelObjectList; namespace detail { @@ -78,6 +79,7 @@ namespace detail { /// returns all generators, inverters, transformers, and electrical storage virtual ModelObject clone(Model model) const override; + //@} /** @name Getters */ //@{ @@ -88,11 +90,11 @@ namespace detail { bool isGeneratorOperationSchemeTypeDefaulted() const; - //boost::optional demandLimitSchemePurchasedElectricDemandLimit() const; + boost::optional demandLimitSchemePurchasedElectricDemandLimit() const; - //boost::optional trackScheduleSchemeSchedule() const; + boost::optional trackScheduleSchemeSchedule() const; - //boost::optional trackMeterSchemeMeterName() const; + boost::optional trackMeterSchemeMeterName() const; std::string electricalBussType() const; @@ -100,10 +102,54 @@ namespace detail { boost::optional inverter() const; - //boost::optional electricalStorage() const; + boost::optional electricalStorage() const; //boost::optional transformer() const; + // New + + // Storage Operation Scheme, defaults to TrackFacilityElectricDemandStoreExcessOnSite + std::string storageOperationScheme() const; + bool isStorageOperationSchemeDefaulted() const; + + // Storage Control Track Meter Name, required if operation = TrackMeterDemandStoreExcessOnSite + boost::optional storageControlTrackMeterName() const; + + // Storage Converter Object Name + //boost::optional storageConverter() const; + // TODO: Implement this object. + + // Maximum Storage State of Charge Fraction, required if storage, defaults + double maximumStorageStateofChargeFraction() const; + bool isMaximumStorageStateofChargeFractionDefaulted() const; + + // Minimum Storage State of Charge Fraction, required if storage, defaults + double minimumStorageStateofChargeFraction() const; + bool isMinimumStorageStateofChargeFractionDefaulted() const; + + // Design Storage Control Charge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules + boost::optional designStorageControlChargePower() const; + + // Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules + // TODO: do I want to default that to daytime? + boost::optional storageChargePowerFractionSchedule() const; + + // Design Storage Control Discharge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules + boost::optional designStorageControlDischargePower() const; + + // Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules + // TODO: do I want to default that to daytime? + boost::optional storageDischargePowerFractionSchedule() const; + + + // Storage Control Utility Demand Target, required if FacilityDemandLeveling + boost::optional storageControlUtilityDemandTarget() const; + + + // Storage Control Utility Demand Target Fraction Schedule Name, will be used only if FacilityDemandLeveling, defaults to 1.0 + Schedule storageControlUtilityDemandTargetFractionSchedule() const; + bool isStorageControlUtilityDemandTargetFractionScheduleDefaulted() const; + //@} /** @name Setters */ //@{ @@ -118,17 +164,17 @@ namespace detail { void resetGeneratorOperationSchemeType(); - //void setDemandLimitSchemePurchasedElectricDemandLimit(double demandLimitSchemePurchasedElectricDemandLimit); + bool setDemandLimitSchemePurchasedElectricDemandLimit(double demandLimitSchemePurchasedElectricDemandLimit); - //void resetDemandLimitSchemePurchasedElectricDemandLimit(); + void resetDemandLimitSchemePurchasedElectricDemandLimit(); - //bool setTrackScheduleSchemeSchedule(Schedule& schedule); + bool setTrackScheduleSchemeSchedule(Schedule& schedule); - //void resetTrackScheduleSchemeSchedule(); + void resetTrackScheduleSchemeSchedule(); - //bool setTrackMeterSchemeMeterName(const std::string& trackMeterSchemeMeterName); + bool setTrackMeterSchemeMeterName(const std::string& trackMeterSchemeMeterName); - //void resetTrackMeterSchemeMeterName(); + void resetTrackMeterSchemeMeterName(); bool setElectricalBussType(const std::string& electricalBussType); @@ -138,18 +184,67 @@ namespace detail { void resetInverter(); - //bool setElectricalStorage(const ElectricalStorage& electricalStorage); + bool setElectricalStorage(const ElectricalStorage& electricalStorage); - //void resetElectricalStorage(); + void resetElectricalStorage(); //bool setTransformer(const Transformer& transformer); //void resetTransformerObject(); + // Storage Operation Scheme + bool setStorageOperationScheme(const std::string& operationScheme); + void resetStorageOperationScheme(); + + // Storage Control Track Meter Name, required if operation = TrackMeterDemandStoreExcessOnSite + bool setStorageControlTrackMeterName(const std::string& meterName); + void resetStorageControlTrackMeterName(); + + // Storage Converter Object Name + ///bool setStorageConverter(const ElectricLoadCenterStorageConverter& converter); + //void resetStorageConverter(); + + // Maximum Storage State of Charge Fraction, required if storage, defaults + bool setMaximumStorageStateofChargeFraction(const double maxStateofCharge); + void resetMaximumStorageStateofChargeFraction(); + + // Minimum Storage State of Charge Fraction, required if storage, defaults + bool setMinimumStorageStateofChargeFraction(const double minStateofCharge); + void resetMinimumStorageStateofChargeFraction(); + + // Design Storage Control Charge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules + bool setDesignStorageControlChargePower(const double designStorageControlChargePower); + void resetDesignStorageControlChargePower(); + + // Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules + // TODO: do I want to default that to daytime? + bool setStorageChargePowerFractionSchedule(Schedule& schedule); + void resetStorageChargePowerFractionSchedule(); + + // Design Storage Control Discharge Power, required if FacilityDemandLeveling or TrackChargeDischargeSchedules + bool setDesignStorageControlDischargePower(const double designStorageControlDischargePower); + void resetDesignStorageControlDischargePower(); + + // Storage Charge Power Fraction Schedule Name, required if TrackChargeDischargeSchedules + // TODO: do I want to default that to daytime? + bool setStorageDischargePowerFractionSchedule(Schedule& schedule); + void resetStorageDischargePowerFractionSchedule(); + + // Storage Control Utility Demand Target, required if FacilityDemandLeveling + bool setStorageControlUtilityDemandTarget(const double storageControlUtilityDemandTarget); + void resetStorageControlUtilityDemandTarget(); + + // Storage Control Utility Demand Target Fraction Schedule Name, will be used only if FacilityDemandLeveling, defaults to 1.0 + bool setStorageControlUtilityDemandTargetFractionSchedule(Schedule& schedule); + void resetStorageControlUtilityDemandTargetFractionSchedule(); + + //@} /** @name Other */ //@{ + bool validityCheck() const; + //@} protected: private: diff --git a/openstudiocore/src/model/ElectricLoadCenterStorageSimple.cpp b/openstudiocore/src/model/ElectricLoadCenterStorageSimple.cpp new file mode 100644 index 00000000000..47a45e68846 --- /dev/null +++ b/openstudiocore/src/model/ElectricLoadCenterStorageSimple.cpp @@ -0,0 +1,478 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include "ElectricLoadCenterStorageSimple.hpp" +#include "ElectricLoadCenterStorageSimple_Impl.hpp" + +#include "Schedule.hpp" +#include "Schedule_Impl.hpp" +#include "ThermalZone.hpp" +#include "ThermalZone_Impl.hpp" +#include "Model.hpp" +#include "Model_Impl.hpp" + +#include "ScheduleTypeLimits.hpp" +#include "ScheduleTypeRegistry.hpp" + +#include +#include + +#include "../utilities/units/Unit.hpp" +#include "../utilities/core/Assert.hpp" + +namespace openstudio { +namespace model { + +namespace detail { + + ElectricLoadCenterStorageSimple_Impl::ElectricLoadCenterStorageSimple_Impl(const IdfObject& idfObject, + Model_Impl* model, + bool keepHandle) + : ElectricalStorage_Impl(idfObject,model,keepHandle) + { + OS_ASSERT(idfObject.iddObject().type() == ElectricLoadCenterStorageSimple::iddObjectType()); + } + + ElectricLoadCenterStorageSimple_Impl::ElectricLoadCenterStorageSimple_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, + bool keepHandle) + : ElectricalStorage_Impl(other,model,keepHandle) + { + OS_ASSERT(other.iddObject().type() == ElectricLoadCenterStorageSimple::iddObjectType()); + } + + ElectricLoadCenterStorageSimple_Impl::ElectricLoadCenterStorageSimple_Impl(const ElectricLoadCenterStorageSimple_Impl& other, + Model_Impl* model, + bool keepHandle) + : ElectricalStorage_Impl(other,model,keepHandle) + {} + + const std::vector& ElectricLoadCenterStorageSimple_Impl::outputVariableNames() const + { + static std::vector result; + if (result.empty()){ + result.push_back("Electric Storage Simple Charge State"); + result.push_back("Electric Storage Charge Power"); + result.push_back("Electric Storage Charge Energy"); + result.push_back("Electric Storage Production Decrement Energy"); + result.push_back("Electric Storage Discharge Power"); + result.push_back("Electric Storage Discharge Energy"); + result.push_back("Electric Storage Thermal Loss Rate"); + result.push_back("Electric Storage Thermal Loss Energy"); + } + return result; + } + + IddObjectType ElectricLoadCenterStorageSimple_Impl::iddObjectType() const { + return ElectricLoadCenterStorageSimple::iddObjectType(); + } + + std::vector ElectricLoadCenterStorageSimple_Impl::getScheduleTypeKeys(const Schedule& schedule) const + { + std::vector result; + UnsignedVector fieldIndices = getSourceIndices(schedule.handle()); + UnsignedVector::const_iterator b(fieldIndices.begin()), e(fieldIndices.end()); + if (std::find(b,e,OS_ElectricLoadCenter_Storage_SimpleFields::AvailabilityScheduleName) != e) + { + result.push_back(ScheduleTypeKey("ElectricLoadCenterStorageSimple","Availability")); + } + return result; + } + + //@} + /** @name Getters */ + //@{ + + // Included in parent class + // boost::optional ElectricLoadCenterStorageSimple_Impl::electricLoadCenterDistribution() const + // { + // boost::optional result; + // for (auto list : getObject().getModelObjectSources(ModelObjectList::iddObjectType())){ + // auto elcds = list.getModelObjectSources(ElectricLoadCenterDistribution::iddObjectType()); + // if (elcds.empty()){ + // error + // } else if (elcds.size() == 1u){ + // return elcds[0]; + // }else{ + // error + // } + // } + // return boost::none; + // } + + + //boost::optional ElectricLoadCenterStorageSimple_Impl::electricLoadCenterDistribution const { + + // boost::optional value; + // for ( const ElectricLoadCenterDistribution& elcd : this->model().getConcreteModelObjects() ) + // { + // if ( boost::optional elecStor = mchp.electricalStorage() ) + // { + // if (elecStor->handle() == this->handle()) + // { + // value = elcd; + // } + // } + // } + // return value; + + //} + + boost::optional ElectricLoadCenterStorageSimple_Impl::optionalAvailabilitySchedule() const { + return getObject().getModelObjectTarget(OS_ElectricLoadCenter_Storage_SimpleFields::AvailabilityScheduleName); + } + + Schedule ElectricLoadCenterStorageSimple_Impl::availabilitySchedule() const { + boost::optional value = optionalAvailabilitySchedule(); + if (!value) { + //LOG_AND_THROW(briefDescription() << " does not have an Availability Schedule attached."); + // I'm choosing to just return alwaysOnDiscreteSchedule + return this->model().alwaysOnDiscreteSchedule(); + } + return value.get(); + } + + bool ElectricLoadCenterStorageSimple_Impl::isAvailabilityScheduleDefaulted() const { + return isEmpty(OS_ElectricLoadCenter_Storage_SimpleFields::AvailabilityScheduleName); + } + + // Optional thermal Zone for heat gains + boost::optional ElectricLoadCenterStorageSimple_Impl::thermalZone() const { + return getObject().getModelObjectTarget(OS_ElectricLoadCenter_Storage_SimpleFields::ZoneName); + } + + // Radiative fraction for zone heat gains, defaults to 0, and not used if thermalZone above isn't used + double ElectricLoadCenterStorageSimple_Impl::radiativeFractionforZoneHeatGains() const { + boost::optional value = getDouble(OS_ElectricLoadCenter_Storage_SimpleFields::RadiativeFractionforZoneHeatGains,true); + OS_ASSERT(value); + return value.get(); + } + + bool ElectricLoadCenterStorageSimple_Impl::isRadiativeFractionforZoneHeatGainsDefaulted() const { + return isEmpty(OS_ElectricLoadCenter_Storage_SimpleFields::RadiativeFractionforZoneHeatGains); + } + + // Nominal Efficiency for Charging for zone heat gains, has a default in IDD + double ElectricLoadCenterStorageSimple_Impl::nominalEnergeticEfficiencyforCharging() const { + boost::optional value = getDouble(OS_ElectricLoadCenter_Storage_SimpleFields::NominalEnergeticEfficiencyforCharging,true); + OS_ASSERT(value); + return value.get(); + } + + bool ElectricLoadCenterStorageSimple_Impl::isNominalEnergeticEfficiencyforChargingDefaulted() const { + return isEmpty(OS_ElectricLoadCenter_Storage_SimpleFields::NominalEnergeticEfficiencyforCharging); + } + + // Nominal Efficiency for Discharging for zone heat gains, has a default in IDD + double ElectricLoadCenterStorageSimple_Impl::nominalDischargingEnergeticEfficiency() const { + boost::optional value = getDouble(OS_ElectricLoadCenter_Storage_SimpleFields::NominalDischargingEnergeticEfficiency,true); + OS_ASSERT(value); + return value.get(); + } + + bool ElectricLoadCenterStorageSimple_Impl::isNominalDischargingEnergeticEfficiencyDefaulted() const { + return isEmpty(OS_ElectricLoadCenter_Storage_SimpleFields::NominalDischargingEnergeticEfficiency); + } + + // Maximum Storage Capacity, required, no default + double ElectricLoadCenterStorageSimple_Impl::maximumStorageCapacity() const { + boost::optional value = getDouble(OS_ElectricLoadCenter_Storage_SimpleFields::MaximumStorageCapacity,true); + OS_ASSERT(value); + return value.get(); + } + + // Maximum Rate of Discharge, required, no default + double ElectricLoadCenterStorageSimple_Impl::maximumPowerforDischarging() const { + boost::optional value = getDouble(OS_ElectricLoadCenter_Storage_SimpleFields::MaximumPowerforDischarging,true); + OS_ASSERT(value); + return value.get(); + } + + // Maximum Rate of Charge, required, no default + double ElectricLoadCenterStorageSimple_Impl::maximumPowerforCharging() const { + boost::optional value = getDouble(OS_ElectricLoadCenter_Storage_SimpleFields::MaximumPowerforCharging,true); + OS_ASSERT(value); + return value.get(); + } + + // Initial state of charge, if empty it will default to half of the maximum capacity + double ElectricLoadCenterStorageSimple_Impl::initialStateofCharge() const { + boost::optional optIniStateCharge = getDouble(OS_ElectricLoadCenter_Storage_SimpleFields::InitialStateofCharge,true); + // if it's set + if (optIniStateCharge) { + // Get it and return + return optIniStateCharge.get(); + } else { + // We Default it to half the maximum capacity + double maxCap = maximumStorageCapacity(); + return maxCap / 2.0; + } + } + + bool ElectricLoadCenterStorageSimple_Impl::isInitialStateofChargeDefaulted() const { + return isEmpty(OS_ElectricLoadCenter_Storage_SimpleFields::InitialStateofCharge); + } + + //@} + /** @name Setters */ + //@{ + + bool ElectricLoadCenterStorageSimple_Impl::setAvailabilitySchedule(Schedule& schedule) { + bool result = setSchedule(OS_ElectricLoadCenter_Storage_SimpleFields::AvailabilityScheduleName, + "ElectricLoadCenterStorageSimple", + "Availability", + schedule); + return result; + } + + void ElectricLoadCenterStorageSimple_Impl::resetAvailabilitySchedule() { + bool result = setString(OS_ElectricLoadCenter_Storage_SimpleFields::AvailabilityScheduleName, ""); + OS_ASSERT(result); + } + + // Set the thermal Zone for heat gains + bool ElectricLoadCenterStorageSimple_Impl::setThermalZone(const ThermalZone& thermalZone) { + bool result = setPointer(OS_ElectricLoadCenter_Storage_SimpleFields::ZoneName, thermalZone.handle()); + return result; + } + + // Reset the zone (leave blank) + void ElectricLoadCenterStorageSimple_Impl::resetThermalZone() { + bool result = setString(OS_ElectricLoadCenter_Storage_SimpleFields::ZoneName, ""); + OS_ASSERT(result); + } + + + bool ElectricLoadCenterStorageSimple_Impl::setRadiativeFractionforZoneHeatGains(double radiativeFractionforZoneHeatGains) { + bool result = setDouble(OS_ElectricLoadCenter_Storage_SimpleFields::RadiativeFractionforZoneHeatGains, radiativeFractionforZoneHeatGains); + return result; + } + + void ElectricLoadCenterStorageSimple_Impl::resetRadiativeFractionforZoneHeatGains() { + bool result = setString(OS_ElectricLoadCenter_Storage_SimpleFields::RadiativeFractionforZoneHeatGains, ""); + OS_ASSERT(result); + } + + bool ElectricLoadCenterStorageSimple_Impl::setNominalEnergeticEfficiencyforCharging(double nominalEnergeticEfficiencyforCharging) { + bool result = setDouble(OS_ElectricLoadCenter_Storage_SimpleFields::NominalEnergeticEfficiencyforCharging, nominalEnergeticEfficiencyforCharging); + return result; + } + + void ElectricLoadCenterStorageSimple_Impl::resetNominalEnergeticEfficiencyforCharging() { + bool result = setString(OS_ElectricLoadCenter_Storage_SimpleFields::NominalEnergeticEfficiencyforCharging, ""); + OS_ASSERT(result); + } + + bool ElectricLoadCenterStorageSimple_Impl::setNominalDischargingEnergeticEfficiency(double nominalDischargingEnergeticEfficiency) { + bool result = setDouble(OS_ElectricLoadCenter_Storage_SimpleFields::NominalDischargingEnergeticEfficiency, nominalDischargingEnergeticEfficiency); + return result; + } + + void ElectricLoadCenterStorageSimple_Impl::resetNominalDischargingEnergeticEfficiency() { + bool result = setString(OS_ElectricLoadCenter_Storage_SimpleFields::NominalDischargingEnergeticEfficiency, ""); + OS_ASSERT(result); + } + + bool ElectricLoadCenterStorageSimple_Impl::setMaximumStorageCapacity(double maximumStorageCapacity) { + bool result = setDouble(OS_ElectricLoadCenter_Storage_SimpleFields::MaximumStorageCapacity, maximumStorageCapacity); + return result; + } + + bool ElectricLoadCenterStorageSimple_Impl::setMaximumPowerforDischarging(double maximumPowerforDischarging) { + bool result = setDouble(OS_ElectricLoadCenter_Storage_SimpleFields::MaximumPowerforDischarging, maximumPowerforDischarging); + return result; + } + + bool ElectricLoadCenterStorageSimple_Impl::setMaximumPowerforCharging(double maximumPowerforCharging) { + bool result = setDouble(OS_ElectricLoadCenter_Storage_SimpleFields::MaximumPowerforCharging, maximumPowerforCharging); + return result; + } + + bool ElectricLoadCenterStorageSimple_Impl::setInitialStateofCharge(double value) { + bool result = setDouble(OS_ElectricLoadCenter_Storage_SimpleFields::InitialStateofCharge, value); + return result; + } + + void ElectricLoadCenterStorageSimple_Impl::resetInitialStateofCharge() { + bool result = setString(OS_ElectricLoadCenter_Storage_SimpleFields::InitialStateofCharge, ""); + OS_ASSERT(result); + } + +} // detail + +/* Constructor. Defaults the availabilitySchedule to alwaysOnDiscreteSchedule, + * Defaults efficiencies for charge and discharge to 0.8 + * maximum storage capacity to 1.0E13 + * Maximum Power for Charge/Discharge to 1.0E6 + * Reference: EnergyPlus example files (v8.5, LrgOff_GridStorageDemandLeveling */ +ElectricLoadCenterStorageSimple::ElectricLoadCenterStorageSimple(const Model& model) + : ElectricalStorage(ElectricLoadCenterStorageSimple::iddObjectType(),model) +{ + OS_ASSERT(getImpl()); + + // already defaults to alwaysOn + //Schedule schedule = model.alwaysOnDiscreteSchedule(); + //setAvailabilitySchedule(schedule); + + setNominalEnergeticEfficiencyforCharging(0.8); + setNominalDischargingEnergeticEfficiency(0.8); + setMaximumStorageCapacity(1.0E13); + setMaximumPowerforDischarging(1.0E6); + setMaximumPowerforCharging(1.0E6); + +} + +IddObjectType ElectricLoadCenterStorageSimple::iddObjectType() { + return IddObjectType(IddObjectType::OS_ElectricLoadCenter_Storage_Simple); +} + +// Convenience method to return the electricalLoadCenter on which it's assigned (optional) +// Included in parent +// boost::optional ElectricLoadCenterStorageSimple::electricLoadCenterDistribution() const +// { + // return getImpl()->electricLoadCenterDistribution(); +// } + +Schedule ElectricLoadCenterStorageSimple::availabilitySchedule() const { + return getImpl()->availabilitySchedule(); +} + +bool ElectricLoadCenterStorageSimple::isAvailabilityScheduleDefaulted() const { + return getImpl()->isAvailabilityScheduleDefaulted(); +} + +// TODO: Included in parent shouldn't need that + //boost::optional ElectricLoadCenterStorageSimple::thermalZone() const { + // return getImpl()->thermalZone(); + //} + +double ElectricLoadCenterStorageSimple::radiativeFractionforZoneHeatGains() const { + return getImpl()->radiativeFractionforZoneHeatGains(); +} + +bool ElectricLoadCenterStorageSimple::isRadiativeFractionforZoneHeatGainsDefaulted() const { + return getImpl()->isRadiativeFractionforZoneHeatGainsDefaulted(); +} + +double ElectricLoadCenterStorageSimple::nominalEnergeticEfficiencyforCharging() const { + return getImpl()->nominalEnergeticEfficiencyforCharging(); +} + +bool ElectricLoadCenterStorageSimple::isNominalEnergeticEfficiencyforChargingDefaulted() const { + return getImpl()->isNominalEnergeticEfficiencyforChargingDefaulted(); +} + +double ElectricLoadCenterStorageSimple::nominalDischargingEnergeticEfficiency() const { + return getImpl()->nominalDischargingEnergeticEfficiency(); +} + +bool ElectricLoadCenterStorageSimple::isNominalDischargingEnergeticEfficiencyDefaulted() const { + return getImpl()->isNominalDischargingEnergeticEfficiencyDefaulted(); +} + +double ElectricLoadCenterStorageSimple::maximumStorageCapacity() const { + return getImpl()->maximumStorageCapacity(); +} + +double ElectricLoadCenterStorageSimple::maximumPowerforDischarging() const { + return getImpl()->maximumPowerforDischarging(); +} + +double ElectricLoadCenterStorageSimple::maximumPowerforCharging() const { + return getImpl()->maximumPowerforCharging(); +} + +double ElectricLoadCenterStorageSimple::initialStateofCharge() const { + return getImpl()->initialStateofCharge(); +} + +bool ElectricLoadCenterStorageSimple::isInitialStateofChargeDefaulted() const { + return getImpl()->isInitialStateofChargeDefaulted(); +} + +// Setters +bool ElectricLoadCenterStorageSimple::setAvailabilitySchedule(Schedule& schedule) { + return getImpl()->setAvailabilitySchedule(schedule); +} + +void ElectricLoadCenterStorageSimple::resetAvailabilitySchedule() { + getImpl()->resetAvailabilitySchedule(); +} + +// TODO: Included in parent shouldn't need that + //bool ElectricLoadCenterStorageSimple::setThermalZone(ThermalZone& zone) { + // return getImpl()->setThermalZone(zone); + //} + //void ElectricLoadCenterStorageSimple::resetThermalZone() { + // getImpl()->resetThermalZone(); + //} + +bool ElectricLoadCenterStorageSimple::setRadiativeFractionforZoneHeatGains(double radiativeFractionforZoneHeatGains) { + return getImpl()->setRadiativeFractionforZoneHeatGains(radiativeFractionforZoneHeatGains); +} + +void ElectricLoadCenterStorageSimple::resetRadiativeFractionforZoneHeatGains() { + getImpl()->resetRadiativeFractionforZoneHeatGains(); +} + +bool ElectricLoadCenterStorageSimple::setNominalEnergeticEfficiencyforCharging(double nominalEnergeticEfficiencyforCharging) { + return getImpl()->setNominalEnergeticEfficiencyforCharging(nominalEnergeticEfficiencyforCharging); +} + +void ElectricLoadCenterStorageSimple::resetNominalEnergeticEfficiencyforCharging() { + getImpl()->resetNominalEnergeticEfficiencyforCharging(); +} + +bool ElectricLoadCenterStorageSimple::setNominalDischargingEnergeticEfficiency(double nominalDischargingEnergeticEfficiency) { + return getImpl()->setNominalDischargingEnergeticEfficiency(nominalDischargingEnergeticEfficiency); +} + +void ElectricLoadCenterStorageSimple::resetNominalDischargingEnergeticEfficiency() { + getImpl()->resetNominalDischargingEnergeticEfficiency(); +} + +bool ElectricLoadCenterStorageSimple::setMaximumStorageCapacity(double maximumStorageCapacity) { + return getImpl()->setMaximumStorageCapacity(maximumStorageCapacity); +} + +bool ElectricLoadCenterStorageSimple::setMaximumPowerforDischarging(double maximumPowerforDischarging) { + return getImpl()->setMaximumPowerforDischarging(maximumPowerforDischarging); +} + +bool ElectricLoadCenterStorageSimple::setMaximumPowerforCharging(double maximumPowerforCharging) { + return getImpl()->setMaximumPowerforCharging(maximumPowerforCharging); +} + +bool ElectricLoadCenterStorageSimple::setInitialStateofCharge(double initialStateofCharge) { + return getImpl()->setInitialStateofCharge(initialStateofCharge); +} + +void ElectricLoadCenterStorageSimple::resetInitialStateofCharge() { + getImpl()->resetInitialStateofCharge(); +} + +/// @cond +ElectricLoadCenterStorageSimple::ElectricLoadCenterStorageSimple(std::shared_ptr impl) + : ElectricalStorage(impl) +{} +/// @endcond + +} // model +} // openstudio + diff --git a/openstudiocore/src/model/ElectricLoadCenterStorageSimple.hpp b/openstudiocore/src/model/ElectricLoadCenterStorageSimple.hpp new file mode 100644 index 00000000000..643c36d74c6 --- /dev/null +++ b/openstudiocore/src/model/ElectricLoadCenterStorageSimple.hpp @@ -0,0 +1,145 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#ifndef MODEL_ELECTRICLOADCENTERSTORAGESIMPLE_HPP +#define MODEL_ELECTRICLOADCENTERSTORAGESIMPLE_HPP + +#include "ModelAPI.hpp" +#include "ElectricalStorage.hpp" + +namespace openstudio { + +namespace model { + +class Schedule; +class ThermalZone; + +namespace detail { + + class ElectricLoadCenterStorageSimple_Impl; + +} // detail + +/** ElectricLoadCenterStorageSimple is a ElectricalStorage that wraps the OpenStudio IDD object 'OS:ElectricLoadCenter:Storage:Simple'. */ +class MODEL_API ElectricLoadCenterStorageSimple : public ElectricalStorage { + public: + /** @name Constructors and Destructors */ + //@{ + + explicit ElectricLoadCenterStorageSimple(const Model& model); + + virtual ~ElectricLoadCenterStorageSimple() {} + + //@} + + static IddObjectType iddObjectType(); + + /** @name Getters */ + //@{ + + // Convenience method to return the electricalLoadCenter on which it's assigned (optional) + // In parent + // boost::optional electricLoadCenterDistribution() const; + + Schedule availabilitySchedule() const; + bool isAvailabilityScheduleDefaulted() const; + + // TODO: Included in parent class, shouldn't need to define it here... + //virtual boost::optional thermalZone() const override; + + double radiativeFractionforZoneHeatGains() const; + bool isRadiativeFractionforZoneHeatGainsDefaulted() const; + + double nominalEnergeticEfficiencyforCharging() const; + bool isNominalEnergeticEfficiencyforChargingDefaulted() const; + + double nominalDischargingEnergeticEfficiency() const; + bool isNominalDischargingEnergeticEfficiencyDefaulted() const; + + double maximumStorageCapacity() const; + + double maximumPowerforDischarging() const; + + double maximumPowerforCharging() const; + + double initialStateofCharge() const; + bool isInitialStateofChargeDefaulted() const; + + //@} + /** @name Setters */ + //@{ + + bool setAvailabilitySchedule(Schedule& schedule); + void resetAvailabilitySchedule(); + + // TODO: Included in parent class, shouldn't need to define it... + //virtual bool setThermalZone(ThermalZone& zone) override; + //virtual void resetThermalZone() override; + + bool setRadiativeFractionforZoneHeatGains(double radiativeFractionforZoneHeatGains); + void resetRadiativeFractionforZoneHeatGains(); + + bool setNominalEnergeticEfficiencyforCharging(double nominalEnergeticEfficiencyforCharging); + void resetNominalEnergeticEfficiencyforCharging(); + + // TODO: I've requested an .IDD change in EnergyPlus, to make this "Nominal Energetic Efficiency for Discharging" + // TODO: https://github.com/NREL/EnergyPlus/issues/5730 + bool setNominalDischargingEnergeticEfficiency(double nominalDischargingEnergeticEfficiency); + void resetNominalDischargingEnergeticEfficiency(); + + bool setMaximumStorageCapacity(double maximumStorageCapacity); + + bool setMaximumPowerforDischarging(double maximumPowerforDischarging); + + bool setMaximumPowerforCharging(double maximumPowerforCharging); + + bool setInitialStateofCharge(double initialStateofCharge); + void resetInitialStateofCharge(); + + //@} + /** @name Other */ + //@{ + + //@} + protected: + /// @cond + typedef detail::ElectricLoadCenterStorageSimple_Impl ImplType; + + explicit ElectricLoadCenterStorageSimple(std::shared_ptr impl); + + friend class detail::ElectricLoadCenterStorageSimple_Impl; + friend class Model; + friend class IdfObject; + friend class openstudio::detail::IdfObject_Impl; + /// @endcond + private: + REGISTER_LOGGER("openstudio.model.ElectricLoadCenterStorageSimple"); +}; + +/** \relates ElectricLoadCenterStorageSimple*/ +typedef boost::optional OptionalElectricLoadCenterStorageSimple; + +/** \relates ElectricLoadCenterStorageSimple*/ +typedef std::vector ElectricLoadCenterStorageSimpleVector; + +} // model +} // openstudio + +#endif // MODEL_ELECTRICLOADCENTERSTORAGESIMPLE_HPP + diff --git a/openstudiocore/src/model/ElectricLoadCenterStorageSimple_Impl.hpp b/openstudiocore/src/model/ElectricLoadCenterStorageSimple_Impl.hpp new file mode 100644 index 00000000000..9d1cb93c7af --- /dev/null +++ b/openstudiocore/src/model/ElectricLoadCenterStorageSimple_Impl.hpp @@ -0,0 +1,150 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#ifndef MODEL_ELECTRICLOADCENTERSTORAGESIMPLE_IMPL_HPP +#define MODEL_ELECTRICLOADCENTERSTORAGESIMPLE_IMPL_HPP + +#include "ModelAPI.hpp" +#include "ElectricalStorage_Impl.hpp" + +namespace openstudio { +namespace model { + +class Schedule; +class ThermalZone; + +namespace detail { + + /** ElectricLoadCenterStorageSimple_Impl is a ElectricalStorage_Impl that is the implementation class for ElectricLoadCenterStorageSimple.*/ + class MODEL_API ElectricLoadCenterStorageSimple_Impl : public ElectricalStorage_Impl { + public: + /** @name Constructors and Destructors */ + //@{ + + ElectricLoadCenterStorageSimple_Impl(const IdfObject& idfObject, + Model_Impl* model, + bool keepHandle); + + ElectricLoadCenterStorageSimple_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, + bool keepHandle); + + ElectricLoadCenterStorageSimple_Impl(const ElectricLoadCenterStorageSimple_Impl& other, + Model_Impl* model, + bool keepHandle); + + virtual ~ElectricLoadCenterStorageSimple_Impl() {} + + //@} + /** @name Virtual Methods */ + //@{ + + virtual const std::vector& outputVariableNames() const override; + + virtual IddObjectType iddObjectType() const override; + + virtual std::vector getScheduleTypeKeys(const Schedule& schedule) const override; + + //@} + /** @name Getters */ + //@{ + + // Convenience method to return the electricalLoadCenter on which it's assigned (optional) + // Included in Base Class + // boost::optional electricLoadCenterDistribution() const; + + Schedule availabilitySchedule() const; + bool isAvailabilityScheduleDefaulted() const; + + virtual boost::optional thermalZone() const override; + + double radiativeFractionforZoneHeatGains() const; + bool isRadiativeFractionforZoneHeatGainsDefaulted() const; + + double nominalEnergeticEfficiencyforCharging() const; + bool isNominalEnergeticEfficiencyforChargingDefaulted() const; + + // TODO: I've requested an .IDD change in EnergyPlus, to make this "Nominal Energetic Efficiency for Discharging" + // TODO: https://github.com/NREL/EnergyPlus/issues/5730 + double nominalDischargingEnergeticEfficiency() const; + bool isNominalDischargingEnergeticEfficiencyDefaulted() const; + + double maximumStorageCapacity() const; + + double maximumPowerforDischarging() const; + + double maximumPowerforCharging() const; + + double initialStateofCharge() const; + bool isInitialStateofChargeDefaulted() const; + + //@} + /** @name Setters */ + //@{ + + bool setAvailabilitySchedule(Schedule& schedule); + void resetAvailabilitySchedule(); + + // Override ElectricalStorage (Base class) methods + virtual bool setThermalZone(const ThermalZone& thermalZone) override; + virtual void resetThermalZone() override; + + bool setRadiativeFractionforZoneHeatGains(double radiativeFractionforZoneHeatGains); + void resetRadiativeFractionforZoneHeatGains(); + + bool setNominalEnergeticEfficiencyforCharging(double nominalEnergeticEfficiencyforCharging); + void resetNominalEnergeticEfficiencyforCharging(); + + bool setNominalDischargingEnergeticEfficiency(double nominalDischargingEnergeticEfficiency); + void resetNominalDischargingEnergeticEfficiency(); + + bool setMaximumStorageCapacity(double maximumStorageCapacity); + + bool setMaximumPowerforDischarging(double maximumPowerforDischarging); + + bool setMaximumPowerforCharging(double maximumPowerforCharging); + + bool setInitialStateofCharge(double initialStateofCharge); + void resetInitialStateofCharge(); + + //@} + /** @name Other */ + //@{ + + // TODO: Remove if not used. Don't think I need to override any of these + //ModelObject clone(Model model) const override; + + //std::vector remove() override; + + //std::vector children() const override; + + //@} + protected: + private: + REGISTER_LOGGER("openstudio.model.ElectricLoadCenterStorageSimple"); + boost::optional optionalAvailabilitySchedule() const; + }; + +} // detail + +} // model +} // openstudio + +#endif // MODEL_ELECTRICLOADCENTERSTORAGESIMPLE_IMPL_HPP + diff --git a/openstudiocore/src/model/ElectricalStorage.cpp b/openstudiocore/src/model/ElectricalStorage.cpp new file mode 100644 index 00000000000..d1e768b8c5a --- /dev/null +++ b/openstudiocore/src/model/ElectricalStorage.cpp @@ -0,0 +1,106 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include "ElectricalStorage.hpp" +#include "ElectricalStorage_Impl.hpp" + +#include "ParentObject.hpp" +#include "ParentObject_Impl.hpp" +#include "Model.hpp" +#include "Model_Impl.hpp" +#include "ElectricLoadCenterDistribution.hpp" +#include "ElectricLoadCenterDistribution_Impl.hpp" + +#include "../utilities/core/Assert.hpp" + +namespace openstudio { + +namespace model { + +namespace detail { + +ElectricalStorage_Impl::ElectricalStorage_Impl(IddObjectType type, Model_Impl* model) + : ParentObject_Impl(type,model) +{} + +ElectricalStorage_Impl::ElectricalStorage_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle) + : ParentObject_Impl(idfObject, model, keepHandle) +{} + +ElectricalStorage_Impl::ElectricalStorage_Impl( + const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, + bool keepHandle) + : ParentObject_Impl(other, model, keepHandle) +{} + +ElectricalStorage_Impl::ElectricalStorage_Impl(const ElectricalStorage_Impl& other, + Model_Impl* model, + bool keepHandles) + : ParentObject_Impl(other, model, keepHandles) +{} + +// Convenience method to find the ELCD linked to this storage device +boost::optional ElectricalStorage_Impl::electricLoadCenterDistribution() const +{ + boost::optional thiselcd; + for (const ElectricLoadCenterDistribution& elcd : this->model().getConcreteModelObjects()) { + if (boost::optional elcSto = elcd.electricalStorage()) { + if (elcSto->handle() == this->handle()) { + thiselcd = elcd; + } + } + } + OS_ASSERT(thiselcd); + return thiselcd.get(); +} + +} // detail + +ElectricalStorage::ElectricalStorage(IddObjectType type,const Model& model) + : ParentObject(type, model) +{ + OS_ASSERT(getImpl()); +} + +ElectricalStorage::ElectricalStorage(std::shared_ptr p) + : ParentObject(p) +{} + +boost::optional ElectricalStorage::electricLoadCenterDistribution() const +{ + return getImpl()->electricLoadCenterDistribution(); +} + +boost::optional ElectricalStorage::thermalZone() const { + return getImpl()->thermalZone(); +} + +bool ElectricalStorage::setThermalZone(const ThermalZone& thermalZone) { + return getImpl()->setThermalZone(thermalZone); +} + +void ElectricalStorage::resetThermalZone() { + getImpl()->resetThermalZone(); +} + +} // model + +} // openstudio + diff --git a/openstudiocore/src/model/ElectricalStorage.hpp b/openstudiocore/src/model/ElectricalStorage.hpp new file mode 100644 index 00000000000..665aac58ed8 --- /dev/null +++ b/openstudiocore/src/model/ElectricalStorage.hpp @@ -0,0 +1,82 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#ifndef MODEL_ELECTRICALSTORAGE_HPP +#define MODEL_ELECTRICALSTORAGE_HPP + +#include "ModelAPI.hpp" +#include "ParentObject.hpp" +#include "ThermalZone.hpp" + +namespace openstudio { +namespace model { + +class ElectricLoadCenterDistribution; + +namespace detail{ + class ElectricalStorage_Impl; +} + +/** ElectricStorage is a ParentObject. +It is the Base Class of both ElectricLoadCenterStorageSimple and ElectricLoadCenterStorageBattery*/ +class MODEL_API ElectricalStorage : public ParentObject { + + public: + + ElectricalStorage(IddObjectType type,const Model& model); + + virtual ~ElectricalStorage() {} + + boost::optional electricLoadCenterDistribution() const; + + virtual boost::optional thermalZone() const; + + virtual bool setThermalZone(const ThermalZone& thermalZone); + + virtual void resetThermalZone(); + + protected: + + friend class Model; + + friend class openstudio::IdfObject; + + /// @cond + + typedef detail::ElectricalStorage_Impl ImplType; + + explicit ElectricalStorage(std::shared_ptr impl); + + private: + + REGISTER_LOGGER("openstudio.model.ElectricalStorage"); + + /// @endcond + +}; + +typedef boost::optional OptionalElectricalStorage; + +typedef std::vector ElectricalStorageVector; + +} // model +} // openstudio + +#endif // MODEL_ELECTRICALSTORAGE_HPP + diff --git a/openstudiocore/src/model/ElectricalStorage_Impl.hpp b/openstudiocore/src/model/ElectricalStorage_Impl.hpp new file mode 100644 index 00000000000..a95a65b861d --- /dev/null +++ b/openstudiocore/src/model/ElectricalStorage_Impl.hpp @@ -0,0 +1,87 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#ifndef MODEL_ELECTRICALSTORAGE_IMPL_HPP +#define MODEL_ELECTRICALSTORAGE_IMPL_HPP + +#include "ParentObject_Impl.hpp" +#include "ThermalZone_Impl.hpp" + +namespace openstudio { +namespace model { + +namespace detail { + + /** ElectricStorage_Impl is a ParentObject_Impl that is the implementation class for ElectricStorage_Impl. + It is the Base Class of both ElectricLoadCenterStorageSimple and ElectricLoadCenterStorageBattery*/ + class MODEL_API ElectricalStorage_Impl : public ParentObject_Impl { + public: + /** @name Constructors and Destructors */ + //@{ + + ElectricalStorage_Impl(IddObjectType type, Model_Impl* model); + + ElectricalStorage_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle); + + ElectricalStorage_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, + bool keepHandle); + + ElectricalStorage_Impl(const ElectricalStorage_Impl& other, Model_Impl* model, bool keepHandles); + + virtual ~ElectricalStorage_Impl() {} + + //@} + /** @name Virtual Methods */ + //@{ + + + //@} + /** @name Getters */ + //@{ + + // Convenience method to return the (optional) electricalLoadCenter on which it's assigned + boost::optional electricLoadCenterDistribution() const; + + virtual boost::optional thermalZone() const = 0; + + //@} + /** @name Setters */ + //@{ + + virtual bool setThermalZone(const ThermalZone& thermalZone) = 0; + + virtual void resetThermalZone() = 0; + + //@} + /** @name Other */ + //@{ + + //@} + private: + + REGISTER_LOGGER("openstudio.model.ElectricalStorage"); + }; + +} // detail + +} // model +} // openstudio + +#endif // MODEL_ELECTRICALSTORAGE_IMPL_HPP diff --git a/openstudiocore/src/model/Facility.cpp b/openstudiocore/src/model/Facility.cpp index 2125469c34c..398be2bea6e 100644 --- a/openstudiocore/src/model/Facility.cpp +++ b/openstudiocore/src/model/Facility.cpp @@ -32,8 +32,8 @@ #include "ExteriorLights_Impl.hpp" #include "LifeCycleCostParameters.hpp" #include "LifeCycleCostParameters_Impl.hpp" -#include "Meter.hpp" -#include "Meter_Impl.hpp" +#include "OutputMeter.hpp" +#include "OutputMeter_Impl.hpp" #include "PlanarSurface.hpp" #include "PlanarSurface_Impl.hpp" #include "Site.hpp" @@ -94,7 +94,7 @@ namespace detail { { std::vector result; - MeterVector meters = this->meters(); + OutputMeterVector meters = this->meters(); result.insert(result.end(),meters.begin(),meters.end()); // building @@ -134,11 +134,11 @@ namespace detail { } /// get meter requests for the facility - std::vector Facility_Impl::meters() const + std::vector Facility_Impl::meters() const { - MeterVector result; - MeterVector meters = this->model().getConcreteModelObjects(); - for (const Meter& meter : meters){ + OutputMeterVector result; + OutputMeterVector meters = this->model().getConcreteModelObjects(); + for (const OutputMeter& meter : meters){ if (meter.installLocationType() && (InstallLocationType::Facility == meter.installLocationType().get().value())){ result.push_back(meter); } @@ -146,14 +146,14 @@ namespace detail { return result; } - boost::optional Facility_Impl::getMeterByFuelType( + boost::optional Facility_Impl::getMeterByFuelType( const FuelType& fuelType, const std::string& reportingFrequency, const boost::optional& endUseType, const boost::optional& specificEndUse) const { - OptionalMeter result; - for (const Meter& meter : this->meters()) { + OptionalOutputMeter result; + for (const OutputMeter& meter : this->meters()) { if (meter.fuelType() && (meter.fuelType() == fuelType)) { if (istringEqual(meter.reportingFrequency(),reportingFrequency)) { OptionalEndUseType meterEndUseType = meter.endUseType(); @@ -2126,12 +2126,12 @@ boost::optional Facility::building() const } /// get meter requests for the facility -std::vector Facility::meters() const +std::vector Facility::meters() const { return getImpl()->meters(); } -boost::optional Facility::getMeterByFuelType( +boost::optional Facility::getMeterByFuelType( const FuelType& fuelType, const std::string& reportingFrequency, const boost::optional& endUseType, diff --git a/openstudiocore/src/model/Facility.hpp b/openstudiocore/src/model/Facility.hpp index e60596accce..50a9c3bab4b 100644 --- a/openstudiocore/src/model/Facility.hpp +++ b/openstudiocore/src/model/Facility.hpp @@ -33,7 +33,7 @@ class EndUses; namespace model { class Building; -class Meter; +class OutputMeter; class ExteriorLights; namespace detail { @@ -47,7 +47,7 @@ namespace detail { * Facility is a unique object which parents the Building in the model. Conceptually, * the Facility object includes the Building as well as exterior equipment, * parking lot lighting, water systems for grounds, etc. The Facility object currently does not - * have any fields, it is simply used to access \link Meter Meters \endlink and high level results + * have any fields, it is simply used to access \link OutputMeter OutputMeters \endlink and high level results * which include exterior end uses. Facility does not have a public constructor because it is a unique ModelObject. * To get the Facility object for a Model or create one if it does not yet exist use model.getUniqueObject(). * To get the Facility object for a Model but not create one if it does not yet exist use model.getOptionalUniqueObject(). @@ -75,10 +75,10 @@ class MODEL_API Facility : public ParentObject { /// Returns the child Building. boost::optional building() const; - /// Returns all \link Meter Meters \endlink at the Facility level. - std::vector meters() const; + /// Returns all \link OutputMeter OutputMeters \endlink at the Facility level. + std::vector meters() const; - boost::optional getMeterByFuelType( + boost::optional getMeterByFuelType( const FuelType& fuelType, const std::string& reportingFrequency="Hourly", const boost::optional& endUseType=boost::none, diff --git a/openstudiocore/src/model/Facility_Impl.hpp b/openstudiocore/src/model/Facility_Impl.hpp index ccc65c275a9..5732580f18d 100644 --- a/openstudiocore/src/model/Facility_Impl.hpp +++ b/openstudiocore/src/model/Facility_Impl.hpp @@ -35,7 +35,7 @@ class Economics; namespace model { class Building; -class Meter; +class OutputMeter; class ExteriorLights; namespace detail { @@ -217,9 +217,9 @@ namespace detail { boost::optional building() const; // get meter requests for the facility - std::vector meters() const; + std::vector meters() const; - boost::optional getMeterByFuelType( + boost::optional getMeterByFuelType( const FuelType& fuelType, const std::string& reportingFrequency, const boost::optional& endUseType, diff --git a/openstudiocore/src/model/Generator.cpp b/openstudiocore/src/model/Generator.cpp index 52b329b1199..8c27167d5ae 100644 --- a/openstudiocore/src/model/Generator.cpp +++ b/openstudiocore/src/model/Generator.cpp @@ -114,9 +114,9 @@ boost::optional Generator::availabilitySchedule() const return getImpl()->availabilitySchedule(); } -boost::optional Generator::ratedThermalToElectricalPowerRatio() const +boost::optional Generator::ratedThermaltoElectricalPowerRatio() const { - return getImpl()->ratedThermalToElectricalPowerRatio(); + return getImpl()->ratedThermaltoElectricalPowerRatio(); } boost::optional Generator::electricLoadCenterDistribution() const diff --git a/openstudiocore/src/model/Generator.hpp b/openstudiocore/src/model/Generator.hpp index 8523425cf18..c3ad96d2a88 100644 --- a/openstudiocore/src/model/Generator.hpp +++ b/openstudiocore/src/model/Generator.hpp @@ -33,7 +33,7 @@ namespace detail{ } /** Generator is the base class for generators. The ratedElectricPowerOutput, availabilitySchedule, and - * ratedThermalToElectricalPowerRatio fields are mapped to fields in the ElectricLoadCenter:Generators object + * ratedThermaltoElectricalPowerRatio fields are mapped to fields in the ElectricLoadCenter:Generators object * in EnergyPlus. The ElectricLoadCenter:Generators object does not exist in OpenStudio. */ class MODEL_API Generator : public ParentObject { @@ -50,7 +50,7 @@ class MODEL_API Generator : public ParentObject { boost::optional availabilitySchedule() const; - boost::optional ratedThermalToElectricalPowerRatio() const; + boost::optional ratedThermaltoElectricalPowerRatio() const; boost::optional electricLoadCenterDistribution() const; diff --git a/openstudiocore/src/model/GeneratorMicroTurbine.cpp b/openstudiocore/src/model/GeneratorMicroTurbine.cpp new file mode 100644 index 00000000000..65337a19c59 --- /dev/null +++ b/openstudiocore/src/model/GeneratorMicroTurbine.cpp @@ -0,0 +1,1151 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include "GeneratorMicroTurbine.hpp" +#include "GeneratorMicroTurbine_Impl.hpp" +#include "GeneratorMicroTurbineHeatRecovery.hpp" +#include "GeneratorMicroTurbineHeatRecovery_Impl.hpp" + +// Need model to check if curve is part of model when setting +#include "Model.hpp" +#include "Model_Impl.hpp" + +#include "Curve.hpp" +#include "Curve_Impl.hpp" +#include "CurveBiquadratic.hpp" +#include "CurveBiquadratic_Impl.hpp" +#include "CurveCubic.hpp" +#include "CurveCubic_Impl.hpp" +#include "CurveQuadratic.hpp" +#include "CurveQuadratic_Impl.hpp" + +#include "StraightComponent.hpp" +#include "StraightComponent_Impl.hpp" +#include "GeneratorMicroTurbineHeatRecovery.hpp" +#include "GeneratorMicroTurbineHeatRecovery_Impl.hpp" + +#include "Schedule.hpp" +#include "Schedule_Impl.hpp" +#include "../../model/ScheduleTypeLimits.hpp" +#include "../../model/ScheduleTypeRegistry.hpp" + +// TODO: Add DataTables if added later to OS? +//#include "DataTables.hpp" // UniVariateTables and BiVariateTables +//#include "DataTables.hpp" + +#include +#include +#include +#include + +#include "../utilities/units/Unit.hpp" + +#include "../utilities/core/Assert.hpp" + +namespace openstudio { +namespace model { + +namespace detail { + + GeneratorMicroTurbine_Impl::GeneratorMicroTurbine_Impl(const IdfObject& idfObject, + Model_Impl* model, + bool keepHandle) + : Generator_Impl(idfObject,model,keepHandle) + { + OS_ASSERT(idfObject.iddObject().type() == GeneratorMicroTurbine::iddObjectType()); + } + + GeneratorMicroTurbine_Impl::GeneratorMicroTurbine_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, + bool keepHandle) + : Generator_Impl(other,model,keepHandle) + { + OS_ASSERT(other.iddObject().type() == GeneratorMicroTurbine::iddObjectType()); + } + + GeneratorMicroTurbine_Impl::GeneratorMicroTurbine_Impl(const GeneratorMicroTurbine_Impl& other, + Model_Impl* model, + bool keepHandle) + : Generator_Impl(other,model,keepHandle) + {} + + // Lists the output variables of a Generator:MicroTurbine, excepts the Heat Recovery specific ones + // (see GeneratorMicroTurbineHeatRecovery::outputVariableNames for these) + const std::vector& GeneratorMicroTurbine_Impl::outputVariableNames() const + { + static std::vector result; + if (result.empty()){ + result.push_back("Generator Produced Electric Power"); + result.push_back("Generator Produced Electric Energy"); + result.push_back("Generator LHV Basis Electric Efficiency"); + // + result.push_back("Generator Gas HHV Basis Rate"); + result.push_back("Generator Gas HHV Basis Energy"); + result.push_back("Generator Gas Mass Flow Rate"); + + result.push_back("Generator Propane HHV Basis Rate"); + result.push_back("Generator Propane HHV Basis Energy"); + result.push_back("Generator Propane Mass Flow Rate"); + // + result.push_back("Generator Fuel HHV Basis Rate"); + result.push_back("Generator Fuel HHV Basis Energy"); + + // These are part of Generator:MicroTurbine:HeatRecovery + // result.push_back("Generator Produced Thermal Rate"); + // result.push_back("Generator Produced Thermal Energy"); + // result.push_back("Generator Thermal Efficiency LHV Basis"); + // result.push_back("Generator Heat Recovery Inlet Temperature"); + // result.push_back("Generator Heat Recovery Outlet Temperature"); + // result.push_back("Generator Heat Recovery Water Mass Flow Rate"); + result.push_back("Generator Standby Electric Power"); + result.push_back("Generator Standby Electric Energy"); + result.push_back("Generator Ancillary Electric Power"); + result.push_back("Generator Ancillary Electric Energy"); + result.push_back("Generator Exhaust Air Mass Flow Rate"); + result.push_back("Generator Exhaust Air Temperature"); + } + return result; + } + + IddObjectType GeneratorMicroTurbine_Impl::iddObjectType() const { + return GeneratorMicroTurbine::iddObjectType(); + } + + std::string GeneratorMicroTurbine_Impl::generatorObjectType() const + { + // translated to ElectricLoadCenter:Generators 'Generator Object Type' + return "Generator:MicroTurbine"; + } + + // This will clone the GeneratorMicroTurbine as well as the GeneratorMicroTurbineHeatRecovery if there is one + // and will return a reference to the GeneratorMicroTurbine + ModelObject GeneratorMicroTurbine_Impl::clone(Model model) const + { + GeneratorMicroTurbine newCHP = ModelObject_Impl::clone(model).cast(); + + + + // If there's a GeneratorMicroTurbineHeatRecovery, clone it as well + if (boost::optional mchpHR = generatorMicroTurbineHeatRecovery()) + { + // Call the BaseClass (ModelObject) clone method to avoid circular references + GeneratorMicroTurbineHeatRecovery mchpHRClone = mchpHR->getImpl()->ModelObject_Impl::clone(model).cast(); + newCHP.getImpl()->setGeneratorMicroTurbineHeatRecovery(mchpHRClone); + + } + + return newCHP; + } + + // Return allowable child types: curves and Generator:MicroTurbine + std::vector GeneratorMicroTurbine_Impl::allowableChildTypes() const + { + std::vector result; + result.push_back(IddObjectType::OS_Generator_MicroTurbine_HeatRecovery); + result.push_back(IddObjectType::OS_Curve_Biquadratic); + result.push_back(IddObjectType::OS_Curve_Cubic); + result.push_back(IddObjectType::OS_Curve_Quadratic); + return result; + } + + // Returns the children object: max of 7 curves and a the GeneratorMicroTurbineHeatRecovery if it exists + std::vector GeneratorMicroTurbine_Impl::children() const + { + std::vector result; + boost::optional oCurve; + + if(boost::optional mo = generatorMicroTurbineHeatRecovery()) + { + result.push_back(mo.get()); + } + + // Should I include curves in there? Even now that then can be shared (resources) + Curve curve = electricalPowerFunctionofTemperatureandElevationCurve(); + result.push_back(curve); + + curve = electricalEfficiencyFunctionofTemperatureCurve(); + result.push_back(curve); + + curve = electricalEfficiencyFunctionofPartLoadRatioCurve(); + result.push_back(curve); + + if (oCurve = exhaustAirFlowRateFunctionofTemperatureCurve()) { + result.push_back(oCurve.get()); + } + if (oCurve = exhaustAirFlowRateFunctionofPartLoadRatioCurve()) { + result.push_back(oCurve.get()); + } + + if (oCurve = exhaustAirTemperatureFunctionofTemperatureCurve()) { + result.push_back(oCurve.get()); + } + if (oCurve = exhaustAirTemperatureFunctionofPartLoadRatioCurve()) { + result.push_back(oCurve.get()); + } + + + + return result; + } + + std::vector GeneratorMicroTurbine_Impl::getScheduleTypeKeys(const Schedule& schedule) const + { + // TODO: Check schedule display names. + std::vector result; + UnsignedVector fieldIndices = getSourceIndices(schedule.handle()); + UnsignedVector::const_iterator b(fieldIndices.begin()), e(fieldIndices.end()); + if (std::find(b,e,OS_Generator_MicroTurbineFields::AvailabilityScheduleName) != e) + { + result.push_back(ScheduleTypeKey("GeneratorMicroTurbine","Availability")); + } + return result; + } + + // translated to ElectricLoadCenter:Generators 'Generator Rated Electric Power Output' + boost::optional GeneratorMicroTurbine_Impl::ratedElectricPowerOutput() const + { + return referenceElectricalPowerOutput(); + } + + boost::optional GeneratorMicroTurbine_Impl::availabilitySchedule() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::AvailabilityScheduleName); + } + + // Convenience method to go fetch the connected GeneratorMicroTurbineHeatRecovery's 'Rated Thermal to Electrical Power Ratio' + boost::optional GeneratorMicroTurbine_Impl::ratedThermaltoElectricalPowerRatio() const + { + // translated to ElectricLoadCenter:Generators 'Generator Rated Thermal to Electrical Power Ratio' + //DLM: need to look into meaning of this field, is this heat recovery size divided by electrical power? + // TODO: Use the GeneratorMicroTurbineHeatRecovery method + boost::optional mchpHR = this->generatorMicroTurbineHeatRecovery(); + boost::optional value; + + if (mchpHR) { + value = mchpHR->ratedThermaltoElectricalPowerRatio(); + } + return value; + } + + double GeneratorMicroTurbine_Impl::referenceElectricalPowerOutput() const { + boost::optional value = getDouble(OS_Generator_MicroTurbineFields::ReferenceElectricalPowerOutput,true); + OS_ASSERT(value); + return value.get(); + } + + double GeneratorMicroTurbine_Impl::minimumFullLoadElectricalPowerOutput() const { + boost::optional value = getDouble(OS_Generator_MicroTurbineFields::MinimumFullLoadElectricalPowerOutput,true); + OS_ASSERT(value); + return value.get(); + } + + bool GeneratorMicroTurbine_Impl::isMinimumFullLoadElectricalPowerOutputDefaulted() const { + return isEmpty(OS_Generator_MicroTurbineFields::MinimumFullLoadElectricalPowerOutput); + } + + // If defaulted, return referenceElectricalPowerOutput + double GeneratorMicroTurbine_Impl::maximumFullLoadElectricalPowerOutput() const { + // TODO: Check if that's the typical way of doing this... Might has well write code that looks the same as usual. @danmacumber? + boost::optional maximumFullLoadElectricalPowerOutput = getDouble(OS_Generator_MicroTurbineFields::MaximumFullLoadElectricalPowerOutput,true); + // If there is a Heat Recovery Object + if (maximumFullLoadElectricalPowerOutput) { + // Get it and return + return maximumFullLoadElectricalPowerOutput.get(); + } + else { + boost::optional referenceElectricalPowerOutput = getDouble(OS_Generator_MicroTurbineFields::ReferenceElectricalPowerOutput,true); + OS_ASSERT(referenceElectricalPowerOutput); + return referenceElectricalPowerOutput.get(); + } + } + + bool GeneratorMicroTurbine_Impl::isMaximumFullLoadElectricalPowerOutputDefaulted() const { + return isEmpty(OS_Generator_MicroTurbineFields::MaximumFullLoadElectricalPowerOutput); + } + + + double GeneratorMicroTurbine_Impl::referenceElectricalEfficiencyUsingLowerHeatingValue() const { + boost::optional value = getDouble(OS_Generator_MicroTurbineFields::ReferenceElectricalEfficiencyUsingLowerHeatingValue,true); + OS_ASSERT(value); + return value.get(); + } + + double GeneratorMicroTurbine_Impl::referenceCombustionAirInletTemperature() const { + boost::optional value = getDouble(OS_Generator_MicroTurbineFields::ReferenceCombustionAirInletTemperature,true); + OS_ASSERT(value); + return value.get(); + } + + bool GeneratorMicroTurbine_Impl::isReferenceCombustionAirInletTemperatureDefaulted() const { + return isEmpty(OS_Generator_MicroTurbineFields::ReferenceCombustionAirInletTemperature); + } + + double GeneratorMicroTurbine_Impl::referenceCombustionAirInletHumidityRatio() const { + boost::optional value = getDouble(OS_Generator_MicroTurbineFields::ReferenceCombustionAirInletHumidityRatio,true); + OS_ASSERT(value); + return value.get(); + } + + bool GeneratorMicroTurbine_Impl::isReferenceCombustionAirInletHumidityRatioDefaulted() const { + return isEmpty(OS_Generator_MicroTurbineFields::ReferenceCombustionAirInletHumidityRatio); + } + + double GeneratorMicroTurbine_Impl::referenceElevation() const { + boost::optional value = getDouble(OS_Generator_MicroTurbineFields::ReferenceElevation,true); + OS_ASSERT(value); + return value.get(); + } + + bool GeneratorMicroTurbine_Impl::isReferenceElevationDefaulted() const { + return isEmpty(OS_Generator_MicroTurbineFields::ReferenceElevation); + } + + Curve GeneratorMicroTurbine_Impl::electricalPowerFunctionofTemperatureandElevationCurve() const { + boost::optional curve = getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::ElectricalPowerFunctionofTemperatureandElevationCurveName); + OS_ASSERT(curve); + return curve.get(); + } + + Curve GeneratorMicroTurbine_Impl::electricalEfficiencyFunctionofTemperatureCurve() const { + boost::optional curve = getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::ElectricalEfficiencyFunctionofTemperatureCurveName); + OS_ASSERT(curve); + return curve.get(); + } + + Curve GeneratorMicroTurbine_Impl::electricalEfficiencyFunctionofPartLoadRatioCurve() const { + boost::optional curve = getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::ElectricalEfficiencyFunctionofPartLoadRatioCurveName); + OS_ASSERT(curve); + return curve.get(); + } +/* Curve GeneratorMicroTurbine_Impl::electricalEfficiencyFunctionofPartLoadRatioCurve() const { + boost::optional value = optionalElectricalEfficiencyFunctionofPartLoadRatioCurve(); + if (!value) { + LOG_AND_THROW(briefDescription() << " does not have an Electrical Efficiency Function of Part Load Ratio Curve attached."); + } + return value.get(); + }*/ + + + std::string GeneratorMicroTurbine_Impl::fuelType() const { + boost::optional value = getString(OS_Generator_MicroTurbineFields::FuelType,true); + OS_ASSERT(value); + return value.get(); + } + + bool GeneratorMicroTurbine_Impl::isFuelTypeDefaulted() const { + return isEmpty(OS_Generator_MicroTurbineFields::FuelType); + } + + double GeneratorMicroTurbine_Impl::fuelHigherHeatingValue() const { + boost::optional value = getDouble(OS_Generator_MicroTurbineFields::FuelHigherHeatingValue,true); + OS_ASSERT(value); + return value.get(); + } + + bool GeneratorMicroTurbine_Impl::isFuelHigherHeatingValueDefaulted() const { + return isEmpty(OS_Generator_MicroTurbineFields::FuelHigherHeatingValue); + } + + double GeneratorMicroTurbine_Impl::fuelLowerHeatingValue() const { + boost::optional value = getDouble(OS_Generator_MicroTurbineFields::FuelLowerHeatingValue,true); + OS_ASSERT(value); + return value.get(); + } + + bool GeneratorMicroTurbine_Impl::isFuelLowerHeatingValueDefaulted() const { + return isEmpty(OS_Generator_MicroTurbineFields::FuelLowerHeatingValue); + } + + double GeneratorMicroTurbine_Impl::standbyPower() const { + boost::optional value = getDouble(OS_Generator_MicroTurbineFields::StandbyPower,true); + OS_ASSERT(value); + return value.get(); + } + + bool GeneratorMicroTurbine_Impl::isStandbyPowerDefaulted() const { + return isEmpty(OS_Generator_MicroTurbineFields::StandbyPower); + } + + double GeneratorMicroTurbine_Impl::ancillaryPower() const { + boost::optional value = getDouble(OS_Generator_MicroTurbineFields::AncillaryPower,true); + OS_ASSERT(value); + return value.get(); + } + + bool GeneratorMicroTurbine_Impl::isAncillaryPowerDefaulted() const { + return isEmpty(OS_Generator_MicroTurbineFields::AncillaryPower); + } + + boost::optional GeneratorMicroTurbine_Impl::ancillaryPowerFunctionofFuelInputCurve() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::AncillaryPowerFunctionofFuelInputCurveName); + } + + // Optional Generator:MicroTurbine:HeatRecovery + boost::optional GeneratorMicroTurbine_Impl::generatorMicroTurbineHeatRecovery() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::GeneratorMicroTurbineHeatRecoveryName); + } + + //boost::optional GeneratorMicroTurbine_Impl::combustionAirInletNode() const { + // return getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::CombustionAirInletNodeName); + //} + + //boost::optional GeneratorMicroTurbine_Impl::combustionAirOutletNode() const { + // return getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::CombustionAirOutletNodeName); + //} + + boost::optional GeneratorMicroTurbine_Impl::referenceExhaustAirMassFlowRate() const { + return getDouble(OS_Generator_MicroTurbineFields::ReferenceExhaustAirMassFlowRate,true); + } + + boost::optional GeneratorMicroTurbine_Impl::exhaustAirFlowRateFunctionofTemperatureCurve() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::ExhaustAirFlowRateFunctionofTemperatureCurveName); + } + + boost::optional GeneratorMicroTurbine_Impl::exhaustAirFlowRateFunctionofPartLoadRatioCurve() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::ExhaustAirFlowRateFunctionofPartLoadRatioCurveName); + } + + boost::optional GeneratorMicroTurbine_Impl::nominalExhaustAirOutletTemperature() const { + return getDouble(OS_Generator_MicroTurbineFields::NominalExhaustAirOutletTemperature,true); + } + + boost::optional GeneratorMicroTurbine_Impl::exhaustAirTemperatureFunctionofTemperatureCurve() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::ExhaustAirTemperatureFunctionofTemperatureCurveName); + } + + boost::optional GeneratorMicroTurbine_Impl::exhaustAirTemperatureFunctionofPartLoadRatioCurve() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::ExhaustAirTemperatureFunctionofPartLoadRatioCurveName); + } + + + bool GeneratorMicroTurbine_Impl::setAvailabilitySchedule(Schedule& schedule) { + bool result = setSchedule(OS_Generator_MicroTurbineFields::AvailabilityScheduleName, + "GeneratorMicroTurbine", + "Availability", + schedule); + return result; + } + + void GeneratorMicroTurbine_Impl::resetAvailabilitySchedule() { + bool result = setString(OS_Generator_MicroTurbineFields::AvailabilityScheduleName, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setReferenceElectricalPowerOutput(double referenceElectricalPowerOutput) { + bool result = setDouble(OS_Generator_MicroTurbineFields::ReferenceElectricalPowerOutput, referenceElectricalPowerOutput); + return result; + } + + bool GeneratorMicroTurbine_Impl::setMinimumFullLoadElectricalPowerOutput(double minimumFullLoadElectricalPowerOutput) { + bool result = setDouble(OS_Generator_MicroTurbineFields::MinimumFullLoadElectricalPowerOutput, minimumFullLoadElectricalPowerOutput); + return result; + } + + void GeneratorMicroTurbine_Impl::resetMinimumFullLoadElectricalPowerOutput() { + bool result = setString(OS_Generator_MicroTurbineFields::MinimumFullLoadElectricalPowerOutput, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setMaximumFullLoadElectricalPowerOutput(double maximumFullLoadElectricalPowerOutput) { + bool result = setDouble(OS_Generator_MicroTurbineFields::MaximumFullLoadElectricalPowerOutput, maximumFullLoadElectricalPowerOutput); + return result; + } + + void GeneratorMicroTurbine_Impl::resetMaximumFullLoadElectricalPowerOutput() { + bool result = setString(OS_Generator_MicroTurbineFields::MaximumFullLoadElectricalPowerOutput, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setReferenceElectricalEfficiencyUsingLowerHeatingValue(double referenceElectricalEfficiencyUsingLowerHeatingValue) { + bool result = setDouble(OS_Generator_MicroTurbineFields::ReferenceElectricalEfficiencyUsingLowerHeatingValue, referenceElectricalEfficiencyUsingLowerHeatingValue); + return result; + } + + void GeneratorMicroTurbine_Impl::setReferenceCombustionAirInletTemperature(double referenceCombustionAirInletTemperature) { + bool result = setDouble(OS_Generator_MicroTurbineFields::ReferenceCombustionAirInletTemperature, referenceCombustionAirInletTemperature); + OS_ASSERT(result); + } + + void GeneratorMicroTurbine_Impl::resetReferenceCombustionAirInletTemperature() { + bool result = setString(OS_Generator_MicroTurbineFields::ReferenceCombustionAirInletTemperature, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setReferenceCombustionAirInletHumidityRatio(double referenceCombustionAirInletHumidityRatio) { + bool result = setDouble(OS_Generator_MicroTurbineFields::ReferenceCombustionAirInletHumidityRatio, referenceCombustionAirInletHumidityRatio); + return result; + } + + void GeneratorMicroTurbine_Impl::resetReferenceCombustionAirInletHumidityRatio() { + bool result = setString(OS_Generator_MicroTurbineFields::ReferenceCombustionAirInletHumidityRatio, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setReferenceElevation(double referenceElevation) { + bool result = setDouble(OS_Generator_MicroTurbineFields::ReferenceElevation, referenceElevation); + return result; + } + + void GeneratorMicroTurbine_Impl::resetReferenceElevation() { + bool result = setString(OS_Generator_MicroTurbineFields::ReferenceElevation, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setElectricalPowerFunctionofTemperatureandElevationCurve(const Curve& curve) + { + if(model() != curve.model()) + { + LOG(Warn,briefDescription() << " does not belong to the same model as the curve you want to set."); + return false; + } + // Todo: do I need to explicitly check if the curve is of the right type? or does defining \object-list BiquadraticCurves in .idd suffice? + bool result = setPointer(OS_Generator_MicroTurbineFields::ElectricalPowerFunctionofTemperatureandElevationCurveName, curve.handle()); + return result; + } + + bool GeneratorMicroTurbine_Impl::setElectricalEfficiencyFunctionofTemperatureCurve(const Curve& curve) { + if(model() != curve.model()) + { + LOG(Warn,briefDescription() << " does not belong to the same model as the curve you want to set."); + return false; + } + bool result = setPointer(OS_Generator_MicroTurbineFields::ElectricalEfficiencyFunctionofTemperatureCurveName, curve.handle()); + return result; + } + + bool GeneratorMicroTurbine_Impl::setElectricalEfficiencyFunctionofPartLoadRatioCurve(const Curve& curve) { + if(model() != curve.model()) + { + LOG(Warn,briefDescription() << " does not belong to the same model as the curve you want to set."); + return false; + } + bool result = setPointer(OS_Generator_MicroTurbineFields::ElectricalEfficiencyFunctionofPartLoadRatioCurveName, curve.handle()); + return result; + } + + bool GeneratorMicroTurbine_Impl::setFuelType(const std::string& fuelType) { + bool result = setString(OS_Generator_MicroTurbineFields::FuelType, fuelType); + return result; + } + + void GeneratorMicroTurbine_Impl::resetFuelType() { + bool result = setString(OS_Generator_MicroTurbineFields::FuelType, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setFuelHigherHeatingValue(double fuelHigherHeatingValue) { + bool result = setDouble(OS_Generator_MicroTurbineFields::FuelHigherHeatingValue, fuelHigherHeatingValue); + return result; + } + + void GeneratorMicroTurbine_Impl::resetFuelHigherHeatingValue() { + bool result = setString(OS_Generator_MicroTurbineFields::FuelHigherHeatingValue, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setFuelLowerHeatingValue(double fuelLowerHeatingValue) { + bool result = setDouble(OS_Generator_MicroTurbineFields::FuelLowerHeatingValue, fuelLowerHeatingValue); + return result; + } + + void GeneratorMicroTurbine_Impl::resetFuelLowerHeatingValue() { + bool result = setString(OS_Generator_MicroTurbineFields::FuelLowerHeatingValue, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setStandbyPower(double standbyPower) { + bool result = setDouble(OS_Generator_MicroTurbineFields::StandbyPower, standbyPower); + return result; + } + + void GeneratorMicroTurbine_Impl::resetStandbyPower() { + bool result = setString(OS_Generator_MicroTurbineFields::StandbyPower, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setAncillaryPower(double ancillaryPower) { + bool result = setDouble(OS_Generator_MicroTurbineFields::AncillaryPower, ancillaryPower); + return result; + } + + void GeneratorMicroTurbine_Impl::resetAncillaryPower() { + bool result = setString(OS_Generator_MicroTurbineFields::AncillaryPower, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setAncillaryPowerFunctionofFuelInputCurve(const Curve& curve) { + bool result = setPointer(OS_Generator_MicroTurbineFields::AncillaryPowerFunctionofFuelInputCurveName, curve.handle()); + return result; + } + + void GeneratorMicroTurbine_Impl::resetAncillaryPowerFunctionofFuelInputCurve() { + bool result = setString(OS_Generator_MicroTurbineFields::AncillaryPowerFunctionofFuelInputCurveName, ""); + OS_ASSERT(result); + } + + + // Private: Generator:MicroTurbine:HeatRecovery + bool GeneratorMicroTurbine_Impl::setGeneratorMicroTurbineHeatRecovery(const GeneratorMicroTurbineHeatRecovery& generatorMicroTurbineHeatRecovery) { + bool result = setPointer(OS_Generator_MicroTurbineFields::GeneratorMicroTurbineHeatRecoveryName, generatorMicroTurbineHeatRecovery.handle()); + return result; + } + + /* + void GeneratorMicroTurbine_Impl::resetGeneratorMicroTurbineHeatRecovery() { + bool result = setString(OS_Generator_MicroTurbineFields::GeneratorMicroTurbineHeatRecoveryName, ""); + OS_ASSERT(result); + }*/ + + /* void GeneratorMicroTurbine_Impl::resetCombustionAirInletNode() { + bool result = setString(OS_Generator_MicroTurbineFields::CombustionAirInletNodeName, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setCombustionAirOutletNode(const boost::optional& connection) { + bool result(false); + if (connection) { + result = setPointer(OS_Generator_MicroTurbineFields::CombustionAirOutletNodeName, connection.get().handle()); + } + else { + resetCombustionAirOutletNode(); + result = true; + } + return result; + } + + void GeneratorMicroTurbine_Impl::resetCombustionAirOutletNode() { + bool result = setString(OS_Generator_MicroTurbineFields::CombustionAirOutletNodeName, ""); + OS_ASSERT(result); + } */ + + bool GeneratorMicroTurbine_Impl::setReferenceExhaustAirMassFlowRate(double referenceExhaustAirMassFlowRate) { + bool result = setDouble(OS_Generator_MicroTurbineFields::ReferenceExhaustAirMassFlowRate, referenceExhaustAirMassFlowRate); + return result; + } + + void GeneratorMicroTurbine_Impl::resetReferenceExhaustAirMassFlowRate() { + bool result = setString(OS_Generator_MicroTurbineFields::ReferenceExhaustAirMassFlowRate, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setExhaustAirFlowRateFunctionofTemperatureCurve(const Curve& curve) { + bool result = setPointer(OS_Generator_MicroTurbineFields::ExhaustAirFlowRateFunctionofTemperatureCurveName, curve.handle()); + return result; + } + + void GeneratorMicroTurbine_Impl::resetExhaustAirFlowRateFunctionofTemperatureCurve() { + bool result = setString(OS_Generator_MicroTurbineFields::ExhaustAirFlowRateFunctionofTemperatureCurveName, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setExhaustAirFlowRateFunctionofPartLoadRatioCurve(const Curve& curve) { + bool result = setPointer(OS_Generator_MicroTurbineFields::ExhaustAirFlowRateFunctionofPartLoadRatioCurveName, curve.handle()); + return result; + } + + void GeneratorMicroTurbine_Impl::resetExhaustAirFlowRateFunctionofPartLoadRatioCurve() { + bool result = setString(OS_Generator_MicroTurbineFields::ExhaustAirFlowRateFunctionofPartLoadRatioCurveName, ""); + OS_ASSERT(result); + } + + void GeneratorMicroTurbine_Impl::setNominalExhaustAirOutletTemperature(double nominalExhaustAirOutletTemperature) { + bool result = setDouble(OS_Generator_MicroTurbineFields::NominalExhaustAirOutletTemperature, nominalExhaustAirOutletTemperature); + OS_ASSERT(result); + } + + void GeneratorMicroTurbine_Impl::resetNominalExhaustAirOutletTemperature() { + bool result = setString(OS_Generator_MicroTurbineFields::NominalExhaustAirOutletTemperature, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setExhaustAirTemperatureFunctionofTemperatureCurve(const Curve& curve) { + bool result = setPointer(OS_Generator_MicroTurbineFields::ExhaustAirTemperatureFunctionofTemperatureCurveName, curve.handle()); + return result; + } + + void GeneratorMicroTurbine_Impl::resetExhaustAirTemperatureFunctionofTemperatureCurve() { + bool result = setString(OS_Generator_MicroTurbineFields::ExhaustAirTemperatureFunctionofTemperatureCurveName, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbine_Impl::setExhaustAirTemperatureFunctionofPartLoadRatioCurve(const Curve& curve) { + bool result = setPointer(OS_Generator_MicroTurbineFields::ExhaustAirTemperatureFunctionofPartLoadRatioCurveName, curve.handle()); + return result; + } + + void GeneratorMicroTurbine_Impl::resetExhaustAirTemperatureFunctionofPartLoadRatioCurve() { + bool result = setString(OS_Generator_MicroTurbineFields::ExhaustAirTemperatureFunctionofPartLoadRatioCurveName, ""); + OS_ASSERT(result); + } + /* + boost::optional GeneratorMicroTurbine_Impl::optionalElectricalPowerFunctionofTemperatureandElevationCurve() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::ElectricalPowerFunctionofTemperatureandElevationCurveName); + } + + boost::optional GeneratorMicroTurbine_Impl::optionalElectricalEfficiencyFunctionofTemperatureCurve() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::ElectricalEfficiencyFunctionofTemperatureCurveName); + } + + boost::optional GeneratorMicroTurbine_Impl::optionalElectricalEfficiencyFunctionofPartLoadRatioCurve() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbineFields::ElectricalEfficiencyFunctionofPartLoadRatioCurveName); + } + */ + +} // detail + +GeneratorMicroTurbine::GeneratorMicroTurbine(const Model& model) + : Generator(GeneratorMicroTurbine::iddObjectType(),model) +{ + OS_ASSERT(getImpl()); + + // TODO set a value to all required fields with no default... + // Source: Generators.idf, Capstone C65 + //setName("Generator MicroTurbine Capstone C65"); + + // Reference Electrical Power Output + setReferenceElectricalPowerOutput(65000); + + // Reference Electrical Efficiency Using Lower Heating Value + setReferenceElectricalEfficiencyUsingLowerHeatingValue(0.29); + + //Electrical Power Function of Temperature and Elevation Curve Name + // CurveBiquadratic + CurveBiquadratic elecPowerFTempElevation(model); + elecPowerFTempElevation.setName(name().get() + " Capstone C65 Power_vs_Temp_Elev"); + elecPowerFTempElevation.setCoefficient1Constant(1.2027697); + elecPowerFTempElevation.setCoefficient2x(-9.671305E-03); + elecPowerFTempElevation.setCoefficient3xPOW2(-4.860793E-06); + elecPowerFTempElevation.setCoefficient4y(-1.542394E-04); + elecPowerFTempElevation.setCoefficient5yPOW2(9.111418E-09); + elecPowerFTempElevation.setCoefficient6xTIMESY(8.797885E-07); + elecPowerFTempElevation.setMinimumValueofx(-17.8); + elecPowerFTempElevation.setMaximumValueofx(50); + elecPowerFTempElevation.setMinimumValueofy(0); + elecPowerFTempElevation.setMaximumValueofy(3050.); + // Temperature, !- Input Unit Type for X + // Distance, !- Input Unit Type for Y + // Dimensionless; !- Output Unit Type + setElectricalPowerFunctionofTemperatureandElevationCurve(elecPowerFTempElevation); + + // ElectricalEfficiencyFunctionofTemperatureCurveName + // \object - list QuadraticCubicCurves + /*! Electrical Efficiency Modifier Curve (function of temperature) +! x = Dry-Bulb Temperature of Combustion Inlet Air (C) + + Curve:Cubic, + Capstone C65 Efficiency_vs_Temp, !- Name + 1.0402217, !- Coefficient1 Constant + -0.0017314, !- Coefficient2 x + -6.497040E-05, !- Coefficient3 x**2 + 5.133175E-07, !- Coefficient4 x**3 + -20.0, !- Minimum Value of x + 50.0, !- Maximum Value of x + , !- Minimum Curve Output + , !- Maximum Curve Output + Temperature, !- Input Unit Type for X + Dimensionless; !- Output Unit Type*/ + CurveCubic elecEffFT(model); + elecEffFT.setName(name().get() + " Capstone C65 Efficiency_vs_Temp"); + elecEffFT.setCoefficient1Constant(1.0402217); + elecEffFT.setCoefficient2x(-0.0017314); + elecEffFT.setCoefficient3xPOW2(-6.497040E-05); + elecEffFT.setCoefficient4xPOW3(5.133175E-07); + elecEffFT.setMinimumValueofx(-20); + elecEffFT.setMaximumValueofx(50); + setElectricalEfficiencyFunctionofTemperatureCurve(elecEffFT); + + // ElectricalEfficiencyFunctionofPartLoadRatioCurveName + // QuadraticCubicCurves + /* Curve:Cubic, + Capstone C65 Efficiency_vs_PLR, !- Name + , !- Coefficient1 Constant + , !- Coefficient2 x + , !- Coefficient3 x**2 + , !- Coefficient4 x**3 + 0.03, !- Minimum Value of x + 1.0; !- Maximum Value of x*/ + CurveCubic elecEffFPLR(model); + elecEffFPLR.setName(name().get() + " Capstone C65 Efficiency_vs_PLR"); + elecEffFPLR.setCoefficient1Constant(0.215290); + elecEffFPLR.setCoefficient2x(2.561463); + elecEffFPLR.setCoefficient3xPOW2(-3.24613); + elecEffFPLR.setCoefficient4xPOW3(1.497306); + elecEffFPLR.setMinimumValueofx(0.03); + elecEffFPLR.setMaximumValueofx(1.0); + setElectricalEfficiencyFunctionofPartLoadRatioCurve(elecEffFPLR); +} + +IddObjectType GeneratorMicroTurbine::iddObjectType() { + return IddObjectType(IddObjectType::OS_Generator_MicroTurbine); +} + +std::vector GeneratorMicroTurbine::validFuelTypeValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), + OS_Generator_MicroTurbineFields::FuelType); +} + +double GeneratorMicroTurbine::referenceElectricalPowerOutput() const { + return getImpl()->referenceElectricalPowerOutput(); +} + +boost::optional GeneratorMicroTurbine::ratedThermaltoElectricalPowerRatio() const { + return getImpl()->ratedThermaltoElectricalPowerRatio(); +} + +boost::optional GeneratorMicroTurbine::availabilitySchedule() const { + return getImpl()->availabilitySchedule(); +} + +double GeneratorMicroTurbine::minimumFullLoadElectricalPowerOutput() const { + return getImpl()->minimumFullLoadElectricalPowerOutput(); +} + +bool GeneratorMicroTurbine::isMinimumFullLoadElectricalPowerOutputDefaulted() const { + return getImpl()->isMinimumFullLoadElectricalPowerOutputDefaulted(); +} + +double GeneratorMicroTurbine::maximumFullLoadElectricalPowerOutput() const { + return getImpl()->maximumFullLoadElectricalPowerOutput(); +} + +bool GeneratorMicroTurbine::isMaximumFullLoadElectricalPowerOutputDefaulted() const { + return getImpl()->isMaximumFullLoadElectricalPowerOutputDefaulted(); +} + +double GeneratorMicroTurbine::referenceElectricalEfficiencyUsingLowerHeatingValue() const { + return getImpl()->referenceElectricalEfficiencyUsingLowerHeatingValue(); +} + +double GeneratorMicroTurbine::referenceCombustionAirInletTemperature() const { + return getImpl()->referenceCombustionAirInletTemperature(); +} + +bool GeneratorMicroTurbine::isReferenceCombustionAirInletTemperatureDefaulted() const { + return getImpl()->isReferenceCombustionAirInletTemperatureDefaulted(); +} + +double GeneratorMicroTurbine::referenceCombustionAirInletHumidityRatio() const { + return getImpl()->referenceCombustionAirInletHumidityRatio(); +} + +bool GeneratorMicroTurbine::isReferenceCombustionAirInletHumidityRatioDefaulted() const { + return getImpl()->isReferenceCombustionAirInletHumidityRatioDefaulted(); +} + +double GeneratorMicroTurbine::referenceElevation() const { + return getImpl()->referenceElevation(); +} + +bool GeneratorMicroTurbine::isReferenceElevationDefaulted() const { + return getImpl()->isReferenceElevationDefaulted(); +} + +Curve GeneratorMicroTurbine::electricalPowerFunctionofTemperatureandElevationCurve() const { + return getImpl()->electricalPowerFunctionofTemperatureandElevationCurve(); +} + +Curve GeneratorMicroTurbine::electricalEfficiencyFunctionofTemperatureCurve() const { + return getImpl()->electricalEfficiencyFunctionofTemperatureCurve(); +} + +Curve GeneratorMicroTurbine::electricalEfficiencyFunctionofPartLoadRatioCurve() const { + return getImpl()->electricalEfficiencyFunctionofPartLoadRatioCurve(); +} + +std::string GeneratorMicroTurbine::fuelType() const { + return getImpl()->fuelType(); +} + +bool GeneratorMicroTurbine::isFuelTypeDefaulted() const { + return getImpl()->isFuelTypeDefaulted(); +} + +double GeneratorMicroTurbine::fuelHigherHeatingValue() const { + return getImpl()->fuelHigherHeatingValue(); +} + +bool GeneratorMicroTurbine::isFuelHigherHeatingValueDefaulted() const { + return getImpl()->isFuelHigherHeatingValueDefaulted(); +} + +double GeneratorMicroTurbine::fuelLowerHeatingValue() const { + return getImpl()->fuelLowerHeatingValue(); +} + +bool GeneratorMicroTurbine::isFuelLowerHeatingValueDefaulted() const { + return getImpl()->isFuelLowerHeatingValueDefaulted(); +} + +double GeneratorMicroTurbine::standbyPower() const { + return getImpl()->standbyPower(); +} + +bool GeneratorMicroTurbine::isStandbyPowerDefaulted() const { + return getImpl()->isStandbyPowerDefaulted(); +} + +double GeneratorMicroTurbine::ancillaryPower() const { + return getImpl()->ancillaryPower(); +} + +bool GeneratorMicroTurbine::isAncillaryPowerDefaulted() const { + return getImpl()->isAncillaryPowerDefaulted(); +} + +boost::optional GeneratorMicroTurbine::ancillaryPowerFunctionofFuelInputCurve() const { + return getImpl()->ancillaryPowerFunctionofFuelInputCurve(); +} + +boost::optional GeneratorMicroTurbine::generatorMicroTurbineHeatRecovery() const { + return getImpl()->generatorMicroTurbineHeatRecovery(); +} + +/* +boost::optional GeneratorMicroTurbine::combustionAirInletNode() const { + return getImpl()->combustionAirInletNode(); +} + +boost::optional GeneratorMicroTurbine::combustionAirOutletNode() const { + return getImpl()->combustionAirOutletNode(); +} */ + +boost::optional GeneratorMicroTurbine::referenceExhaustAirMassFlowRate() const { + return getImpl()->referenceExhaustAirMassFlowRate(); +} + +boost::optional GeneratorMicroTurbine::exhaustAirFlowRateFunctionofTemperatureCurve() const { + return getImpl()->exhaustAirFlowRateFunctionofTemperatureCurve(); +} + +boost::optional GeneratorMicroTurbine::exhaustAirFlowRateFunctionofPartLoadRatioCurve() const { + return getImpl()->exhaustAirFlowRateFunctionofPartLoadRatioCurve(); +} + +boost::optional GeneratorMicroTurbine::nominalExhaustAirOutletTemperature() const { + return getImpl()->nominalExhaustAirOutletTemperature(); +} + +boost::optional GeneratorMicroTurbine::exhaustAirTemperatureFunctionofTemperatureCurve() const { + return getImpl()->exhaustAirTemperatureFunctionofTemperatureCurve(); +} + +boost::optional GeneratorMicroTurbine::exhaustAirTemperatureFunctionofPartLoadRatioCurve() const { + return getImpl()->exhaustAirTemperatureFunctionofPartLoadRatioCurve(); +} + +bool GeneratorMicroTurbine::setReferenceElectricalPowerOutput(double referenceElectricalPowerOutput) { + return getImpl()->setReferenceElectricalPowerOutput(referenceElectricalPowerOutput); +} + +bool GeneratorMicroTurbine::setMinimumFullLoadElectricalPowerOutput(double minimumFullLoadElectricalPowerOutput) { + return getImpl()->setMinimumFullLoadElectricalPowerOutput(minimumFullLoadElectricalPowerOutput); +} + +void GeneratorMicroTurbine::resetMinimumFullLoadElectricalPowerOutput() { + getImpl()->resetMinimumFullLoadElectricalPowerOutput(); +} + +bool GeneratorMicroTurbine::setAvailabilitySchedule(Schedule& schedule) { + return getImpl()->setAvailabilitySchedule(schedule); +} + +void GeneratorMicroTurbine::resetAvailabilitySchedule() { + getImpl()->resetAvailabilitySchedule(); +} + +bool GeneratorMicroTurbine::setMaximumFullLoadElectricalPowerOutput(double maximumFullLoadElectricalPowerOutput) { + return getImpl()->setMaximumFullLoadElectricalPowerOutput(maximumFullLoadElectricalPowerOutput); +} + +void GeneratorMicroTurbine::resetMaximumFullLoadElectricalPowerOutput() { + getImpl()->resetMaximumFullLoadElectricalPowerOutput(); +} + +bool GeneratorMicroTurbine::setReferenceElectricalEfficiencyUsingLowerHeatingValue(double referenceElectricalEfficiencyUsingLowerHeatingValue) { + return getImpl()->setReferenceElectricalEfficiencyUsingLowerHeatingValue(referenceElectricalEfficiencyUsingLowerHeatingValue); +} + +void GeneratorMicroTurbine::setReferenceCombustionAirInletTemperature(double referenceCombustionAirInletTemperature) { + getImpl()->setReferenceCombustionAirInletTemperature(referenceCombustionAirInletTemperature); +} + +void GeneratorMicroTurbine::resetReferenceCombustionAirInletTemperature() { + getImpl()->resetReferenceCombustionAirInletTemperature(); +} + +bool GeneratorMicroTurbine::setReferenceCombustionAirInletHumidityRatio(double referenceCombustionAirInletHumidityRatio) { + return getImpl()->setReferenceCombustionAirInletHumidityRatio(referenceCombustionAirInletHumidityRatio); +} + +void GeneratorMicroTurbine::resetReferenceCombustionAirInletHumidityRatio() { + getImpl()->resetReferenceCombustionAirInletHumidityRatio(); +} + +bool GeneratorMicroTurbine::setReferenceElevation(double referenceElevation) { + return getImpl()->setReferenceElevation(referenceElevation); +} + +void GeneratorMicroTurbine::resetReferenceElevation() { + getImpl()->resetReferenceElevation(); +} + +bool GeneratorMicroTurbine::setElectricalPowerFunctionofTemperatureandElevationCurve(const Curve& curve) { + return getImpl()->setElectricalPowerFunctionofTemperatureandElevationCurve(curve); +} + +bool GeneratorMicroTurbine::setElectricalEfficiencyFunctionofTemperatureCurve(const Curve& curve) { + return getImpl()->setElectricalEfficiencyFunctionofTemperatureCurve(curve); +} + +bool GeneratorMicroTurbine::setElectricalEfficiencyFunctionofPartLoadRatioCurve(const Curve& curve) { + return getImpl()->setElectricalEfficiencyFunctionofPartLoadRatioCurve(curve); +} + +bool GeneratorMicroTurbine::setFuelType(const std::string& fuelType) { + return getImpl()->setFuelType(fuelType); +} + +void GeneratorMicroTurbine::resetFuelType() { + getImpl()->resetFuelType(); +} + +bool GeneratorMicroTurbine::setFuelHigherHeatingValue(double fuelHigherHeatingValue) { + return getImpl()->setFuelHigherHeatingValue(fuelHigherHeatingValue); +} + +void GeneratorMicroTurbine::resetFuelHigherHeatingValue() { + getImpl()->resetFuelHigherHeatingValue(); +} + +bool GeneratorMicroTurbine::setFuelLowerHeatingValue(double fuelLowerHeatingValue) { + return getImpl()->setFuelLowerHeatingValue(fuelLowerHeatingValue); +} + +void GeneratorMicroTurbine::resetFuelLowerHeatingValue() { + getImpl()->resetFuelLowerHeatingValue(); +} + +bool GeneratorMicroTurbine::setStandbyPower(double standbyPower) { + return getImpl()->setStandbyPower(standbyPower); +} + +void GeneratorMicroTurbine::resetStandbyPower() { + getImpl()->resetStandbyPower(); +} + +bool GeneratorMicroTurbine::setAncillaryPower(double ancillaryPower) { + return getImpl()->setAncillaryPower(ancillaryPower); +} + +void GeneratorMicroTurbine::resetAncillaryPower() { + getImpl()->resetAncillaryPower(); +} + +bool GeneratorMicroTurbine::setAncillaryPowerFunctionofFuelInputCurve(const Curve& curve) { + return getImpl()->setAncillaryPowerFunctionofFuelInputCurve(curve); +} + +void GeneratorMicroTurbine::resetAncillaryPowerFunctionofFuelInputCurve() { + getImpl()->resetAncillaryPowerFunctionofFuelInputCurve(); +} + +// These isn't made "public" to bindings +/*bool GeneratorMicroTurbine::setGeneratorMicroTurbineHeatRecovery(const GeneratorMicroTurbineHeatRecovery& heatRecovery) { + return getImpl()->setGeneratorMicroTurbineHeatRecovery(heatRecovery); +}*/ + +/* This isn't implemented +void GeneratorMicroTurbine::resetGeneratorMicroTurbineHeatRecovery() { + getImpl()->resetGeneratorMicroTurbineHeatRecovery(); +}*/ + +/* +bool GeneratorMicroTurbine::setCombustionAirInletNode(const Connection& connection) { + return getImpl()->setCombustionAirInletNode(connection); +} + +void GeneratorMicroTurbine::resetCombustionAirInletNode() { + getImpl()->resetCombustionAirInletNode(); +} + +bool GeneratorMicroTurbine::setCombustionAirOutletNode(const Connection& connection) { + return getImpl()->setCombustionAirOutletNode(connection); +} + +void GeneratorMicroTurbine::resetCombustionAirOutletNode() { + getImpl()->resetCombustionAirOutletNode(); +} */ + +bool GeneratorMicroTurbine::setReferenceExhaustAirMassFlowRate(double referenceExhaustAirMassFlowRate) { + return getImpl()->setReferenceExhaustAirMassFlowRate(referenceExhaustAirMassFlowRate); +} + +void GeneratorMicroTurbine::resetReferenceExhaustAirMassFlowRate() { + getImpl()->resetReferenceExhaustAirMassFlowRate(); +} + +bool GeneratorMicroTurbine::setExhaustAirFlowRateFunctionofTemperatureCurve(const Curve& curve) { + return getImpl()->setExhaustAirFlowRateFunctionofTemperatureCurve(curve); +} + +void GeneratorMicroTurbine::resetExhaustAirFlowRateFunctionofTemperatureCurve() { + getImpl()->resetExhaustAirFlowRateFunctionofTemperatureCurve(); +} + +bool GeneratorMicroTurbine::setExhaustAirFlowRateFunctionofPartLoadRatioCurve(const Curve& curve) { + return getImpl()->setExhaustAirFlowRateFunctionofPartLoadRatioCurve(curve); +} + +void GeneratorMicroTurbine::resetExhaustAirFlowRateFunctionofPartLoadRatioCurve() { + getImpl()->resetExhaustAirFlowRateFunctionofPartLoadRatioCurve(); +} + +void GeneratorMicroTurbine::setNominalExhaustAirOutletTemperature(double nominalExhaustAirOutletTemperature) { + getImpl()->setNominalExhaustAirOutletTemperature(nominalExhaustAirOutletTemperature); +} + +void GeneratorMicroTurbine::resetNominalExhaustAirOutletTemperature() { + getImpl()->resetNominalExhaustAirOutletTemperature(); +} + +bool GeneratorMicroTurbine::setExhaustAirTemperatureFunctionofTemperatureCurve(const Curve& curve) { + return getImpl()->setExhaustAirTemperatureFunctionofTemperatureCurve(curve); +} + +void GeneratorMicroTurbine::resetExhaustAirTemperatureFunctionofTemperatureCurve() { + getImpl()->resetExhaustAirTemperatureFunctionofTemperatureCurve(); +} + +bool GeneratorMicroTurbine::setExhaustAirTemperatureFunctionofPartLoadRatioCurve(const Curve& curve) { + return getImpl()->setExhaustAirTemperatureFunctionofPartLoadRatioCurve(curve); +} + +void GeneratorMicroTurbine::resetExhaustAirTemperatureFunctionofPartLoadRatioCurve() { + getImpl()->resetExhaustAirTemperatureFunctionofPartLoadRatioCurve(); +} + + +/// @cond +GeneratorMicroTurbine::GeneratorMicroTurbine(std::shared_ptr impl) + : Generator(impl) +{} +/// @endcond + +} // model +} // openstudio + diff --git a/openstudiocore/src/model/GeneratorMicroTurbine.hpp b/openstudiocore/src/model/GeneratorMicroTurbine.hpp new file mode 100644 index 00000000000..359a7b8ed6c --- /dev/null +++ b/openstudiocore/src/model/GeneratorMicroTurbine.hpp @@ -0,0 +1,261 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#ifndef MODEL_GENERATORMICROTURBINE_HPP +#define MODEL_GENERATORMICROTURBINE_HPP + +#include +#include "Generator.hpp" +#include "GeneratorMicroTurbineHeatRecovery.hpp" + +namespace openstudio { + +namespace model { + +class Curve; +// For the optional Generator:MicroTurbine:HeatRecovery +// It was broken out because that part needs to connect to a plant loop +class StraightComponent; + +// TODO: add the tables class if they get added to OS later? +//class DataTables // UniVariateTables and BiVariateTables + +//class Connection; + +namespace detail { + + class GeneratorMicroTurbine_Impl; + +} // detail + +/** GeneratorMicroTurbine is a Generator that wraps the OpenStudio IDD object 'OS:Generator:MicroTurbine'. */ +class MODEL_API GeneratorMicroTurbine : public Generator { + public: + /** @name Constructors and Destructors */ + //@{ + + // TODO: Could add a constructor with all the required inputs, but that's a lot of them + + explicit GeneratorMicroTurbine(const Model& model); + + virtual ~GeneratorMicroTurbine() {} + + virtual boost::optional ratedThermaltoElectricalPowerRatio() const; + + //@} + + static IddObjectType iddObjectType(); + + static std::vector validFuelTypeValues(); + + /** @name Getters */ + //@{ + + // TODO: In E+ there's ElectricLoadCenter:GeneratorList where you'll specify the order of generators and the availability Schedule + // here it's been moved to the Generator themselves + boost::optional availabilitySchedule() const; + + double referenceElectricalPowerOutput() const; + + double minimumFullLoadElectricalPowerOutput() const; + bool isMinimumFullLoadElectricalPowerOutputDefaulted() const; + + // This will default to referenceElectricalPowerOutput if not defined, like E+ does + double maximumFullLoadElectricalPowerOutput() const; + bool isMaximumFullLoadElectricalPowerOutputDefaulted() const; + + double referenceElectricalEfficiencyUsingLowerHeatingValue() const; + + double referenceCombustionAirInletTemperature() const; + bool isReferenceCombustionAirInletTemperatureDefaulted() const; + + double referenceCombustionAirInletHumidityRatio() const; + bool isReferenceCombustionAirInletHumidityRatioDefaulted() const; + + double referenceElevation() const; + bool isReferenceElevationDefaulted() const; + + Curve electricalPowerFunctionofTemperatureandElevationCurve() const; + + Curve electricalEfficiencyFunctionofTemperatureCurve() const; + + Curve electricalEfficiencyFunctionofPartLoadRatioCurve() const; + + std::string fuelType() const; + bool isFuelTypeDefaulted() const; + + double fuelHigherHeatingValue() const; + bool isFuelHigherHeatingValueDefaulted() const; + + double fuelLowerHeatingValue() const; + bool isFuelLowerHeatingValueDefaulted() const; + + double standbyPower() const; + bool isStandbyPowerDefaulted() const; + + double ancillaryPower() const; + bool isAncillaryPowerDefaulted() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCurves, UniVariateTables. + boost::optional ancillaryPowerFunctionofFuelInputCurve() const; + + // Optional Generator:MicroTurbine:HeatRecovery + boost::optional generatorMicroTurbineHeatRecovery() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + //boost::optional combustionAirInletNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + // boost::optional combustionAirOutletNode() const; + + boost::optional referenceExhaustAirMassFlowRate() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + boost::optional exhaustAirFlowRateFunctionofTemperatureCurve() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + boost::optional exhaustAirFlowRateFunctionofPartLoadRatioCurve() const; + + boost::optional nominalExhaustAirOutletTemperature() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + boost::optional exhaustAirTemperatureFunctionofTemperatureCurve() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + boost::optional exhaustAirTemperatureFunctionofPartLoadRatioCurve() const; + + //@} + /** @name Setters */ + //@{ + + bool setAvailabilitySchedule(Schedule& schedule); + void resetAvailabilitySchedule(); + + bool setReferenceElectricalPowerOutput(double referenceElectricalPowerOutput); + + bool setMinimumFullLoadElectricalPowerOutput(double minimumFullLoadElectricalPowerOutput); + void resetMinimumFullLoadElectricalPowerOutput(); + + bool setMaximumFullLoadElectricalPowerOutput(double maximumFullLoadElectricalPowerOutput); + void resetMaximumFullLoadElectricalPowerOutput(); + + bool setReferenceElectricalEfficiencyUsingLowerHeatingValue(double referenceElectricalEfficiencyUsingLowerHeatingValue); + + void setReferenceCombustionAirInletTemperature(double referenceCombustionAirInletTemperature); + void resetReferenceCombustionAirInletTemperature(); + + bool setReferenceCombustionAirInletHumidityRatio(double referenceCombustionAirInletHumidityRatio); + void resetReferenceCombustionAirInletHumidityRatio(); + + bool setReferenceElevation(double referenceElevation); + void resetReferenceElevation(); + + // TODO: Check argument type. From object lists, some candidates are: BiquadraticCurves, BiVariateTables. + bool setElectricalPowerFunctionofTemperatureandElevationCurve(const Curve& electricalPowerFunctionofTemperatureandElevationCurve); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCubicCurves. + bool setElectricalEfficiencyFunctionofTemperatureCurve(const Curve& electricalEfficiencyFunctionofTemperatureCurve); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCubicCurves. + bool setElectricalEfficiencyFunctionofPartLoadRatioCurve(const Curve& electricalEfficiencyFunctionofPartLoadRatioCurve); + + bool setFuelType(const std::string& fuelType); + void resetFuelType(); + + bool setFuelHigherHeatingValue(double fuelHigherHeatingValue); + void resetFuelHigherHeatingValue(); + + bool setFuelLowerHeatingValue(double fuelLowerHeatingValue); + void resetFuelLowerHeatingValue(); + + bool setStandbyPower(double standbyPower); + void resetStandbyPower(); + + bool setAncillaryPower(double ancillaryPower); + void resetAncillaryPower(); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCurves, UniVariateTables. + bool setAncillaryPowerFunctionofFuelInputCurve(const Curve& ancillaryPowerFunctionofFuelInputCurve); + void resetAncillaryPowerFunctionofFuelInputCurve(); + + // Optional Generator:MicroTurbine:HeatRecovery + //bool setGeneratorMicroTurbineHeatRecovery(const GeneratorMicroTurbineHeatRecovery& generatorMicroTurbineHeatRecovery); + //void resetGeneratorMicroTurbineHeatRecovery(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + //bool setCombustionAirInletNode(const Connection& connection); + //void resetCombustionAirInletNode(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + //bool setCombustionAirOutletNode(const Connection& connection); + //void resetCombustionAirOutletNode(); + + bool setReferenceExhaustAirMassFlowRate(double referenceExhaustAirMassFlowRate); + void resetReferenceExhaustAirMassFlowRate(); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + bool setExhaustAirFlowRateFunctionofTemperatureCurve(const Curve& exhaustAirFlowRateFunctionofTemperatureCurve); + void resetExhaustAirFlowRateFunctionofTemperatureCurve(); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + bool setExhaustAirFlowRateFunctionofPartLoadRatioCurve(const Curve& exhaustAirFlowRateFunctionofPartLoadRatioCurve); + void resetExhaustAirFlowRateFunctionofPartLoadRatioCurve(); + + void setNominalExhaustAirOutletTemperature(double nominalExhaustAirOutletTemperature); + void resetNominalExhaustAirOutletTemperature(); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + bool setExhaustAirTemperatureFunctionofTemperatureCurve(const Curve& exhaustAirTemperatureFunctionofTemperatureCurve); + void resetExhaustAirTemperatureFunctionofTemperatureCurve(); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + bool setExhaustAirTemperatureFunctionofPartLoadRatioCurve(const Curve& exhaustAirTemperatureFunctionofPartLoadRatioCurve); + void resetExhaustAirTemperatureFunctionofPartLoadRatioCurve(); + + //@} + /** @name Other */ + //@{ + + //@} + protected: + /// @cond + typedef detail::GeneratorMicroTurbine_Impl ImplType; + + explicit GeneratorMicroTurbine(std::shared_ptr impl); + + friend class detail::GeneratorMicroTurbine_Impl; + friend class Model; + friend class IdfObject; + friend class openstudio::detail::IdfObject_Impl; + /// @endcond + private: + REGISTER_LOGGER("openstudio.model.GeneratorMicroTurbine"); +}; + +/** \relates GeneratorMicroTurbine*/ +typedef boost::optional OptionalGeneratorMicroTurbine; + +/** \relates GeneratorMicroTurbine*/ +typedef std::vector GeneratorMicroTurbineVector; + +} // model +} // openstudio + +#endif // MODEL_GENERATORMICROTURBINE_HPP + diff --git a/openstudiocore/src/model/GeneratorMicroTurbineHeatRecovery.cpp b/openstudiocore/src/model/GeneratorMicroTurbineHeatRecovery.cpp new file mode 100644 index 00000000000..04f5f7c7e1e --- /dev/null +++ b/openstudiocore/src/model/GeneratorMicroTurbineHeatRecovery.cpp @@ -0,0 +1,718 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ +#include "Model.hpp" +#include "Model_Impl.hpp" + +#include "GeneratorMicroTurbine.hpp" +#include "GeneratorMicroTurbine_Impl.hpp" +#include "GeneratorMicroTurbineHeatRecovery.hpp" +#include "GeneratorMicroTurbineHeatRecovery_Impl.hpp" + +#include "Node.hpp" +#include "Node_Impl.hpp" +#include "PlantLoop.hpp" +#include "PlantLoop_Impl.hpp" + +#include "Curve.hpp" +#include "Curve_Impl.hpp" +// TODO: add the tables class if they get added to OS later? +//#include "DataTables.hpp" + + +#include +#include +#include + + +// TODO not sure if need all of these +#include "../utilities/core/Compare.hpp" +#include "../utilities/core/Assert.hpp" +#include "../utilities/units/Quantity.hpp" +#include "../utilities/units/OSOptionalQuantity.hpp" + + +namespace openstudio { +namespace model { + + namespace detail { + + GeneratorMicroTurbineHeatRecovery_Impl::GeneratorMicroTurbineHeatRecovery_Impl(const IdfObject& idfObject, + Model_Impl* model, + bool keepHandle) + : StraightComponent_Impl(idfObject, model, keepHandle) + { + OS_ASSERT(idfObject.iddObject().type() == GeneratorMicroTurbineHeatRecovery::iddObjectType()); + } + + GeneratorMicroTurbineHeatRecovery_Impl::GeneratorMicroTurbineHeatRecovery_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, + bool keepHandle) + : StraightComponent_Impl(other, model, keepHandle) + { + OS_ASSERT(other.iddObject().type() == GeneratorMicroTurbineHeatRecovery::iddObjectType()); + } + + GeneratorMicroTurbineHeatRecovery_Impl::GeneratorMicroTurbineHeatRecovery_Impl(const GeneratorMicroTurbineHeatRecovery_Impl& other, + Model_Impl* model, + bool keepHandle) + : StraightComponent_Impl(other, model, keepHandle) + {} + + // Lists the output variables that are specific to the heat recovery portion of a Generator:MicroTurbine + const std::vector& GeneratorMicroTurbineHeatRecovery_Impl::outputVariableNames() const + { + static std::vector result; + if (result.empty()){ + result.push_back("Generator Produced Thermal Rate"); + result.push_back("Generator Produced Thermal Energy"); + result.push_back("Generator Thermal Efficiency LHV Basis"); + result.push_back("Generator Heat Recovery Inlet Temperature"); + result.push_back("Generator Heat Recovery Outlet Temperature"); + result.push_back("Generator Heat Recovery Water Mass Flow Rate"); + } + return result; + } + + IddObjectType GeneratorMicroTurbineHeatRecovery_Impl::iddObjectType() const { + return GeneratorMicroTurbineHeatRecovery::iddObjectType(); + } + + // This will clone both the GeneratorMicroTurbineHeatRecovery and its linked GeneratorMicroTurbineHeatRecovery + // and will return a reference to the GeneratorMicroTurbineHeatRecovery + ModelObject GeneratorMicroTurbineHeatRecovery_Impl::clone(Model model) const + { + + // We call the parent generator's Clone method which will clone both the mchp and mchpHR + GeneratorMicroTurbine mchp = generatorMicroTurbine(); + GeneratorMicroTurbine mchpClone = mchp.clone(model).cast(); + + // We get the clone of the parent generator's MTHR so we can return that + GeneratorMicroTurbineHeatRecovery mchpHRClone = mchpClone.generatorMicroTurbineHeatRecovery().get(); + + + return mchpHRClone; + } + + std::vector GeneratorMicroTurbineHeatRecovery_Impl::allowableChildTypes() const + { + std::vector result; + result.push_back(IddObjectType::OS_Curve_Bicubic); + result.push_back(IddObjectType::OS_Curve_Biquadratic); + result.push_back(IddObjectType::OS_Curve_Cubic); + result.push_back(IddObjectType::OS_Curve_Quadratic); + return result; + } + + // Returns the children objects (max of 4 curves) + std::vector GeneratorMicroTurbineHeatRecovery_Impl::children() const + { + std::vector result; + boost::optional oCurve; + + // Curves should be included + if (oCurve = thermalEfficiencyFunctionofTemperatureandElevationCurve()) { + result.push_back(oCurve.get()); + } + if (oCurve = heatRecoveryRateFunctionofPartLoadRatioCurve()) { + result.push_back(oCurve.get()); + } + if (oCurve = heatRecoveryRateFunctionofInletWaterTemperatureCurve()) { + result.push_back(oCurve.get()); + } + + if (oCurve = heatRecoveryRateFunctionofWaterFlowRateCurve()) { + result.push_back(oCurve.get()); + } + + return result; + } + + unsigned GeneratorMicroTurbineHeatRecovery_Impl::inletPort() + { + return OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryWaterInletNodeName; + } + + unsigned GeneratorMicroTurbineHeatRecovery_Impl::outletPort() + { + return OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryWaterOutletNodeName; + } + + // Add to plantLoop Node: accepts to be placed on both the supply and the demand + // You should make sure that this is compatible with your Generator Operation Scheme + // For example, if FollowThermal, it must be placed on the supply side of the plant loop + bool GeneratorMicroTurbineHeatRecovery_Impl::addToNode(Node & node) + { + // This can be placed on the supply or the demand side + if( boost::optional plant = node.plantLoop() ) + { + return StraightComponent_Impl::addToNode(node); + } + + return false; + } + + + //boost::optional GeneratorMicroTurbineHeatRecovery_Impl::heatRecoveryWaterInletNode() const { + // return getObject().getModelObjectTarget(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryWaterInletNodeName); + //} + + //boost::optional GeneratorMicroTurbineHeatRecovery_Impl::heatRecoveryWaterOutletNode() const { + // return getObject().getModelObjectTarget(OS_Generator_MicroTurbineHeatRecoveryFields::HeatRecoveryWaterOutletNodeName); + //} + + double GeneratorMicroTurbineHeatRecovery_Impl::referenceThermalEfficiencyUsingLowerHeatValue() const { + boost::optional value = getDouble(OS_Generator_MicroTurbine_HeatRecoveryFields::ReferenceThermalEfficiencyUsingLowerHeatValue,true); + OS_ASSERT(value); + return value.get(); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::isReferenceThermalEfficiencyUsingLowerHeatValueDefaulted() const { + return isEmpty(OS_Generator_MicroTurbine_HeatRecoveryFields::ReferenceThermalEfficiencyUsingLowerHeatValue); + } + + double GeneratorMicroTurbineHeatRecovery_Impl::referenceInletWaterTemperature() const { + boost::optional value = getDouble(OS_Generator_MicroTurbine_HeatRecoveryFields::ReferenceInletWaterTemperature,true); + OS_ASSERT(value); + return value.get(); + } + + std::string GeneratorMicroTurbineHeatRecovery_Impl::heatRecoveryWaterFlowOperatingMode() const { + boost::optional value = getString(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryWaterFlowOperatingMode,true); + OS_ASSERT(value); + return value.get(); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::isHeatRecoveryWaterFlowOperatingModeDefaulted() const { + return isEmpty(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryWaterFlowOperatingMode); + } + + double GeneratorMicroTurbineHeatRecovery_Impl::referenceHeatRecoveryWaterFlowRate() const { + boost::optional value = getDouble(OS_Generator_MicroTurbine_HeatRecoveryFields::ReferenceHeatRecoveryWaterFlowRate,true); + OS_ASSERT(value); + return value.get(); + } + + boost::optional GeneratorMicroTurbineHeatRecovery_Impl::heatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurveName); + } + + boost::optional GeneratorMicroTurbineHeatRecovery_Impl::thermalEfficiencyFunctionofTemperatureandElevationCurve() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbine_HeatRecoveryFields::ThermalEfficiencyFunctionofTemperatureandElevationCurveName); + } + + boost::optional GeneratorMicroTurbineHeatRecovery_Impl::heatRecoveryRateFunctionofPartLoadRatioCurve() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryRateFunctionofPartLoadRatioCurveName); + } + + boost::optional GeneratorMicroTurbineHeatRecovery_Impl::heatRecoveryRateFunctionofInletWaterTemperatureCurve() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryRateFunctionofInletWaterTemperatureCurveName); + } + + boost::optional GeneratorMicroTurbineHeatRecovery_Impl::heatRecoveryRateFunctionofWaterFlowRateCurve() const { + return getObject().getModelObjectTarget(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryRateFunctionofWaterFlowRateCurveName); + } + + double GeneratorMicroTurbineHeatRecovery_Impl::minimumHeatRecoveryWaterFlowRate() const { + boost::optional value = getDouble(OS_Generator_MicroTurbine_HeatRecoveryFields::MinimumHeatRecoveryWaterFlowRate,true); + OS_ASSERT(value); + return value.get(); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::isMinimumHeatRecoveryWaterFlowRateDefaulted() const { + return isEmpty(OS_Generator_MicroTurbine_HeatRecoveryFields::MinimumHeatRecoveryWaterFlowRate); + } + + double GeneratorMicroTurbineHeatRecovery_Impl::maximumHeatRecoveryWaterFlowRate() const { + boost::optional value = getDouble(OS_Generator_MicroTurbine_HeatRecoveryFields::MaximumHeatRecoveryWaterFlowRate,true); + OS_ASSERT(value); + return value.get(); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::isMaximumHeatRecoveryWaterFlowRateDefaulted() const { + return isEmpty(OS_Generator_MicroTurbine_HeatRecoveryFields::MaximumHeatRecoveryWaterFlowRate); + } + + boost::optional GeneratorMicroTurbineHeatRecovery_Impl::maximumHeatRecoveryWaterTemperature() const { + return getDouble(OS_Generator_MicroTurbine_HeatRecoveryFields::MaximumHeatRecoveryWaterTemperature,true); + } + + // Get the parent generatorMicroTurbine + GeneratorMicroTurbine GeneratorMicroTurbineHeatRecovery_Impl::generatorMicroTurbine() const { + + boost::optional value; + for ( const GeneratorMicroTurbine& mchp : this->model().getConcreteModelObjects() ) + { + if ( boost::optional mchpHR = mchp.generatorMicroTurbineHeatRecovery() ) + { + if (mchpHR->handle() == this->handle()) + { + value = mchp; + } + } + } + OS_ASSERT(value); + return value.get(); + + } + + + + + + // If defaulted, return generatorMicroTurbineHeatRecovery 'Reference Thermal Efficiency Using Lower Heat Value' divided by its generatorMicroTurbine 'Reference Electrical Efficiency Using Lower Heating Value' + double GeneratorMicroTurbineHeatRecovery_Impl::ratedThermaltoElectricalPowerRatio() const { + boost::optional optRatedThermaltoElectricalPowerRatio = getDouble(OS_Generator_MicroTurbine_HeatRecoveryFields::RatedThermaltoElectricalPowerRatio, true); + // If there it's set + if (optRatedThermaltoElectricalPowerRatio) { + // Get it and return + return optRatedThermaltoElectricalPowerRatio.get(); + } + else { + // We try to default it + // First, check if there's a linked generator + // TODO: This should return an actual mchp once I make it part of the constructor. + //boost::optional mchp = this->generatorMicroTurbine(); + //if ( mchp ) { + GeneratorMicroTurbine mchp = this->generatorMicroTurbine(); + double refElecEffUsingLowerHeatingVal = mchp.referenceElectricalEfficiencyUsingLowerHeatingValue(); + double refThermalEffUsingLowerHeatVal = this->referenceThermalEfficiencyUsingLowerHeatValue(); + double ratedThermaltoElectricalPowerRatio = refThermalEffUsingLowerHeatVal / refElecEffUsingLowerHeatingVal; + return ratedThermaltoElectricalPowerRatio; + //} + } + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::isRatedThermaltoElectricalPowerRatioDefaulted() const { + return isEmpty(OS_Generator_MicroTurbine_HeatRecoveryFields::RatedThermaltoElectricalPowerRatio); + } + + + /*bool GeneratorMicroTurbineHeatRecovery_Impl::setHeatRecoveryWaterInletNode(const boost::optional& connection) { + bool result(false); + if (connection) { + result = setPointer(OS_Generator_MicroTurbineHeatRecoveryFields::HeatRecoveryWaterInletNodeName, connection.get().handle()); + } + else { + resetHeatRecoveryWaterInletNode(); + result = true; + } + return result; + } + + void GeneratorMicroTurbineHeatRecovery_Impl::resetHeatRecoveryWaterInletNode() { + bool result = setString(OS_Generator_MicroTurbineHeatRecoveryFields::HeatRecoveryWaterInletNodeName, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::setHeatRecoveryWaterOutletNode(const boost::optional& connection) { + bool result(false); + if (connection) { + result = setPointer(OS_Generator_MicroTurbineHeatRecoveryFields::HeatRecoveryWaterOutletNodeName, connection.get().handle()); + } + else { + resetHeatRecoveryWaterOutletNode(); + result = true; + } + return result; + } + + void GeneratorMicroTurbineHeatRecovery_Impl::resetHeatRecoveryWaterOutletNode() { + bool result = setString(OS_Generator_MicroTurbineHeatRecoveryFields::HeatRecoveryWaterOutletNodeName, ""); + OS_ASSERT(result); + } */ + + bool GeneratorMicroTurbineHeatRecovery_Impl::setReferenceThermalEfficiencyUsingLowerHeatValue(double value) { + bool result = setDouble(OS_Generator_MicroTurbine_HeatRecoveryFields::ReferenceThermalEfficiencyUsingLowerHeatValue, value); + return result; + } + + void GeneratorMicroTurbineHeatRecovery_Impl::resetReferenceThermalEfficiencyUsingLowerHeatValue() { + bool result = setString(OS_Generator_MicroTurbine_HeatRecoveryFields::ReferenceThermalEfficiencyUsingLowerHeatValue, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::setReferenceInletWaterTemperature(double value) { + bool result = setDouble(OS_Generator_MicroTurbine_HeatRecoveryFields::ReferenceInletWaterTemperature, value); + return result; + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::setHeatRecoveryWaterFlowOperatingMode(std::string heatRecoveryWaterFlowOperatingMode) { + bool result = setString(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryWaterFlowOperatingMode, heatRecoveryWaterFlowOperatingMode); + return result; + } + + void GeneratorMicroTurbineHeatRecovery_Impl::resetHeatRecoveryWaterFlowOperatingMode() { + bool result = setString(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryWaterFlowOperatingMode, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::setReferenceHeatRecoveryWaterFlowRate(double value) { + bool result = setDouble(OS_Generator_MicroTurbine_HeatRecoveryFields::ReferenceHeatRecoveryWaterFlowRate, value); + return result; + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::setHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve(const Curve& curve) { + bool result = setPointer(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurveName, curve.handle()); + return result; + } + + void GeneratorMicroTurbineHeatRecovery_Impl::resetHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve() { + bool result = setString(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurveName, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::setThermalEfficiencyFunctionofTemperatureandElevationCurve(const Curve& curve) { + bool result = setPointer(OS_Generator_MicroTurbine_HeatRecoveryFields::ThermalEfficiencyFunctionofTemperatureandElevationCurveName, curve.handle()); + return result; + } + + void GeneratorMicroTurbineHeatRecovery_Impl::resetThermalEfficiencyFunctionofTemperatureandElevationCurve() { + bool result = setString(OS_Generator_MicroTurbine_HeatRecoveryFields::ThermalEfficiencyFunctionofTemperatureandElevationCurveName, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::setHeatRecoveryRateFunctionofPartLoadRatioCurve(const Curve& curve) { + bool result = setPointer(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryRateFunctionofPartLoadRatioCurveName, curve.handle()); + return result; + } + + void GeneratorMicroTurbineHeatRecovery_Impl::resetHeatRecoveryRateFunctionofPartLoadRatioCurve() { + bool result = setString(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryRateFunctionofPartLoadRatioCurveName, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::setHeatRecoveryRateFunctionofInletWaterTemperatureCurve(const Curve& curve) { + bool result = setPointer(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryRateFunctionofInletWaterTemperatureCurveName, curve.handle()); + return result; + } + + void GeneratorMicroTurbineHeatRecovery_Impl::resetHeatRecoveryRateFunctionofInletWaterTemperatureCurve() { + bool result = setString(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryRateFunctionofInletWaterTemperatureCurveName, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::setHeatRecoveryRateFunctionofWaterFlowRateCurve(const Curve& curve) { + bool result = setPointer(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryRateFunctionofWaterFlowRateCurveName, curve.handle()); + return result; + } + + void GeneratorMicroTurbineHeatRecovery_Impl::resetHeatRecoveryRateFunctionofWaterFlowRateCurve() { + bool result = setString(OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryRateFunctionofWaterFlowRateCurveName, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::setMinimumHeatRecoveryWaterFlowRate(double minimumHeatRecoveryWaterFlowRate) { + bool result = setDouble(OS_Generator_MicroTurbine_HeatRecoveryFields::MinimumHeatRecoveryWaterFlowRate, minimumHeatRecoveryWaterFlowRate); + return result; + } + + void GeneratorMicroTurbineHeatRecovery_Impl::resetMinimumHeatRecoveryWaterFlowRate() { + bool result = setString(OS_Generator_MicroTurbine_HeatRecoveryFields::MinimumHeatRecoveryWaterFlowRate, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::setMaximumHeatRecoveryWaterFlowRate(double maximumHeatRecoveryWaterFlowRate) { + bool result = setDouble(OS_Generator_MicroTurbine_HeatRecoveryFields::MaximumHeatRecoveryWaterFlowRate, maximumHeatRecoveryWaterFlowRate); + return result; + } + + void GeneratorMicroTurbineHeatRecovery_Impl::resetMaximumHeatRecoveryWaterFlowRate() { + bool result = setString(OS_Generator_MicroTurbine_HeatRecoveryFields::MaximumHeatRecoveryWaterFlowRate, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::setMaximumHeatRecoveryWaterTemperature(double maximumHeatRecoveryWaterTemperature) { + bool result = setDouble(OS_Generator_MicroTurbine_HeatRecoveryFields::MaximumHeatRecoveryWaterTemperature, maximumHeatRecoveryWaterTemperature); + return result; + } + + void GeneratorMicroTurbineHeatRecovery_Impl::resetMaximumHeatRecoveryWaterTemperature() { + bool result = setString(OS_Generator_MicroTurbine_HeatRecoveryFields::MaximumHeatRecoveryWaterTemperature, ""); + OS_ASSERT(result); + } + + bool GeneratorMicroTurbineHeatRecovery_Impl::setRatedThermaltoElectricalPowerRatio(double ratedThermaltoElectricalPowerRatio) { + bool result = setDouble(OS_Generator_MicroTurbine_HeatRecoveryFields::RatedThermaltoElectricalPowerRatio, ratedThermaltoElectricalPowerRatio); + return result; + } + + void GeneratorMicroTurbineHeatRecovery_Impl::resetRatedThermaltoElectricalPowerRatio() { + bool result = setString(OS_Generator_MicroTurbine_HeatRecoveryFields::RatedThermaltoElectricalPowerRatio, ""); + OS_ASSERT(result); + } + + +} // detail + +// The constructor needs model, and a GeneratorMicroTurbine +GeneratorMicroTurbineHeatRecovery::GeneratorMicroTurbineHeatRecovery( const Model& model, + GeneratorMicroTurbine & mchp ) + : StraightComponent(GeneratorMicroTurbineHeatRecovery::iddObjectType(),model) +{ + + // Set object in parent + mchp.getImpl()->setGeneratorMicroTurbineHeatRecovery((*this)); + //mchp.setGeneratorMicroTurbineHeatRecovery( (*this) ); + + // Set the Name to mchp.name + " Heat Recovery" + if (OptionalString parentName = mchp.name()) { + setName( (*parentName) + " Heat Recovery"); + } + + // Reference Thermal Efficiency Using Lower Heat Value has a default of 0 in E+ idd which isn't smart in this case + // TODO Should I set it here, or change the .idd?? + // 0.4975 would be better + // Going with Kyle and Mark's way + setReferenceThermalEfficiencyUsingLowerHeatValue(0.4975); + + // Assign all values that are required but have no default + + // Reference Inlet Water Temperature + setReferenceInletWaterTemperature(60); + + // Reference Heat Recovery Water Flow Rate + setReferenceHeatRecoveryWaterFlowRate(0.00252362); + + // Maximum Heat Recovery Water Flow Rate: has a default value of 0 in E+.idd which isn't right in this case + // TODO: Should I set it here or change default in .idd? + // 0.003785432 + // TODO: Or make it an optional and set it to the reference Heat recovery water flow rate times 1.5? + + + +} + +IddObjectType GeneratorMicroTurbineHeatRecovery::iddObjectType() { + return IddObjectType(IddObjectType::OS_Generator_MicroTurbine_HeatRecovery); +} + +std::vector GeneratorMicroTurbineHeatRecovery::validHeatRecoveryWaterFlowOperatingModeValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), + OS_Generator_MicroTurbine_HeatRecoveryFields::HeatRecoveryWaterFlowOperatingMode); +} + + +/* +boost::optional GeneratorMicroTurbineHeatRecovery::heatRecoveryWaterInletNode() const { + return getImpl()->heatRecoveryWaterInletNode(); +} + +boost::optional GeneratorMicroTurbineHeatRecovery::heatRecoveryWaterOutletNode() const { + return getImpl()->heatRecoveryWaterOutletNode(); +} +*/ + +double GeneratorMicroTurbineHeatRecovery::referenceThermalEfficiencyUsingLowerHeatValue() const { + return getImpl()->referenceThermalEfficiencyUsingLowerHeatValue(); +} + +bool GeneratorMicroTurbineHeatRecovery::isReferenceThermalEfficiencyUsingLowerHeatValueDefaulted() const { + return getImpl()->isReferenceThermalEfficiencyUsingLowerHeatValueDefaulted(); +} + +double GeneratorMicroTurbineHeatRecovery::referenceInletWaterTemperature() const { + return getImpl()->referenceInletWaterTemperature(); +} + +std::string GeneratorMicroTurbineHeatRecovery::heatRecoveryWaterFlowOperatingMode() const { + return getImpl()->heatRecoveryWaterFlowOperatingMode(); +} + +bool GeneratorMicroTurbineHeatRecovery::isHeatRecoveryWaterFlowOperatingModeDefaulted() const { + return getImpl()->isHeatRecoveryWaterFlowOperatingModeDefaulted(); +} + +double GeneratorMicroTurbineHeatRecovery::referenceHeatRecoveryWaterFlowRate() const { + return getImpl()->referenceHeatRecoveryWaterFlowRate(); +} + +boost::optional GeneratorMicroTurbineHeatRecovery::heatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve() const { + return getImpl()->heatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve(); +} + +boost::optional GeneratorMicroTurbineHeatRecovery::thermalEfficiencyFunctionofTemperatureandElevationCurve() const { + return getImpl()->thermalEfficiencyFunctionofTemperatureandElevationCurve(); +} + +boost::optional GeneratorMicroTurbineHeatRecovery::heatRecoveryRateFunctionofPartLoadRatioCurve() const { + return getImpl()->heatRecoveryRateFunctionofPartLoadRatioCurve(); +} + +boost::optional GeneratorMicroTurbineHeatRecovery::heatRecoveryRateFunctionofInletWaterTemperatureCurve() const { + return getImpl()->heatRecoveryRateFunctionofInletWaterTemperatureCurve(); +} + +boost::optional GeneratorMicroTurbineHeatRecovery::heatRecoveryRateFunctionofWaterFlowRateCurve() const { + return getImpl()->heatRecoveryRateFunctionofWaterFlowRateCurve(); +} + +double GeneratorMicroTurbineHeatRecovery::minimumHeatRecoveryWaterFlowRate() const { + return getImpl()->minimumHeatRecoveryWaterFlowRate(); +} + +bool GeneratorMicroTurbineHeatRecovery::isMinimumHeatRecoveryWaterFlowRateDefaulted() const { + return getImpl()->isMinimumHeatRecoveryWaterFlowRateDefaulted(); +} + +double GeneratorMicroTurbineHeatRecovery::maximumHeatRecoveryWaterFlowRate() const { + return getImpl()->maximumHeatRecoveryWaterFlowRate(); +} + +bool GeneratorMicroTurbineHeatRecovery::isMaximumHeatRecoveryWaterFlowRateDefaulted() const { + return getImpl()->isMaximumHeatRecoveryWaterFlowRateDefaulted(); +} + +boost::optional GeneratorMicroTurbineHeatRecovery::maximumHeatRecoveryWaterTemperature() const { + return getImpl()->maximumHeatRecoveryWaterTemperature(); +} + +double GeneratorMicroTurbineHeatRecovery::ratedThermaltoElectricalPowerRatio() const { + return getImpl()->ratedThermaltoElectricalPowerRatio(); +} + +bool GeneratorMicroTurbineHeatRecovery::isRatedThermaltoElectricalPowerRatioDefaulted() const { + return getImpl()->isRatedThermaltoElectricalPowerRatioDefaulted(); +} + +GeneratorMicroTurbine GeneratorMicroTurbineHeatRecovery::generatorMicroTurbine() const { + return getImpl()->generatorMicroTurbine(); +} + +/* +bool GeneratorMicroTurbineHeatRecovery::setHeatRecoveryWaterInletNode(const Connection& connection) { + return getImpl()->setHeatRecoveryWaterInletNode(connection); +} + +void GeneratorMicroTurbineHeatRecovery::resetHeatRecoveryWaterInletNode() { + getImpl()->resetHeatRecoveryWaterInletNode(); +} + +bool GeneratorMicroTurbineHeatRecovery::setHeatRecoveryWaterOutletNode(const Connection& connection) { + return getImpl()->setHeatRecoveryWaterOutletNode(connection); +} + +void GeneratorMicroTurbineHeatRecovery::resetHeatRecoveryWaterOutletNode() { + getImpl()->resetHeatRecoveryWaterOutletNode(); +} */ + +bool GeneratorMicroTurbineHeatRecovery::setReferenceThermalEfficiencyUsingLowerHeatValue(double referenceThermalEfficiencyUsingLowerHeatValue) { + return getImpl()->setReferenceThermalEfficiencyUsingLowerHeatValue(referenceThermalEfficiencyUsingLowerHeatValue); +} + +void GeneratorMicroTurbineHeatRecovery::resetReferenceThermalEfficiencyUsingLowerHeatValue() { + getImpl()->resetReferenceThermalEfficiencyUsingLowerHeatValue(); +} + +bool GeneratorMicroTurbineHeatRecovery::setReferenceInletWaterTemperature(double value) { + return getImpl()->setReferenceInletWaterTemperature(value); +} + +bool GeneratorMicroTurbineHeatRecovery::setHeatRecoveryWaterFlowOperatingMode(std::string heatRecoveryWaterFlowOperatingMode) { + return getImpl()->setHeatRecoveryWaterFlowOperatingMode(heatRecoveryWaterFlowOperatingMode); +} + +void GeneratorMicroTurbineHeatRecovery::resetHeatRecoveryWaterFlowOperatingMode() { + getImpl()->resetHeatRecoveryWaterFlowOperatingMode(); +} + +bool GeneratorMicroTurbineHeatRecovery::setReferenceHeatRecoveryWaterFlowRate(double value) { + return getImpl()->setReferenceHeatRecoveryWaterFlowRate(value); +} + +bool GeneratorMicroTurbineHeatRecovery::setHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve(const Curve& curve) { + return getImpl()->setHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve(curve); +} + +void GeneratorMicroTurbineHeatRecovery::resetHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve() { + getImpl()->resetHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve(); +} + +bool GeneratorMicroTurbineHeatRecovery::setThermalEfficiencyFunctionofTemperatureandElevationCurve(const Curve& curve) { + return getImpl()->setThermalEfficiencyFunctionofTemperatureandElevationCurve(curve); +} + +void GeneratorMicroTurbineHeatRecovery::resetThermalEfficiencyFunctionofTemperatureandElevationCurve() { + getImpl()->resetThermalEfficiencyFunctionofTemperatureandElevationCurve(); +} + +bool GeneratorMicroTurbineHeatRecovery::setHeatRecoveryRateFunctionofPartLoadRatioCurve(const Curve& curve) { + return getImpl()->setHeatRecoveryRateFunctionofPartLoadRatioCurve(curve); +} + +void GeneratorMicroTurbineHeatRecovery::resetHeatRecoveryRateFunctionofPartLoadRatioCurve() { + getImpl()->resetHeatRecoveryRateFunctionofPartLoadRatioCurve(); +} + +bool GeneratorMicroTurbineHeatRecovery::setHeatRecoveryRateFunctionofInletWaterTemperatureCurve(const Curve& curve) { + return getImpl()->setHeatRecoveryRateFunctionofInletWaterTemperatureCurve(curve); +} + +void GeneratorMicroTurbineHeatRecovery::resetHeatRecoveryRateFunctionofInletWaterTemperatureCurve() { + getImpl()->resetHeatRecoveryRateFunctionofInletWaterTemperatureCurve(); +} + +bool GeneratorMicroTurbineHeatRecovery::setHeatRecoveryRateFunctionofWaterFlowRateCurve(const Curve& curve) { + return getImpl()->setHeatRecoveryRateFunctionofWaterFlowRateCurve(curve); +} + +void GeneratorMicroTurbineHeatRecovery::resetHeatRecoveryRateFunctionofWaterFlowRateCurve() { + getImpl()->resetHeatRecoveryRateFunctionofWaterFlowRateCurve(); +} + +bool GeneratorMicroTurbineHeatRecovery::setMinimumHeatRecoveryWaterFlowRate(double minimumHeatRecoveryWaterFlowRate) { + return getImpl()->setMinimumHeatRecoveryWaterFlowRate(minimumHeatRecoveryWaterFlowRate); +} + +void GeneratorMicroTurbineHeatRecovery::resetMinimumHeatRecoveryWaterFlowRate() { + getImpl()->resetMinimumHeatRecoveryWaterFlowRate(); +} + +bool GeneratorMicroTurbineHeatRecovery::setMaximumHeatRecoveryWaterFlowRate(double maximumHeatRecoveryWaterFlowRate) { + return getImpl()->setMaximumHeatRecoveryWaterFlowRate(maximumHeatRecoveryWaterFlowRate); +} + +void GeneratorMicroTurbineHeatRecovery::resetMaximumHeatRecoveryWaterFlowRate() { + getImpl()->resetMaximumHeatRecoveryWaterFlowRate(); +} + +bool GeneratorMicroTurbineHeatRecovery::setMaximumHeatRecoveryWaterTemperature(double maximumHeatRecoveryWaterTemperature) { + return getImpl()->setMaximumHeatRecoveryWaterTemperature(maximumHeatRecoveryWaterTemperature); +} + +void GeneratorMicroTurbineHeatRecovery::resetMaximumHeatRecoveryWaterTemperature() { + getImpl()->resetMaximumHeatRecoveryWaterTemperature(); +} + +bool GeneratorMicroTurbineHeatRecovery::setRatedThermaltoElectricalPowerRatio(double ratedThermaltoElectricalPowerRatio) { + return getImpl()->setRatedThermaltoElectricalPowerRatio(ratedThermaltoElectricalPowerRatio); +} + +void GeneratorMicroTurbineHeatRecovery::resetRatedThermaltoElectricalPowerRatio() { + getImpl()->resetRatedThermaltoElectricalPowerRatio(); +} + +/// @cond +GeneratorMicroTurbineHeatRecovery::GeneratorMicroTurbineHeatRecovery(std::shared_ptr impl) + : StraightComponent(impl) +{} +/// @endcond + +} // model +} // openstudio + diff --git a/openstudiocore/src/model/GeneratorMicroTurbineHeatRecovery.hpp b/openstudiocore/src/model/GeneratorMicroTurbineHeatRecovery.hpp new file mode 100644 index 00000000000..40c90b478d1 --- /dev/null +++ b/openstudiocore/src/model/GeneratorMicroTurbineHeatRecovery.hpp @@ -0,0 +1,191 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#ifndef MODEL_GENERATORMICROTURBINEHEATRECOVERY_HPP +#define MODEL_GENERATORMICROTURBINEHEATRECOVERY_HPP + +#include +#include "StraightComponent.hpp" + + +namespace openstudio { +namespace model { + +// TODO: Check the following class names against object getters and setters. +class Curve; +class GeneratorMicroTurbine; + +namespace detail { + + class GeneratorMicroTurbineHeatRecovery_Impl; + +} // detail + +/** GeneratorMicroTurbineHeatRecovery is a StraightComponent that wraps the OpenStudio IDD object 'OS:Generator:MicroTurbine:HeatRecovery'. */ +class MODEL_API GeneratorMicroTurbineHeatRecovery : public StraightComponent { + public: + /** @name Constructors and Destructors */ + //@{ + + // Constructs a new GeneratorMicroTurbineHeatRecovery object in the model, given a GeneratorMicroTurbine + explicit GeneratorMicroTurbineHeatRecovery( const Model& model, + GeneratorMicroTurbine & mchp ); + + virtual ~GeneratorMicroTurbineHeatRecovery() {} + + //@} + + static IddObjectType iddObjectType(); + + static std::vector validHeatRecoveryWaterFlowOperatingModeValues(); + + /** @name Getters */ + //@{ + + // TODO: Check return type. From object lists, some candidates are: Connection. + // boost::optional heatRecoveryWaterInletNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + // boost::optional heatRecoveryWaterOutletNode() const; + + double referenceThermalEfficiencyUsingLowerHeatValue() const; + bool isReferenceThermalEfficiencyUsingLowerHeatValueDefaulted() const; + + double referenceInletWaterTemperature() const; + + std::string heatRecoveryWaterFlowOperatingMode() const; + bool isHeatRecoveryWaterFlowOperatingModeDefaulted() const; + + double referenceHeatRecoveryWaterFlowRate() const; + + // TODO: Check return type. From object lists, some candidates are: BiquadraticCurves, BiVariateTables. + boost::optional heatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve() const; + + // TODO: Check return type. From object lists, some candidates are: BicubicBiquadraticCurves, BiVariateTables. + boost::optional thermalEfficiencyFunctionofTemperatureandElevationCurve() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + boost::optional heatRecoveryRateFunctionofPartLoadRatioCurve() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCurves, UniVariateTables. + boost::optional heatRecoveryRateFunctionofInletWaterTemperatureCurve() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCurves, UniVariateTables. + boost::optional heatRecoveryRateFunctionofWaterFlowRateCurve() const; + + double minimumHeatRecoveryWaterFlowRate() const; + bool isMinimumHeatRecoveryWaterFlowRateDefaulted() const; + + double maximumHeatRecoveryWaterFlowRate() const; + bool isMaximumHeatRecoveryWaterFlowRateDefaulted() const; + + boost::optional maximumHeatRecoveryWaterTemperature() const; + + double ratedThermaltoElectricalPowerRatio() const; + bool isRatedThermaltoElectricalPowerRatioDefaulted() const; + + // Return optional parent generator + GeneratorMicroTurbine generatorMicroTurbine() const; + + //@} + /** @name Setters */ + //@{ + + // TODO: Check argument type. From object lists, some candidates are: Connection. + //bool setHeatRecoveryWaterInletNode(const Connection& connection); + //void resetHeatRecoveryWaterInletNode(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + //bool setHeatRecoveryWaterOutletNode(const Connection& connection); + //void resetHeatRecoveryWaterOutletNode(); + + bool setReferenceThermalEfficiencyUsingLowerHeatValue(double referenceThermalEfficiencyUsingLowerHeatValue); + void resetReferenceThermalEfficiencyUsingLowerHeatValue(); + + bool setReferenceInletWaterTemperature(double referenceInletWaterTemperature); + + bool setHeatRecoveryWaterFlowOperatingMode(std::string heatRecoveryWaterFlowOperatingMode); + void resetHeatRecoveryWaterFlowOperatingMode(); + + bool setReferenceHeatRecoveryWaterFlowRate(double referenceHeatRecoveryWaterFlowRate); + //void resetReferenceHeatRecoveryWaterFlowRate(); + + // TODO: Check argument type. From object lists, some candidates are: BiquadraticCurves, BiVariateTables. + bool setHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve(const Curve& heatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve); + void resetHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve(); + + // TODO: Check argument type. From object lists, some candidates are: BicubicBiquadraticCurves, BiVariateTables. + bool setThermalEfficiencyFunctionofTemperatureandElevationCurve(const Curve& thermalEfficiencyFunctionofTemperatureandElevationCurve); + void resetThermalEfficiencyFunctionofTemperatureandElevationCurve(); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + bool setHeatRecoveryRateFunctionofPartLoadRatioCurve(const Curve& heatRecoveryRateFunctionofPartLoadRatioCurve); + void resetHeatRecoveryRateFunctionofPartLoadRatioCurve(); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCurves, UniVariateTables. + bool setHeatRecoveryRateFunctionofInletWaterTemperatureCurve(const Curve& heatRecoveryRateFunctionofInletWaterTemperatureCurve); + void resetHeatRecoveryRateFunctionofInletWaterTemperatureCurve(); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCurves, UniVariateTables. + bool setHeatRecoveryRateFunctionofWaterFlowRateCurve(const Curve& heatRecoveryRateFunctionofWaterFlowRateCurve); + void resetHeatRecoveryRateFunctionofWaterFlowRateCurve(); + + bool setMinimumHeatRecoveryWaterFlowRate(double minimumHeatRecoveryWaterFlowRate); + void resetMinimumHeatRecoveryWaterFlowRate(); + + bool setMaximumHeatRecoveryWaterFlowRate(double maximumHeatRecoveryWaterFlowRate); + void resetMaximumHeatRecoveryWaterFlowRate(); + + bool setMaximumHeatRecoveryWaterTemperature(double maximumHeatRecoveryWaterTemperature); + void resetMaximumHeatRecoveryWaterTemperature(); + + bool setRatedThermaltoElectricalPowerRatio(double ratedThermaltoElectricalPowerRatio); + void resetRatedThermaltoElectricalPowerRatio(); + + //@} + /** @name Other */ + //@{ + + //@} + protected: + /// @cond + typedef detail::GeneratorMicroTurbineHeatRecovery_Impl ImplType; + + explicit GeneratorMicroTurbineHeatRecovery(std::shared_ptr impl); + + friend class detail::GeneratorMicroTurbineHeatRecovery_Impl; + friend class Model; + friend class IdfObject; + friend class openstudio::detail::IdfObject_Impl; + /// @endcond + private: + REGISTER_LOGGER("openstudio.model.GeneratorMicroTurbineHeatRecovery"); +}; + +/** \relates GeneratorMicroTurbineHeatRecovery*/ +typedef boost::optional OptionalGeneratorMicroTurbineHeatRecovery; + +/** \relates GeneratorMicroTurbineHeatRecovery*/ +typedef std::vector GeneratorMicroTurbineHeatRecoveryVector; + +} // model +} // openstudio + +#endif // MODEL_GENERATORMICROTURBINEHEATRECOVERY_HPP + diff --git a/openstudiocore/src/model/GeneratorMicroTurbineHeatRecovery_Impl.hpp b/openstudiocore/src/model/GeneratorMicroTurbineHeatRecovery_Impl.hpp new file mode 100644 index 00000000000..21db64f5512 --- /dev/null +++ b/openstudiocore/src/model/GeneratorMicroTurbineHeatRecovery_Impl.hpp @@ -0,0 +1,198 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#ifndef MODEL_GENERATORMICROTURBINEHEATRECOVERY_IMPL_HPP +#define MODEL_GENERATORMICROTURBINEHEATRECOVERY_IMPL_HPP + +#include "ModelAPI.hpp" +#include "StraightComponent_Impl.hpp" + +namespace openstudio { +namespace model { + +// TODO: Check the following class names against object getters and setters. +class Curve; +class GeneratorMicroTurbine; + +namespace detail { + + class MODEL_API GeneratorMicroTurbineHeatRecovery_Impl : public StraightComponent_Impl { + + public: + /** @name Constructors and Destructors */ + //@{ + + GeneratorMicroTurbineHeatRecovery_Impl(const IdfObject& idfObject, + Model_Impl* model, + bool keepHandle); + + GeneratorMicroTurbineHeatRecovery_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, + bool keepHandle); + + GeneratorMicroTurbineHeatRecovery_Impl(const GeneratorMicroTurbineHeatRecovery_Impl& other, + Model_Impl* model, + bool keepHandle); + + virtual ~GeneratorMicroTurbineHeatRecovery_Impl() {} + + //@} + /** @name Virtual Methods */ + //@{ + + virtual const std::vector& outputVariableNames() const; + + virtual IddObjectType iddObjectType() const; + + virtual unsigned inletPort() override; + + virtual unsigned outletPort() override; + + // TODO: I think this should be virtual bool since it's defined in both HVACcomponent and StraightComponent. @Kyle? + virtual bool addToNode(Node & node) override; + + // DLM: consider reimplementing any other virtual methods of StraightComponent or HVACComponent + + //@} + /** @name Getters */ + //@{ + + //boost::optional heatRecoveryWaterInletNode() const; + + //boost::optional heatRecoveryWaterOutletNode() const; + + // TODO: I might need to make this one default to something that makes sense... + double referenceThermalEfficiencyUsingLowerHeatValue() const; + bool isReferenceThermalEfficiencyUsingLowerHeatValueDefaulted() const; + + double referenceInletWaterTemperature() const; + + std::string heatRecoveryWaterFlowOperatingMode() const; + bool isHeatRecoveryWaterFlowOperatingModeDefaulted() const; + + double referenceHeatRecoveryWaterFlowRate() const; + + // BiquadraticCurves, BiVariateTables. + boost::optional heatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve() const; + + // BicubicBiquadraticCurves, BiVariateTables. + boost::optional thermalEfficiencyFunctionofTemperatureandElevationCurve() const; + + // QuadraticCubicCurves, UniVariateTables. + boost::optional heatRecoveryRateFunctionofPartLoadRatioCurve() const; + + //QuadraticCurves, UniVariateTables. + boost::optional heatRecoveryRateFunctionofInletWaterTemperatureCurve() const; + + // QuadraticCurves, UniVariateTables. + boost::optional heatRecoveryRateFunctionofWaterFlowRateCurve() const; + + double minimumHeatRecoveryWaterFlowRate() const; + bool isMinimumHeatRecoveryWaterFlowRateDefaulted() const; + + double maximumHeatRecoveryWaterFlowRate() const; + bool isMaximumHeatRecoveryWaterFlowRateDefaulted() const; + + boost::optional maximumHeatRecoveryWaterTemperature() const; + + double ratedThermaltoElectricalPowerRatio() const; + bool isRatedThermaltoElectricalPowerRatioDefaulted() const; + + // Return optional parent generator + GeneratorMicroTurbine generatorMicroTurbine() const; + + //@} + /** @name Setters */ + //@{ + + // TODO: Check argument type. From object lists, some candidates are: Connection. + //bool setHeatRecoveryWaterInletNode(const Connection& connection); + //void resetHeatRecoveryWaterInletNode(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + //bool setHeatRecoveryWaterOutletNode(const Connection& connection); + //void resetHeatRecoveryWaterOutletNode(); + + bool setReferenceThermalEfficiencyUsingLowerHeatValue(double referenceThermalEfficiencyUsingLowerHeatValue); + void resetReferenceThermalEfficiencyUsingLowerHeatValue(); + + bool setReferenceInletWaterTemperature(double referenceInletWaterTemperature); + + bool setHeatRecoveryWaterFlowOperatingMode(std::string heatRecoveryWaterFlowOperatingMode); + void resetHeatRecoveryWaterFlowOperatingMode(); + + bool setReferenceHeatRecoveryWaterFlowRate(double referenceHeatRecoveryWaterFlowRate); + + // BiquadraticCurves, BiVariateTables. + bool setHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve(const Curve& heatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve); + void resetHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve(); + + // BicubicBiquadraticCurves, BiVariateTables. + bool setThermalEfficiencyFunctionofTemperatureandElevationCurve(const Curve& thermalEfficiencyFunctionofTemperatureandElevationCurve); + void resetThermalEfficiencyFunctionofTemperatureandElevationCurve(); + + // QuadraticCubicCurves, UniVariateTables. + bool setHeatRecoveryRateFunctionofPartLoadRatioCurve(const Curve& heatRecoveryRateFunctionofPartLoadRatioCurve); + void resetHeatRecoveryRateFunctionofPartLoadRatioCurve(); + + // QuadraticCurves, UniVariateTables. + bool setHeatRecoveryRateFunctionofInletWaterTemperatureCurve(const Curve& heatRecoveryRateFunctionofInletWaterTemperatureCurve); + void resetHeatRecoveryRateFunctionofInletWaterTemperatureCurve(); + + // QuadraticCurves, UniVariateTables. + bool setHeatRecoveryRateFunctionofWaterFlowRateCurve(const Curve& heatRecoveryRateFunctionofWaterFlowRateCurve); + void resetHeatRecoveryRateFunctionofWaterFlowRateCurve(); + + bool setMinimumHeatRecoveryWaterFlowRate(double minimumHeatRecoveryWaterFlowRate); + void resetMinimumHeatRecoveryWaterFlowRate(); + + bool setMaximumHeatRecoveryWaterFlowRate(double maximumHeatRecoveryWaterFlowRate); + void resetMaximumHeatRecoveryWaterFlowRate(); + + bool setMaximumHeatRecoveryWaterTemperature(double maximumHeatRecoveryWaterTemperature); + void resetMaximumHeatRecoveryWaterTemperature(); + + bool setRatedThermaltoElectricalPowerRatio(double ratedThermaltoElectricalPowerRatio); + void resetRatedThermaltoElectricalPowerRatio(); + + + //@} + /** @name Other */ + //@{ + + ModelObject clone(Model model) const override; + + std::vector allowableChildTypes() const override; + + std::vector children() const override; + + //@} + protected: + private: + REGISTER_LOGGER("openstudio.model.GeneratorMicroTurbineHeatRecovery"); + + }; + +} // detail + +} // model +} // openstudio + +#endif // MODEL_GENERATORMICROTURBINEHEATRECOVERY_IMPL_HPP + diff --git a/openstudiocore/src/model/GeneratorMicroTurbine_Impl.hpp b/openstudiocore/src/model/GeneratorMicroTurbine_Impl.hpp new file mode 100644 index 00000000000..839b505eedb --- /dev/null +++ b/openstudiocore/src/model/GeneratorMicroTurbine_Impl.hpp @@ -0,0 +1,266 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#ifndef MODEL_GENERATORMICROTURBINE_IMPL_HPP +#define MODEL_GENERATORMICROTURBINE_IMPL_HPP + +#include +#include "Generator_Impl.hpp" +#include "GeneratorMicroTurbineHeatRecovery_Impl.hpp" + +namespace openstudio { +namespace model { + +class Curve; +// For the optional Generator:MicroTurbine:HeatRecovery +// It was broken out because that part needs to connect to a plant loop +class StraightComponent; + +// TODO: add the tables class if they get added to OS later? +//class DataTables // UniVariateTables and BiVariateTables + +namespace detail { + + /** GeneratorMicroTurbine_Impl is a Generator_Impl that is the implementation class for GeneratorMicroTurbine.*/ + class MODEL_API GeneratorMicroTurbine_Impl : public Generator_Impl { + + public: + /** @name Constructors and Destructors */ + //@{ + + GeneratorMicroTurbine_Impl(const IdfObject& idfObject, + Model_Impl* model, + bool keepHandle); + + GeneratorMicroTurbine_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, + bool keepHandle); + + GeneratorMicroTurbine_Impl(const GeneratorMicroTurbine_Impl& other, + Model_Impl* model, + bool keepHandle); + + virtual ~GeneratorMicroTurbine_Impl() {} + + //@} + /** @name Virtual Methods */ + //@{ + + virtual const std::vector& outputVariableNames() const; + + virtual IddObjectType iddObjectType() const; + + virtual std::vector getScheduleTypeKeys(const Schedule& schedule) const override; + + virtual std::string generatorObjectType() const; + + virtual boost::optional ratedElectricPowerOutput() const; + + virtual boost::optional availabilitySchedule() const override; + + virtual boost::optional ratedThermaltoElectricalPowerRatio() const override; + + //@} + /** @name Getters */ + //@{ + + double referenceElectricalPowerOutput() const; + + double minimumFullLoadElectricalPowerOutput() const; + bool isMinimumFullLoadElectricalPowerOutputDefaulted() const; + + // This will default to referenceElectricalPowerOutput if not defined, like E+ does + double maximumFullLoadElectricalPowerOutput() const; + bool isMaximumFullLoadElectricalPowerOutputDefaulted() const; + + double referenceElectricalEfficiencyUsingLowerHeatingValue() const; + + double referenceCombustionAirInletTemperature() const; + bool isReferenceCombustionAirInletTemperatureDefaulted() const; + + double referenceCombustionAirInletHumidityRatio() const; + bool isReferenceCombustionAirInletHumidityRatioDefaulted() const; + + double referenceElevation() const; + bool isReferenceElevationDefaulted() const; + + // TODO: Check return type. From object lists, some candidates are: BiquadraticCurves, BiVariateTables. + Curve electricalPowerFunctionofTemperatureandElevationCurve() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCubicCurves. + Curve electricalEfficiencyFunctionofTemperatureCurve() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCubicCurves. + Curve electricalEfficiencyFunctionofPartLoadRatioCurve() const; + + std::string fuelType() const; + bool isFuelTypeDefaulted() const; + + double fuelHigherHeatingValue() const; + bool isFuelHigherHeatingValueDefaulted() const; + + double fuelLowerHeatingValue() const; + bool isFuelLowerHeatingValueDefaulted() const; + + double standbyPower() const; + bool isStandbyPowerDefaulted() const; + + double ancillaryPower() const; + bool isAncillaryPowerDefaulted() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCurves, UniVariateTables. + boost::optional ancillaryPowerFunctionofFuelInputCurve() const; + + // Optional Generator:MicroTurbine:HeatRecovery + boost::optional generatorMicroTurbineHeatRecovery() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + //boost::optional combustionAirInletNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + //boost::optional combustionAirOutletNode() const; + + boost::optional referenceExhaustAirMassFlowRate() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + boost::optional exhaustAirFlowRateFunctionofTemperatureCurve() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + boost::optional exhaustAirFlowRateFunctionofPartLoadRatioCurve() const; + + boost::optional nominalExhaustAirOutletTemperature() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + boost::optional exhaustAirTemperatureFunctionofTemperatureCurve() const; + + // TODO: Check return type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + boost::optional exhaustAirTemperatureFunctionofPartLoadRatioCurve() const; + + //@} + /** @name Setters */ + //@{ + + bool setAvailabilitySchedule(Schedule& schedule); + void resetAvailabilitySchedule(); + + bool setReferenceElectricalPowerOutput(double referenceElectricalPowerOutput); + + bool setMinimumFullLoadElectricalPowerOutput(double minimumFullLoadElectricalPowerOutput); + void resetMinimumFullLoadElectricalPowerOutput(); + + bool setMaximumFullLoadElectricalPowerOutput(double maximumFullLoadElectricalPowerOutput); + void resetMaximumFullLoadElectricalPowerOutput(); + + bool setReferenceElectricalEfficiencyUsingLowerHeatingValue(double referenceElectricalEfficiencyUsingLowerHeatingValue); + + void setReferenceCombustionAirInletTemperature(double referenceCombustionAirInletTemperature); + void resetReferenceCombustionAirInletTemperature(); + + bool setReferenceCombustionAirInletHumidityRatio(double referenceCombustionAirInletHumidityRatio); + void resetReferenceCombustionAirInletHumidityRatio(); + + bool setReferenceElevation(double referenceElevation); + void resetReferenceElevation(); + + // TODO: Check argument type. From object lists, some candidates are: BiquadraticCurves, BiVariateTables. + bool setElectricalPowerFunctionofTemperatureandElevationCurve(const Curve& electricalPowerFunctionofTemperatureandElevationCurve); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCubicCurves. + bool setElectricalEfficiencyFunctionofTemperatureCurve(const Curve& electricalEfficiencyFunctionofTemperatureCurve); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCubicCurves. + bool setElectricalEfficiencyFunctionofPartLoadRatioCurve(const Curve& electricalEfficiencyFunctionofPartLoadRatioCurve); + + bool setFuelType(const std::string& fuelType); + void resetFuelType(); + + bool setFuelHigherHeatingValue(double fuelHigherHeatingValue); + void resetFuelHigherHeatingValue(); + + bool setFuelLowerHeatingValue(double fuelLowerHeatingValue); + void resetFuelLowerHeatingValue(); + + bool setStandbyPower(double standbyPower); + void resetStandbyPower(); + + bool setAncillaryPower(double ancillaryPower); + void resetAncillaryPower(); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCurves, UniVariateTables. + bool setAncillaryPowerFunctionofFuelInputCurve(const Curve& ancillaryPowerFunctionofFuelInputCurve); + void resetAncillaryPowerFunctionofFuelInputCurve(); + + // Private setter + bool setGeneratorMicroTurbineHeatRecovery(const GeneratorMicroTurbineHeatRecovery& generatorMicroTurbineHeatRecovery); + //void resetGeneratorMicroTurbineHeatRecovery(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + //bool setCombustionAirInletNode(const Connection& connection); + //void resetCombustionAirInletNode(); + + // TODO: Check argument type. From object lists, some candidates are: Connection. + //bool setCombustionAirOutletNode(const Connection& connection); + //void resetCombustionAirOutletNode(); + + bool setReferenceExhaustAirMassFlowRate(double referenceExhaustAirMassFlowRate); + void resetReferenceExhaustAirMassFlowRate(); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + bool setExhaustAirFlowRateFunctionofTemperatureCurve(const Curve& exhaustAirFlowRateFunctionofTemperatureCurve); + void resetExhaustAirFlowRateFunctionofTemperatureCurve(); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + bool setExhaustAirFlowRateFunctionofPartLoadRatioCurve(const Curve& exhaustAirFlowRateFunctionofPartLoadRatioCurve); + void resetExhaustAirFlowRateFunctionofPartLoadRatioCurve(); + + void setNominalExhaustAirOutletTemperature(double nominalExhaustAirOutletTemperature); + void resetNominalExhaustAirOutletTemperature(); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + bool setExhaustAirTemperatureFunctionofTemperatureCurve(const Curve& exhaustAirTemperatureFunctionofTemperatureCurve); + void resetExhaustAirTemperatureFunctionofTemperatureCurve(); + + // TODO: Check argument type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + bool setExhaustAirTemperatureFunctionofPartLoadRatioCurve(const Curve& exhaustAirTemperatureFunctionofPartLoadRatioCurve); + void resetExhaustAirTemperatureFunctionofPartLoadRatioCurve(); + + //@} + /** @name Other */ + //@{ + + ModelObject clone(Model model) const override; + + std::vector allowableChildTypes() const override; + + std::vector children() const override; + + //@} + protected: + private: + REGISTER_LOGGER("openstudio.model.GeneratorMicroTurbine"); + + }; + +} // detail + +} // model +} // openstudio + +#endif // MODEL_GENERATORMICROTURBINE_IMPL_HPP + diff --git a/openstudiocore/src/model/GeneratorPhotovoltaic.cpp b/openstudiocore/src/model/GeneratorPhotovoltaic.cpp index 634de14e907..9960a9c61f8 100644 --- a/openstudiocore/src/model/GeneratorPhotovoltaic.cpp +++ b/openstudiocore/src/model/GeneratorPhotovoltaic.cpp @@ -136,7 +136,7 @@ namespace detail { return "Generator:Photovoltaic"; } - boost::optional GeneratorPhotovoltaic_Impl::ratedThermalToElectricalPowerRatio() const + boost::optional GeneratorPhotovoltaic_Impl::ratedThermaltoElectricalPowerRatio() const { return boost::none; } diff --git a/openstudiocore/src/model/GeneratorPhotovoltaic_Impl.hpp b/openstudiocore/src/model/GeneratorPhotovoltaic_Impl.hpp index 5e4aaec081a..5e496f2152a 100644 --- a/openstudiocore/src/model/GeneratorPhotovoltaic_Impl.hpp +++ b/openstudiocore/src/model/GeneratorPhotovoltaic_Impl.hpp @@ -82,7 +82,7 @@ namespace detail { virtual boost::optional availabilitySchedule() const override; - virtual boost::optional ratedThermalToElectricalPowerRatio() const override; + virtual boost::optional ratedThermaltoElectricalPowerRatio() const override; //@} /** @name Getters */ diff --git a/openstudiocore/src/model/Generator_Impl.hpp b/openstudiocore/src/model/Generator_Impl.hpp index 13d94f3b386..1b686c3f797 100644 --- a/openstudiocore/src/model/Generator_Impl.hpp +++ b/openstudiocore/src/model/Generator_Impl.hpp @@ -57,7 +57,7 @@ namespace detail { virtual boost::optional availabilitySchedule() const = 0; - virtual boost::optional ratedThermalToElectricalPowerRatio() const = 0; + virtual boost::optional ratedThermaltoElectricalPowerRatio() const = 0; //@} /** @name Getters */ diff --git a/openstudiocore/src/model/MaterialPropertyGlazingSpectralData_Impl.hpp b/openstudiocore/src/model/MaterialPropertyGlazingSpectralData_Impl.hpp index cba6b8640ca..da29e3be1ff 100644 --- a/openstudiocore/src/model/MaterialPropertyGlazingSpectralData_Impl.hpp +++ b/openstudiocore/src/model/MaterialPropertyGlazingSpectralData_Impl.hpp @@ -32,8 +32,8 @@ namespace detail { /** MaterialPropertyGlazingSpectralData_Impl is a ResourceObject_Impl that is the implementation class for MaterialPropertyGlazingSpectralData.*/ class MODEL_API MaterialPropertyGlazingSpectralData_Impl : public ResourceObject_Impl { - Q_OBJECT; - public: + + public: /** @name Constructors and Destructors */ //@{ diff --git a/openstudiocore/src/model/Meter.cpp b/openstudiocore/src/model/Meter.cpp deleted file mode 100644 index 681a57ab4fa..00000000000 --- a/openstudiocore/src/model/Meter.cpp +++ /dev/null @@ -1,643 +0,0 @@ -/********************************************************************** - * Copyright (c) 2008-2016, Alliance for Sustainable Energy. - * All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - **********************************************************************/ - -#include "Meter.hpp" -#include "Meter_Impl.hpp" - -#include "Model.hpp" -#include "Facility.hpp" -#include "Facility_Impl.hpp" -#include "Building.hpp" -#include "Building_Impl.hpp" - -#include - -#include -#include - -#include "../utilities/data/DataEnums.hpp" -#include "../utilities/data/TimeSeries.hpp" -#include "../utilities/sql/SqlFile.hpp" -#include "../utilities/sql/SqlFileEnums.hpp" -#include "../utilities/core/Assert.hpp" - -#include -#include - -namespace openstudio { -namespace model { - -namespace detail { - - Meter_Impl::Meter_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle) - : ModelObject_Impl(idfObject,model,keepHandle) - { - OS_ASSERT(idfObject.iddObject().type() == Meter::iddObjectType()); - } - - Meter_Impl::Meter_Impl(const openstudio::detail::WorkspaceObject_Impl& other, - Model_Impl* model, - bool keepHandle) - : ModelObject_Impl(other,model,keepHandle) - { - OS_ASSERT(other.iddObject().type() == Meter::iddObjectType()); - } - - Meter_Impl::Meter_Impl(const Meter_Impl& other, - Model_Impl* model, - bool keepHandle) - : ModelObject_Impl(other,model,keepHandle) - {} - - const std::vector& Meter_Impl::outputVariableNames() const - { - static std::vector result; - if (result.empty()){ - } - return result; - } - - IddObjectType Meter_Impl::iddObjectType() const { - return Meter::iddObjectType(); - } - - boost::optional Meter_Impl::parent() const - { - boost::optional result; - boost::optional installLocationType = this->installLocationType(); - if(installLocationType){ - switch (installLocationType->value()){ - case InstallLocationType::Facility: - result = this->model().getOptionalUniqueModelObject(); - break; - case InstallLocationType::Building: - result = this->model().building(); - break; - default: - ; - } - - } - return result; - } - - std::string Meter_Impl::name() const { - boost::optional value = getString(OS_MeterFields::Name,true); - OS_ASSERT(value); - return value.get(); - } - - std::string Meter_Impl::reportingFrequency() const { - boost::optional value = getString(OS_MeterFields::ReportingFrequency,true); - OS_ASSERT(value); - return value.get(); - } - - bool Meter_Impl::isReportingFrequencyDefaulted() const { - return isEmpty(OS_MeterFields::ReportingFrequency); - } - - bool Meter_Impl::meterFileOnly() const { - boost::optional value = getString(OS_MeterFields::MeterFileOnly,true); - OS_ASSERT(value); - return openstudio::istringEqual(value.get(), "True"); - } - - bool Meter_Impl::isMeterFileOnlyDefaulted() const { - return isEmpty(OS_MeterFields::MeterFileOnly); - } - - bool Meter_Impl::cumulative() const { - boost::optional value = getString(OS_MeterFields::Cumulative,true); - OS_ASSERT(value); - return openstudio::istringEqual(value.get(), "True"); - } - - bool Meter_Impl::isCumulativeDefaulted() const { - return isEmpty(OS_MeterFields::Cumulative); - } - - boost::optional Meter_Impl::specificEndUse() const - { - boost::optional result; - std::string myName = name(); - boost::smatch matches; - if (boost::regex_search(myName, matches, Meter::meterRegex())) - { - // match is always true but may be empty - if (matches[1].first != matches[1].second){ - result = std::string(matches[1].first, matches[1].second); - } - } - - return result; - } - - boost::optional Meter_Impl::endUseType() const - { - boost::optional result; - std::string myName = name(); - boost::smatch matches; - if (boost::regex_search(myName, matches, Meter::meterRegex())) - { - if (matches[2].matched){ - result = EndUseType(std::string(matches[2].first, matches[2].second)); - } - } - - return result; - } - - boost::optional Meter_Impl::fuelType() const - { - boost::optional result; - std::string myName = name(); - boost::smatch matches; - if (boost::regex_search(myName, matches, Meter::meterRegex())) - { - if (matches[3].matched){ - result = FuelType(std::string(matches[3].first, matches[3].second)); - } - } - - return result; - } - - boost::optional Meter_Impl::installLocationType() const - { - boost::optional result; - std::string myName = name(); - boost::smatch matches; - if (boost::regex_search(myName, matches, Meter::meterRegex())) - { - if (matches[4].matched){ - result = InstallLocationType(std::string(matches[4].first, matches[4].second)); - } - } - - return result; - } - - boost::optional Meter_Impl::specificInstallLocation() const - { - boost::optional result; - std::string myName = name(); - boost::smatch matches; - if (boost::regex_search(myName, matches, Meter::meterRegex())) - { - // match is always true but may be empty - if (matches[5].first != matches[5].second){ - result = std::string(matches[5].first, matches[5].second); - } - } - - return result; - } - - bool Meter_Impl::setName(std::string name) { - return setString(OS_MeterFields::Name, name); - } - - bool Meter_Impl::setReportingFrequency(const std::string& reportingFrequency) { - return setString(OS_MeterFields::ReportingFrequency, reportingFrequency); - } - - void Meter_Impl::resetReportingFrequency() { - bool result = setString(OS_MeterFields::ReportingFrequency, ""); - OS_ASSERT(result); - } - - void Meter_Impl::setMeterFileOnly(bool meterFileOnly) { - bool result = false; - if (meterFileOnly) { - result = setString(OS_MeterFields::MeterFileOnly, "True"); - } else { - result = setString(OS_MeterFields::MeterFileOnly, "False"); - } - OS_ASSERT(result); - } - - void Meter_Impl::resetMeterFileOnly() { - bool result = setString(OS_MeterFields::MeterFileOnly, ""); - OS_ASSERT(result); - } - - void Meter_Impl::setCumulative(bool cumulative) { - bool result = false; - if (cumulative) { - result = setString(OS_MeterFields::Cumulative, "True"); - } else { - result = setString(OS_MeterFields::Cumulative, "False"); - } - OS_ASSERT(result); - } - - void Meter_Impl::resetCumulative() { - bool result = setString(OS_MeterFields::Cumulative, ""); - OS_ASSERT(result); - } - - bool Meter_Impl::setSpecificEndUse(const std::string& endUse) - { - ModelObject object = getObject(); - - std::string name = Meter::getName(endUse, endUseType(), fuelType(), installLocationType(), specificInstallLocation()); - - bool result = object.setString(OS_MeterFields::Name, name); - if (!result){ - LOG(Error, "Could not set name to '" << name << "'"); - } - - return result; - } - - bool Meter_Impl::resetSpecificEndUse() - { - return setSpecificEndUse(""); - } - - bool Meter_Impl::setEndUseType(EndUseType type) - { - ModelObject object = getObject(); - - std::string name = Meter::getName(specificEndUse(), type, fuelType(), installLocationType(), specificInstallLocation()); - - bool result = object.setString(OS_MeterFields::Name, name); - if (!result){ - LOG(Error, "Could not set name to '" << name << "'"); - } - - return result; - } - - bool Meter_Impl::resetEndUseType() - { - ModelObject object = getObject(); - - std::string name = Meter::getName(specificEndUse(), boost::none, fuelType(), installLocationType(), specificInstallLocation()); - - bool result = object.setString(OS_MeterFields::Name, name); - if (!result){ - LOG(Error, "Could not set name to '" << name << "'"); - } - - return result; - } - - bool Meter_Impl::setFuelType(FuelType type) - { - ModelObject object = getObject(); - - std::string name = Meter::getName(specificEndUse(), endUseType(), type, installLocationType(), specificInstallLocation()); - - bool result = object.setString(OS_MeterFields::Name, name); - if (!result){ - LOG(Error, "Could not set name to '" << name << "'"); - } - - return result; - } - - bool Meter_Impl::resetFuelType() - { - ModelObject object = getObject(); - - std::string name = Meter::getName(specificEndUse(), endUseType(), boost::none, installLocationType(), specificInstallLocation()); - - bool result = object.setString(OS_MeterFields::Name, name); - if (!result){ - LOG(Error, "Could not set name to '" << name << "'"); - } - - return result; - } - - bool Meter_Impl::setInstallLocationType(InstallLocationType type) - { - ModelObject object = getObject(); - - std::string name = Meter::getName(specificEndUse(), endUseType(), fuelType(), type, specificInstallLocation()); - - bool result = object.setString(OS_MeterFields::Name, name); - if (!result){ - LOG(Error, "Could not set name to '" << name << "'"); - } - - return result; - } - - bool Meter_Impl::resetInstallLocationType() - { - ModelObject object = getObject(); - - std::string name = Meter::getName(specificEndUse(), endUseType(), fuelType(), boost::none, specificInstallLocation()); - - bool result = object.setString(OS_MeterFields::Name, name); - if (!result){ - LOG(Error, "Could not set name to '" << name << "'"); - } - - return result; - } - - bool Meter_Impl::setSpecificInstallLocation(const std::string& locationName) - { - ModelObject object = getObject(); - - std::string name = Meter::getName(specificEndUse(), endUseType(), fuelType(), installLocationType(), locationName); - - bool result = object.setString(OS_MeterFields::Name, name); - if (!result){ - LOG(Error, "Could not set name to '" << name << "'"); - } - - return result; - } - - bool Meter_Impl::resetSpecificInstallLocation() - { - return setSpecificInstallLocation(""); - } - - openstudio::OptionalTimeSeries Meter_Impl::getData(const std::string& envPeriod) const - { - return getData(envPeriod, specificInstallLocation()); - } - - openstudio::OptionalTimeSeries Meter_Impl::getData(const std::string& envPeriod, const OptionalString& specificInstallLocation) const - { - openstudio::OptionalTimeSeries result; - OptionalSqlFile sqlFile = model().sqlFile(); - - if (sqlFile){ - ModelObject object = getObject(); - - // get name using specific install location passed in - std::string name; - if (specificInstallLocation){ - name = Meter::getName(specificEndUse(), endUseType(), fuelType(), installLocationType(), boost::to_upper_copy(*specificInstallLocation)); - }else{ - name = Meter::getName(specificEndUse(), endUseType(), fuelType(), installLocationType(), specificInstallLocation); - } - - std::string frequency = this->reportingFrequency(); - if (openstudio::istringEqual(frequency, "RunPeriod")){ - frequency = "Run Period"; - }else if (openstudio::istringEqual(frequency, "Timestep")){ - frequency = "Zone Timestep"; - }else if (openstudio::istringEqual(frequency, "Detailed")){ - frequency = "HVAC System Timestep"; - } - - // currently the key value is not associated with the meter, it is part of the name - result = sqlFile->timeSeries(envPeriod, frequency, name, ""); - - if (!result){ - LOG(Debug, "Query for envPeriod = '" << envPeriod << - "', frequency = '" << frequency << - "', name = '" << name << - "', keyValue = '' did not return a TimeSeries"); - - } - } - - return result; - } - - -} // detail - -Meter::Meter(const Model& model) - : ModelObject(Meter::iddObjectType(),model) -{ - OS_ASSERT(getImpl()); -} - -IddObjectType Meter::iddObjectType() { - IddObjectType result(IddObjectType::OS_Meter); - return result; -} - -boost::regex Meter::meterRegex() -{ - // DLM: Must put more specific terms, e.g. HeatingCoils, before less specific terms, e.g. Heating - const static boost::regex result("^(.*?)?:?(InteriorLights|ExteriorLights|InteriorEquipment|ExteriorEquipment|Fans|Pumps|HeatingCoils|Heating|CoolingCoils|Cooling|HeatRejection|Humidifier|HeatRecoveryForCooling|HeatRecoveryForHeating|HeatRecovery|WaterSystems|Cogeneration|Refrigeration|Chillers|Boilers|Baseboard)?:?(Electricity|Gasoline|Gas|Diesel|Coal|FuelOil_1|FuelOil_2|Propane|Water|Steam|DistrictCooling|DistrictHeating|EnergyTransfer)?:?(Facility|Building|HVAC|Zone|System|Plant)?:?([^:]*?)?$"); - return result; -} - -std::string Meter::getName(const boost::optional& specificEndUseType, - const boost::optional& endUseType, - const boost::optional& fuelType, - const boost::optional& installLocationType, - const boost::optional& specificInstallLocation) -{ - std::string result; - - if (specificEndUseType && !specificEndUseType->empty()){ - result += *specificEndUseType; - } - if (endUseType){ - if (!result.empty()){ - result += ":"; - } - result += EndUseType(*endUseType).valueName(); - } - if (fuelType){ - if (!result.empty()){ - result += ":"; - } - result += FuelType(*fuelType).valueName(); - } - if (installLocationType){ - // there is a weird corner case to handle 'InteriorLights:Electricity:Facility' -> 'InteriorLights:Electricity' - // this might not catch all cases - if (installLocationType.get() != InstallLocationType::Facility || !endUseType){ - if (!result.empty()){ - result += ":"; - } - result += InstallLocationType(*installLocationType).valueName(); - } - } - if (specificInstallLocation && !specificInstallLocation->empty()){ - if (!result.empty()){ - result += ":"; - } - result += *specificInstallLocation; - } - LOG(Debug, "getName result = '" << result << "'"); - return result; -} - -std::string Meter::name() const { - return getImpl()->name(); -} - -std::string Meter::reportingFrequency() const { - return getImpl()->reportingFrequency(); -} - -bool Meter::isReportingFrequencyDefaulted() const { - return getImpl()->isReportingFrequencyDefaulted(); -} - -bool Meter::meterFileOnly() const { - return getImpl()->meterFileOnly(); -} - -bool Meter::isMeterFileOnlyDefaulted() const { - return getImpl()->isMeterFileOnlyDefaulted(); -} - -bool Meter::cumulative() const { - return getImpl()->cumulative(); -} - -bool Meter::isCumulativeDefaulted() const { - return getImpl()->isCumulativeDefaulted(); -} - -boost::optional Meter::specificEndUse() const -{ - return getImpl()->specificEndUse(); -} - -boost::optional Meter::endUseType() const -{ - return getImpl()->endUseType(); -} - -boost::optional Meter::fuelType() const -{ - return getImpl()->fuelType(); -} - -boost::optional Meter::installLocationType() const -{ - return getImpl()->installLocationType(); -} - -boost::optional Meter::specificInstallLocation() const -{ - return getImpl()->specificInstallLocation(); -} - -bool Meter::setName(std::string name) { - return getImpl()->setName(name); -} - -bool Meter::setReportingFrequency(const std::string& reportingFrequency) { - return getImpl()->setReportingFrequency(reportingFrequency); -} - -void Meter::resetReportingFrequency() { - getImpl()->resetReportingFrequency(); -} - -void Meter::setMeterFileOnly(bool meterFileOnly) { - getImpl()->setMeterFileOnly(meterFileOnly); -} - -void Meter::resetMeterFileOnly() { - getImpl()->resetMeterFileOnly(); -} - -void Meter::setCumulative(bool cumulative) { - getImpl()->setCumulative(cumulative); -} - -void Meter::resetCumulative() { - getImpl()->resetCumulative(); -} - -bool Meter::setSpecificEndUse(const std::string& endUse) -{ - return getImpl()->setSpecificEndUse(endUse); -} - -bool Meter::resetSpecificEndUse() -{ - return getImpl()->resetSpecificEndUse(); -} - -bool Meter::setEndUseType(EndUseType type) -{ - return getImpl()->setEndUseType(type); -} - -bool Meter::resetEndUseType() -{ - return getImpl()->resetEndUseType(); -} - -bool Meter::setFuelType(FuelType type) -{ - return getImpl()->setFuelType(type); -} - -bool Meter::resetFuelType() -{ - return getImpl()->resetFuelType(); -} - -bool Meter::setInstallLocationType(InstallLocationType type) -{ - return getImpl()->setInstallLocationType(type); -} - -bool Meter::resetInstallLocationType() -{ - return getImpl()->resetInstallLocationType(); -} - -bool Meter::setSpecificInstallLocation(const std::string& locationName) -{ - return getImpl()->setSpecificInstallLocation(locationName); -} - -bool Meter::resetSpecificInstallLocation() -{ - return getImpl()->resetSpecificInstallLocation(); -} - -openstudio::OptionalTimeSeries Meter::getData(const std::string& envPeriod) const -{ - return getImpl()->getData(envPeriod); -} - -openstudio::OptionalTimeSeries Meter::getData(const std::string& envPeriod, const OptionalString& specificInstallLocation) const -{ - return getImpl()->getData(envPeriod, specificInstallLocation); -} - -bool MeterFuelTypeEquals(const Meter& meter,const FuelType& ft) { - OptionalFuelType oft = meter.fuelType(); - if (oft && (oft.get() == ft)) { return true; } - return false; -} - -/// @cond -Meter::Meter(std::shared_ptr impl) - : ModelObject(impl) -{} -/// @endcond - - -} // model -} // openstudio - diff --git a/openstudiocore/src/model/MeterCustom.cpp b/openstudiocore/src/model/MeterCustom.cpp new file mode 100644 index 00000000000..5ba9c4d0104 --- /dev/null +++ b/openstudiocore/src/model/MeterCustom.cpp @@ -0,0 +1,290 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include "MeterCustom.hpp" +#include "MeterCustom_Impl.hpp" + +#include "Model.hpp" +#include "Model_Impl.hpp" + +#include "ModelObject.hpp" +#include "ModelObject_Impl.hpp" + +#include +#include +#include + +// Needed for extensible groups +#include "../utilities/idf/WorkspaceExtensibleGroup.hpp" + +#include "../utilities/core/Assert.hpp" + +namespace openstudio { +namespace model { + +namespace detail { + + MeterCustom_Impl::MeterCustom_Impl(const IdfObject& idfObject, + Model_Impl* model, + bool keepHandle) + : ModelObject_Impl(idfObject,model,keepHandle) + { + OS_ASSERT(idfObject.iddObject().type() == MeterCustom::iddObjectType()); + } + + MeterCustom_Impl::MeterCustom_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, + bool keepHandle) + : ModelObject_Impl(other, model, keepHandle) + { + OS_ASSERT(other.iddObject().type() == MeterCustom::iddObjectType()); + } + + MeterCustom_Impl::MeterCustom_Impl(const MeterCustom_Impl& other, + Model_Impl* model, + bool keepHandle) + : ModelObject_Impl(other,model,keepHandle) + {} + + // This logically doesn't produce any output variables + const std::vector& MeterCustom_Impl::outputVariableNames() const + { + static std::vector result; + if (result.empty()){ + } + //LOG(Info, "Meter:Custom does not produce any output variables."); + return result; + } + + IddObjectType MeterCustom_Impl::iddObjectType() const { + return MeterCustom::iddObjectType(); + } + + // fuel Type + boost::optional MeterCustom_Impl::fuelType() const { + return getString(OS_Meter_CustomFields::FuelType,true); + } + + bool MeterCustom_Impl::setFuelType(const std::string& fuelType) { + return setString(OS_Meter_CustomFields::FuelType, fuelType); + } + + void MeterCustom_Impl::resetFuelType() { + bool result = setString(OS_Meter_CustomFields::FuelType, ""); + OS_ASSERT(result); + } + + + // Add a new (Key, Var) group + bool MeterCustom_Impl::addKeyVarGroup(const std::string& keyName, const std::string& outputVariableorMeterName) { + WorkspaceExtensibleGroup eg = getObject().pushExtensibleGroup().cast(); + + bool temp = eg.setString(OS_Meter_CustomExtensibleFields::KeyName, keyName); + bool ok = eg.setString(OS_Meter_CustomExtensibleFields::OutputVariableorMeterName, outputVariableorMeterName); + + if (temp) { + temp = ok; + } + + if (!temp) { + getObject().eraseExtensibleGroup(eg.groupIndex()); + return temp; + } + return temp; + } + + // Remove the (Key, Var) group at given index + bool MeterCustom_Impl::removeKeyVarGroup(unsigned groupIndex) { + bool ok = false; + unsigned numberofDataPairs = numExtensibleGroups(); + // Only delete if the index is smaller than the number of groups + if (groupIndex < numberofDataPairs) { + getObject().eraseExtensibleGroup(groupIndex); + ok = true; + } + + return ok; + } + + // Remove all the (Key, Var) groups + void MeterCustom_Impl::removeAllKeyVarGroups() { + getObject().clearExtensibleGroups(); + } + + // Return a vector of (Key, Var) pairs + std::vector< std::pair > MeterCustom_Impl::keyVarGroups() { + std::vector< std::pair > result; + + std::vector groups = extensibleGroups(); + + for (const auto & group : groups) { + boost::optional keyName = group.cast().getString(OS_Meter_CustomExtensibleFields::KeyName); + boost::optional outputVariableorMeterName = group.cast().getString(OS_Meter_CustomExtensibleFields::OutputVariableorMeterName); + + if (keyName && outputVariableorMeterName) { + result.push_back(std::make_pair(keyName.get(), outputVariableorMeterName.get())); + } + } + + return result; + } + + // Return the number of (KeyName, OutputVariableorMeterName) groups + unsigned MeterCustom_Impl::numKeyVarGroups() const { + return numExtensibleGroups(); + } + + + // Lower level functions + /** Get the Key Name at index. Indexing starts at 0. */ + boost::optional MeterCustom_Impl::keyName(unsigned index) const { + IdfExtensibleGroup eg = getExtensibleGroup(index); + if (!eg.empty()) { + return eg.getString(OS_Meter_CustomExtensibleFields::KeyName, true); + } + return boost::none; + } + + /** Set the Key Name at index. Indexing starts at 0. */ + bool MeterCustom_Impl::setKeyName(unsigned index, const std::string& str) { + IdfExtensibleGroup eg = getExtensibleGroup(index); + if (!eg.empty()) { + return eg.setString(OS_Meter_CustomExtensibleFields::KeyName, str); + } else { + StringVector values(2u); + values[OS_Meter_CustomExtensibleFields::KeyName] = str; + return !insertExtensibleGroup(index, values).empty(); + } + OS_ASSERT(false); + return false; + } + + /** Get the Output Variable of Meter Name at index. Indexing starts at 0. */ + boost::optional MeterCustom_Impl::outputVariableorMeterName(unsigned index) const { + IdfExtensibleGroup eg = getExtensibleGroup(index); + if (!eg.empty()) { + return eg.getString(OS_Meter_CustomExtensibleFields::OutputVariableorMeterName, true); + } + return boost::none; + } + + /** Set the Output Variable of Meter Name at index. Indexing starts at 0. */ + bool MeterCustom_Impl::setOutputVariableorMeterName(unsigned index, const std::string& str) { + IdfExtensibleGroup eg = getExtensibleGroup(index); + if (!eg.empty()) { + return eg.setString(OS_Meter_CustomExtensibleFields::OutputVariableorMeterName, str); + } else { + StringVector values(2u); + values[OS_Meter_CustomExtensibleFields::OutputVariableorMeterName] = str; + return !insertExtensibleGroup(index, values).empty(); + } + OS_ASSERT(false); + return false; + } + + + + +} // detail + +MeterCustom::MeterCustom(const Model& model) + : ModelObject(MeterCustom::iddObjectType(), model) +{ + OS_ASSERT(getImpl()); + + // Default the fuelType to Electricity (maybe "Generic"?) + setFuelType("Electricity"); + +} + +IddObjectType MeterCustom::iddObjectType() { + return IddObjectType(IddObjectType::OS_Meter_Custom); +} + +std::vector MeterCustom::fuelTypeValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), + OS_Meter_CustomFields::FuelType); +} + +boost::optional MeterCustom::fuelType() const { + return getImpl()->fuelType(); +} + +bool MeterCustom::setFuelType(const std::string& fuelType) { + return getImpl()->setFuelType(fuelType); +} + +void MeterCustom::resetFuelType() { + getImpl()->resetFuelType(); +} + +// Add a new (Key, Var) group +bool MeterCustom::addKeyVarGroup(const std::string& keyName, const std::string& outputVariableorMeterName) { + return getImpl()->addKeyVarGroup(keyName, outputVariableorMeterName); +} + +// Remove the (Key, Var) group at given index +bool MeterCustom::removeKeyVarGroup(unsigned groupIndex) { + return getImpl()->removeKeyVarGroup(groupIndex); +} + +// Remove all the (Key, Var) groups +void MeterCustom::removeAllKeyVarGroups() { + getImpl()->removeAllKeyVarGroups(); +} + +// // Return a vector of (Key, Var) pairs +std::vector< std::pair > MeterCustom::keyVarGroups() { + return getImpl()->keyVarGroups(); +} + +// Return the number of (KeyName, OutputVariableorMeterName) groups +unsigned MeterCustom::numKeyVarGroups() const { + return getImpl()->numKeyVarGroups(); +} + + +// Lower level functions +/** Get the Key Name at index. Indexing starts at 0. */ +boost::optional MeterCustom::keyName(unsigned index) const { + return getImpl()->keyName(index); +} +/** Set the Key Name at index. Indexing starts at 0. */ +bool MeterCustom::setKeyName(unsigned index, const std::string& str) { + return getImpl()->setKeyName(index, str); +} + +/** Get the Output Variable of Meter Name at index. Indexing starts at 0. */ +boost::optional MeterCustom::outputVariableorMeterName(unsigned index) const { + return getImpl()->outputVariableorMeterName(index); +} +/** Set the Output Variable of Meter Name at index. Indexing starts at 0. */ +bool MeterCustom::setOutputVariableorMeterName(unsigned index, const std::string& str) { + return getImpl()->setOutputVariableorMeterName(index, str); +} + +/// @cond +MeterCustom::MeterCustom(std::shared_ptr impl) + : ModelObject(impl) +{} +/// @endcond + +} // model +} // openstudio + diff --git a/openstudiocore/src/model/MeterCustom.hpp b/openstudiocore/src/model/MeterCustom.hpp new file mode 100644 index 00000000000..ce49f69b4c3 --- /dev/null +++ b/openstudiocore/src/model/MeterCustom.hpp @@ -0,0 +1,135 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#ifndef MODEL_METERCUSTOM_HPP +#define MODEL_METERCUSTOM_HPP + +#include "ModelAPI.hpp" +#include "ModelObject.hpp" + +//#include + +namespace openstudio { +namespace model { + +namespace detail { + + class MeterCustom_Impl; + +} // detail + +/** MeterCustom is a ModelObject that wraps the OpenStudio IDD object 'OS:Meter:Custom'. */ +class MODEL_API MeterCustom : public ModelObject { + public: + /** @name Constructors and Destructors */ + //@{ + + // Constructs a new MeterCustom object in the model. + explicit MeterCustom(const Model& model); + + virtual ~MeterCustom() {} + + //@} + + static IddObjectType iddObjectType(); + + static std::vector fuelTypeValues(); + + /** @name Getters */ + //@{ + + boost::optional fuelType() const; + + // Return a vector of (Key, Var) pairs + std::vector< std::pair > keyVarGroups(); + + // Return the number of (KeyName, OutputVariableorMeterName) groups + unsigned numKeyVarGroups() const; + + + // Lower Level functions + /** Get the Key Name at index. Indexing starts at 0. */ + boost::optional keyName(unsigned index) const; + + /** Get the Output Variable of Meter Name at index. Indexing starts at 0. */ + boost::optional outputVariableorMeterName(unsigned index) const; + + //@} + /** @name Setters */ + //@{ + + bool setFuelType(const std::string& fuelType); + + void resetFuelType(); + + // Add a new (Key, Var) group + bool addKeyVarGroup(const std::string& keyName, const std::string& outputVariableorMeterName); + + // Remove the (Key, Var) group at given index + bool removeKeyVarGroup(unsigned groupIndex); + + // Remove all the (Key, Var) groups + void removeAllKeyVarGroups(); + + + // Lower level functions + /** Set the Key Name at index. Indexing starts at 0. */ + bool setKeyName(unsigned index, const std::string& str); + + /** Set the Output Variable of Meter Name at index. Indexing starts at 0. */ + bool setOutputVariableorMeterName(unsigned index, const std::string& str); + + //@} + /** @name Other */ + //@{ + + //@} + /** @name Type Casting */ + //@{ + + + //@} + protected: + /// @cond + typedef detail::MeterCustom_Impl ImplType; + + explicit MeterCustom(std::shared_ptr impl); + + friend class detail::MeterCustom_Impl; + friend class Model; + friend class IdfObject; + friend class openstudio::detail::IdfObject_Impl; + /// @endcond + private: + std::shared_ptr m_impl; + + REGISTER_LOGGER("openstudio.model.MeterCustom"); +}; + +/** \relates MeterCustom*/ +typedef boost::optional OptionalMeterCustom; + +/** \relates MeterCustom*/ +typedef std::vector MeterCustomVector; + +} // model +} // openstudio + +#endif // MODEL_METERCUSTOM_HPP + diff --git a/openstudiocore/src/model/MeterCustomDecrement.cpp b/openstudiocore/src/model/MeterCustomDecrement.cpp new file mode 100644 index 00000000000..909470ebc3b --- /dev/null +++ b/openstudiocore/src/model/MeterCustomDecrement.cpp @@ -0,0 +1,309 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include "MeterCustomDecrement.hpp" +#include "MeterCustomDecrement_Impl.hpp" + +#include "Model.hpp" +#include "Model_Impl.hpp" + +#include "ModelObject.hpp" +#include "ModelObject_Impl.hpp" + +#include +#include +#include + +// Needed for extensible groups +#include "../utilities/idf/WorkspaceExtensibleGroup.hpp" + +#include "../utilities/core/Assert.hpp" + +namespace openstudio { +namespace model { + +namespace detail { + + MeterCustomDecrement_Impl::MeterCustomDecrement_Impl(const IdfObject& idfObject, + Model_Impl* model, + bool keepHandle) + : ModelObject_Impl(idfObject,model,keepHandle) + { + OS_ASSERT(idfObject.iddObject().type() == MeterCustomDecrement::iddObjectType()); + } + + MeterCustomDecrement_Impl::MeterCustomDecrement_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, + bool keepHandle) + : ModelObject_Impl(other, model, keepHandle) + { + OS_ASSERT(other.iddObject().type() == MeterCustomDecrement::iddObjectType()); + } + + MeterCustomDecrement_Impl::MeterCustomDecrement_Impl(const MeterCustomDecrement_Impl& other, + Model_Impl* model, + bool keepHandle) + : ModelObject_Impl(other,model,keepHandle) + {} + + // This logically doesn't produce any output variables + const std::vector& MeterCustomDecrement_Impl::outputVariableNames() const + { + static std::vector result; + if (result.empty()){ + } + //LOG(Info, "Meter:Custom does not produce any output variables."); + return result; + } + + IddObjectType MeterCustomDecrement_Impl::iddObjectType() const { + return MeterCustomDecrement::iddObjectType(); + } + + // fuel Type + boost::optional MeterCustomDecrement_Impl::fuelType() const { + return getString(OS_Meter_CustomDecrementFields::FuelType,true); + } + + bool MeterCustomDecrement_Impl::setFuelType(const std::string& fuelType) { + return setString(OS_Meter_CustomDecrementFields::FuelType, fuelType); + } + + void MeterCustomDecrement_Impl::resetFuelType() { + bool result = setString(OS_Meter_CustomDecrementFields::FuelType, ""); + OS_ASSERT(result); + } + + // Source Meter Name + std::string MeterCustomDecrement_Impl::sourceMeterName() const { + return getString(OS_Meter_CustomDecrementFields::SourceMeterName,true).get(); + } + + bool MeterCustomDecrement_Impl::setSourceMeterName(const std::string& sourceMeterName) { + return setString(OS_Meter_CustomDecrementFields::SourceMeterName, sourceMeterName); + } + + // Add a new (Key, Var) group + bool MeterCustomDecrement_Impl::addKeyVarGroup(const std::string& keyName, const std::string& outputVariableorMeterName) { + WorkspaceExtensibleGroup eg = getObject().pushExtensibleGroup().cast(); + + bool temp = eg.setString(OS_Meter_CustomDecrementExtensibleFields::KeyName, keyName); + bool ok = eg.setString(OS_Meter_CustomDecrementExtensibleFields::OutputVariableorMeterName, outputVariableorMeterName); + + if (temp) { + temp = ok; + } + + if (!temp) { + getObject().eraseExtensibleGroup(eg.groupIndex()); + return temp; + } + return temp; + } + + // Remove the (Key, Var) group at given index + bool MeterCustomDecrement_Impl::removeKeyVarGroup(unsigned groupIndex) { + bool ok = false; + unsigned numberofDataPairs = numExtensibleGroups(); + // Only delete if the index is smaller than the number of groups + if (groupIndex < numberofDataPairs) { + getObject().eraseExtensibleGroup(groupIndex); + ok = true; + } + + return ok; + } + + // Remove all the (Key, Var) groups + void MeterCustomDecrement_Impl::removeAllKeyVarGroups() { + getObject().clearExtensibleGroups(); + } + + // Return a vector of (Key, Var) pairs + std::vector< std::pair > MeterCustomDecrement_Impl::keyVarGroups() { + std::vector< std::pair > result; + + std::vector groups = extensibleGroups(); + + for (const auto & group : groups) { + boost::optional keyName = group.cast().getString(OS_Meter_CustomDecrementExtensibleFields::KeyName); + boost::optional outputVariableorMeterName = group.cast().getString(OS_Meter_CustomDecrementExtensibleFields::OutputVariableorMeterName); + + if (keyName && outputVariableorMeterName) { + result.push_back(std::make_pair(keyName.get(), outputVariableorMeterName.get())); + } + } + + return result; + } + + // Return the number of (KeyName, OutputVariableorMeterName) groups + unsigned MeterCustomDecrement_Impl::numKeyVarGroups() const { + return numExtensibleGroups(); + } + + + // Lower level functions + /** Get the Key Name at index. Indexing starts at 0. */ + boost::optional MeterCustomDecrement_Impl::keyName(unsigned index) const { + IdfExtensibleGroup eg = getExtensibleGroup(index); + if (!eg.empty()) { + return eg.getString(OS_Meter_CustomDecrementExtensibleFields::KeyName, true); + } + return boost::none; + } + + /** Set the Key Name at index. Indexing starts at 0. */ + bool MeterCustomDecrement_Impl::setKeyName(unsigned index, const std::string& str) { + IdfExtensibleGroup eg = getExtensibleGroup(index); + if (!eg.empty()) { + return eg.setString(OS_Meter_CustomDecrementExtensibleFields::KeyName, str); + } else { + StringVector values(2u); + values[OS_Meter_CustomDecrementExtensibleFields::KeyName] = str; + return !insertExtensibleGroup(index, values).empty(); + } + OS_ASSERT(false); + return false; + } + + /** Get the Output Variable of Meter Name at index. Indexing starts at 0. */ + boost::optional MeterCustomDecrement_Impl::outputVariableorMeterName(unsigned index) const { + IdfExtensibleGroup eg = getExtensibleGroup(index); + if (!eg.empty()) { + return eg.getString(OS_Meter_CustomDecrementExtensibleFields::OutputVariableorMeterName, true); + } + return boost::none; + } + + /** Set the Output Variable of Meter Name at index. Indexing starts at 0. */ + bool MeterCustomDecrement_Impl::setOutputVariableorMeterName(unsigned index, const std::string& str) { + IdfExtensibleGroup eg = getExtensibleGroup(index); + if (!eg.empty()) { + return eg.setString(OS_Meter_CustomDecrementExtensibleFields::OutputVariableorMeterName, str); + } else { + StringVector values(2u); + values[OS_Meter_CustomDecrementExtensibleFields::OutputVariableorMeterName] = str; + return !insertExtensibleGroup(index, values).empty(); + } + OS_ASSERT(false); + return false; + } + + + + +} // detail + +MeterCustomDecrement::MeterCustomDecrement(const Model& model, const std::string& sourceMeterName) + : ModelObject(MeterCustomDecrement::iddObjectType(), model) +{ + OS_ASSERT(getImpl()); + + setSourceMeterName(sourceMeterName); + + // Default the fuelType to Electricity (maybe "Generic"?) + setFuelType("Electricity"); + +} + +IddObjectType MeterCustomDecrement::iddObjectType() { + return IddObjectType(IddObjectType::OS_Meter_CustomDecrement); +} + +std::vector MeterCustomDecrement::fuelTypeValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), + OS_Meter_CustomDecrementFields::FuelType); +} + +boost::optional MeterCustomDecrement::fuelType() const { + return getImpl()->fuelType(); +} + +bool MeterCustomDecrement::setFuelType(const std::string& fuelType) { + return getImpl()->setFuelType(fuelType); +} + +void MeterCustomDecrement::resetFuelType() { + getImpl()->resetFuelType(); +} + +std::string MeterCustomDecrement::sourceMeterName() const { + return getImpl()->sourceMeterName(); +} + +bool MeterCustomDecrement::setSourceMeterName(const std::string& sourceMeterName) { + return getImpl()->setSourceMeterName(sourceMeterName); +} + + +// Add a new (Key, Var) group +bool MeterCustomDecrement::addKeyVarGroup(const std::string& keyName, const std::string& outputVariableorMeterName) { + return getImpl()->addKeyVarGroup(keyName, outputVariableorMeterName); +} + +// Remove the (Key, Var) group at given index +bool MeterCustomDecrement::removeKeyVarGroup(unsigned groupIndex) { + return getImpl()->removeKeyVarGroup(groupIndex); +} + +// Remove all the (Key, Var) groups +void MeterCustomDecrement::removeAllKeyVarGroups() { + getImpl()->removeAllKeyVarGroups(); +} + +// // Return a vector of (Key, Var) pairs +std::vector< std::pair > MeterCustomDecrement::keyVarGroups() { + return getImpl()->keyVarGroups(); +} + +// Return the number of (KeyName, OutputVariableorMeterName) groups +unsigned MeterCustomDecrement::numKeyVarGroups() const { + return getImpl()->numKeyVarGroups(); +} + + +// Lower level functions +/** Get the Key Name at index. Indexing starts at 0. */ +boost::optional MeterCustomDecrement::keyName(unsigned index) const { + return getImpl()->keyName(index); +} +/** Set the Key Name at index. Indexing starts at 0. */ +bool MeterCustomDecrement::setKeyName(unsigned index, const std::string& str) { + return getImpl()->setKeyName(index, str); +} + +/** Get the Output Variable of Meter Name at index. Indexing starts at 0. */ +boost::optional MeterCustomDecrement::outputVariableorMeterName(unsigned index) const { + return getImpl()->outputVariableorMeterName(index); +} +/** Set the Output Variable of Meter Name at index. Indexing starts at 0. */ +bool MeterCustomDecrement::setOutputVariableorMeterName(unsigned index, const std::string& str) { + return getImpl()->setOutputVariableorMeterName(index, str); +} + +/// @cond +MeterCustomDecrement::MeterCustomDecrement(std::shared_ptr impl) + : ModelObject(impl) +{} +/// @endcond + +} // model +} // openstudio + diff --git a/openstudiocore/src/model/MeterCustomDecrement.hpp b/openstudiocore/src/model/MeterCustomDecrement.hpp new file mode 100644 index 00000000000..51f37104a8a --- /dev/null +++ b/openstudiocore/src/model/MeterCustomDecrement.hpp @@ -0,0 +1,139 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#ifndef MODEL_METERCUSTOMDECREMENT_HPP +#define MODEL_METERCUSTOMDECREMENT_HPP + +#include "ModelAPI.hpp" +#include "ModelObject.hpp" + +//#include + +namespace openstudio { +namespace model { + +namespace detail { + + class MeterCustomDecrement_Impl; + +} // detail + +/** MeterCustomDecrement is a ModelObject that wraps the OpenStudio IDD object 'OS:Meter:Custom'. */ +class MODEL_API MeterCustomDecrement : public ModelObject { + public: + /** @name Constructors and Destructors */ + //@{ + + // Constructs a new MeterCustomDecrement object in the model. + explicit MeterCustomDecrement(const Model& model, const std::string& sourceMeterName); + + virtual ~MeterCustomDecrement() {} + + //@} + + static IddObjectType iddObjectType(); + + static std::vector fuelTypeValues(); + + /** @name Getters */ + //@{ + + boost::optional fuelType() const; + + std::string sourceMeterName() const; + + // Return a vector of (Key, Var) pairs + std::vector< std::pair > keyVarGroups(); + + // Return the number of (KeyName, OutputVariableorMeterName) groups + unsigned numKeyVarGroups() const; + + + // Lower Level functions + /** Get the Key Name at index. Indexing starts at 0. */ + boost::optional keyName(unsigned index) const; + + /** Get the Output Variable of Meter Name at index. Indexing starts at 0. */ + boost::optional outputVariableorMeterName(unsigned index) const; + + //@} + /** @name Setters */ + //@{ + + bool setFuelType(const std::string& fuelType); + + void resetFuelType(); + + bool setSourceMeterName(const std::string& sourceMeterName); + + // Add a new (Key, Var) group + bool addKeyVarGroup(const std::string& keyName, const std::string& outputVariableorMeterName); + + // Remove the (Key, Var) group at given index + bool removeKeyVarGroup(unsigned groupIndex); + + // Remove all the (Key, Var) groups + void removeAllKeyVarGroups(); + + + // Lower level functions + /** Set the Key Name at index. Indexing starts at 0. */ + bool setKeyName(unsigned index, const std::string& str); + + /** Set the Output Variable of Meter Name at index. Indexing starts at 0. */ + bool setOutputVariableorMeterName(unsigned index, const std::string& str); + + //@} + /** @name Other */ + //@{ + + //@} + /** @name Type Casting */ + //@{ + + + //@} + protected: + /// @cond + typedef detail::MeterCustomDecrement_Impl ImplType; + + explicit MeterCustomDecrement(std::shared_ptr impl); + + friend class detail::MeterCustomDecrement_Impl; + friend class Model; + friend class IdfObject; + friend class openstudio::detail::IdfObject_Impl; + /// @endcond + private: + std::shared_ptr m_impl; + + REGISTER_LOGGER("openstudio.model.MeterCustomDecrement"); +}; + +/** \relates MeterCustomDecrement*/ +typedef boost::optional OptionalMeterCustomDecrement; + +/** \relates MeterCustomDecrement*/ +typedef std::vector MeterCustomDecrementVector; + +} // model +} // openstudio + +#endif // MODEL_METERCUSTOMDECREMENT_HPP + diff --git a/openstudiocore/src/model/MeterCustomDecrement_Impl.hpp b/openstudiocore/src/model/MeterCustomDecrement_Impl.hpp new file mode 100644 index 00000000000..f21bb2c33d5 --- /dev/null +++ b/openstudiocore/src/model/MeterCustomDecrement_Impl.hpp @@ -0,0 +1,138 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#ifndef MODEL_METERCUSTOMDECREMENT_IMPL_HPP +#define MODEL_METERCUSTOMDECREMENT_IMPL_HPP + +#include "ModelAPI.hpp" +#include "ModelObject_Impl.hpp" + + +namespace openstudio { +namespace model { + +namespace detail { + + /** MeterCustomDecrement_Impl is a ModelObject_Impl that is the implementation class for MeterCustomDecrement.*/ +class MODEL_API MeterCustomDecrement_Impl : public ModelObject_Impl { + + public: + /** @name Constructors and Destructors */ + //@{ + + // constructor + MeterCustomDecrement_Impl(const IdfObject& idfObject, + Model_Impl* model, + bool keepHandle); + + // construct from workspace + MeterCustomDecrement_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, + bool keepHandle); + + // clone copy constructor + MeterCustomDecrement_Impl(const MeterCustomDecrement_Impl& other, + Model_Impl* model, + bool keepHandle); + + // virtual destructor + virtual ~MeterCustomDecrement_Impl() {} + + //@} + /** @name Virtual Methods */ + //@{ + + virtual const std::vector& outputVariableNames() const; + + virtual IddObjectType iddObjectType() const; + + //@} + /** @name Getters */ + //@{ + + boost::optional fuelType() const; + + std::string sourceMeterName() const; + + // Return a vector of (Key, Var) pairs + std::vector< std::pair > keyVarGroups(); + + // Return the number of (KeyName, OutputVariableorMeterName) groups + unsigned numKeyVarGroups() const; + + + // Lower Level functions + /** Get the Key Name at index. Indexing starts at 0. */ + boost::optional keyName(unsigned index) const; + + /** Get the Output Variable of Meter Name at index. Indexing starts at 0. */ + boost::optional outputVariableorMeterName(unsigned index) const; + + //@} + /** @name Setters */ + //@{ + + bool setFuelType(const std::string& fuelType); + + void resetFuelType(); + + bool setSourceMeterName(const std::string& sourceMeterName); + + // Add a new (Key, Var) group + bool addKeyVarGroup(const std::string& keyName, const std::string& outputVariableorMeterName); + + // Remove the (Key, Var) group at given index + bool removeKeyVarGroup(unsigned groupIndex); + + // Remove all the (Key, Var) groups + void removeAllKeyVarGroups(); + + + // Lower level functions + /** Set the Key Name at index. Indexing starts at 0. */ + bool setKeyName(unsigned index, const std::string& str); + + /** Set the Output Variable of Meter Name at index. Indexing starts at 0. */ + bool setOutputVariableorMeterName(unsigned index, const std::string& str); + + + + + + //@} + /** @name Other */ + //@{ + + //@} + /** @name Type Casting */ + //@{ + + //@} + protected: + private: + REGISTER_LOGGER("openstudio.model.MeterCustomDecrement"); + }; + +} // detail + +} // model +} // openstudio + +#endif // MODEL_METERCUSTOMDECREMENT_IMPL_HPP + diff --git a/openstudiocore/src/model/MeterCustom_Impl.hpp b/openstudiocore/src/model/MeterCustom_Impl.hpp new file mode 100644 index 00000000000..f8756719818 --- /dev/null +++ b/openstudiocore/src/model/MeterCustom_Impl.hpp @@ -0,0 +1,134 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#ifndef MODEL_METERCUSTOM_IMPL_HPP +#define MODEL_METERCUSTOM_IMPL_HPP + +#include "ModelAPI.hpp" +#include "ModelObject_Impl.hpp" + + +namespace openstudio { +namespace model { + +namespace detail { + + /** MeterCustom_Impl is a ModelObject_Impl that is the implementation class for MeterCustom.*/ +class MODEL_API MeterCustom_Impl : public ModelObject_Impl { + + public: + /** @name Constructors and Destructors */ + //@{ + + // constructor + MeterCustom_Impl(const IdfObject& idfObject, + Model_Impl* model, + bool keepHandle); + + // construct from workspace + MeterCustom_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, + bool keepHandle); + + // clone copy constructor + MeterCustom_Impl(const MeterCustom_Impl& other, + Model_Impl* model, + bool keepHandle); + + // virtual destructor + virtual ~MeterCustom_Impl() {} + + //@} + /** @name Virtual Methods */ + //@{ + + virtual const std::vector& outputVariableNames() const; + + virtual IddObjectType iddObjectType() const; + + //@} + /** @name Getters */ + //@{ + + boost::optional fuelType() const; + + // Return a vector of (Key, Var) pairs + std::vector< std::pair > keyVarGroups(); + + // Return the number of (KeyName, OutputVariableorMeterName) groups + unsigned numKeyVarGroups() const; + + + // Lower Level functions + /** Get the Key Name at index. Indexing starts at 0. */ + boost::optional keyName(unsigned index) const; + + /** Get the Output Variable of Meter Name at index. Indexing starts at 0. */ + boost::optional outputVariableorMeterName(unsigned index) const; + + //@} + /** @name Setters */ + //@{ + + bool setFuelType(const std::string& fuelType); + + void resetFuelType(); + + // Add a new (Key, Var) group + bool addKeyVarGroup(const std::string& keyName, const std::string& outputVariableorMeterName); + + // Remove the (Key, Var) group at given index + bool removeKeyVarGroup(unsigned groupIndex); + + // Remove all the (Key, Var) groups + void removeAllKeyVarGroups(); + + + // Lower level functions + /** Set the Key Name at index. Indexing starts at 0. */ + bool setKeyName(unsigned index, const std::string& str); + + /** Set the Output Variable of Meter Name at index. Indexing starts at 0. */ + bool setOutputVariableorMeterName(unsigned index, const std::string& str); + + + + + + //@} + /** @name Other */ + //@{ + + //@} + /** @name Type Casting */ + //@{ + + //@} + protected: + private: + REGISTER_LOGGER("openstudio.model.MeterCustom"); + }; + +} // detail + +} // model +} // openstudio + +#endif // MODEL_METERCUSTOM_IMPL_HPP + diff --git a/openstudiocore/src/model/Model.cpp b/openstudiocore/src/model/Model.cpp index f30628a2847..ea0b4f3c833 100644 --- a/openstudiocore/src/model/Model.cpp +++ b/openstudiocore/src/model/Model.cpp @@ -322,6 +322,7 @@ if (_className::iddObjectType() == typeToCreate) { \ REGISTER_CONSTRUCTOR(ElectricLoadCenterDistribution); REGISTER_CONSTRUCTOR(ElectricLoadCenterInverterLookUpTable); REGISTER_CONSTRUCTOR(ElectricLoadCenterInverterSimple); + REGISTER_CONSTRUCTOR(ElectricLoadCenterStorageSimple); REGISTER_CONSTRUCTOR(EvaporativeCoolerDirectResearchSpecial); REGISTER_CONSTRUCTOR(EvaporativeCoolerIndirectResearchSpecial); REGISTER_CONSTRUCTOR(EvaporativeFluidCoolerSingleSpeed); @@ -340,6 +341,8 @@ if (_className::iddObjectType() == typeToCreate) { \ REGISTER_CONSTRUCTOR(GasEquipment); REGISTER_CONSTRUCTOR(GasEquipmentDefinition); REGISTER_CONSTRUCTOR(GasMixture); + REGISTER_CONSTRUCTOR(GeneratorMicroTurbine); + REGISTER_CONSTRUCTOR(GeneratorMicroTurbineHeatRecovery); REGISTER_CONSTRUCTOR(GeneratorPhotovoltaic); REGISTER_CONSTRUCTOR(GlareSensor); REGISTER_CONSTRUCTOR(GroundHeatExchangerHorizontalTrench); @@ -374,12 +377,14 @@ if (_className::iddObjectType() == typeToCreate) { \ REGISTER_CONSTRUCTOR(LuminaireDefinition); REGISTER_CONSTRUCTOR(MaterialPropertyGlazingSpectralData); REGISTER_CONSTRUCTOR(MasslessOpaqueMaterial); - REGISTER_CONSTRUCTOR(Meter); + REGISTER_CONSTRUCTOR(MeterCustom); + REGISTER_CONSTRUCTOR(MeterCustomDecrement); REGISTER_CONSTRUCTOR(ModelObjectList); REGISTER_CONSTRUCTOR(Node); REGISTER_CONSTRUCTOR(OtherEquipment); REGISTER_CONSTRUCTOR(OtherEquipmentDefinition); REGISTER_CONSTRUCTOR(OutputControlReportingTolerances); + REGISTER_CONSTRUCTOR(OutputMeter); REGISTER_CONSTRUCTOR(OutputVariable); REGISTER_CONSTRUCTOR(OutsideSurfaceConvectionAlgorithm); REGISTER_CONSTRUCTOR(People); @@ -727,6 +732,7 @@ if (_className::iddObjectType() == typeToCreate) { \ REGISTER_COPYCONSTRUCTORS(ElectricLoadCenterDistribution); REGISTER_COPYCONSTRUCTORS(ElectricLoadCenterInverterLookUpTable); REGISTER_COPYCONSTRUCTORS(ElectricLoadCenterInverterSimple); + REGISTER_COPYCONSTRUCTORS(ElectricLoadCenterStorageSimple); REGISTER_COPYCONSTRUCTORS(EvaporativeCoolerDirectResearchSpecial); REGISTER_COPYCONSTRUCTORS(EvaporativeCoolerIndirectResearchSpecial); REGISTER_COPYCONSTRUCTORS(EvaporativeFluidCoolerSingleSpeed); @@ -745,6 +751,8 @@ if (_className::iddObjectType() == typeToCreate) { \ REGISTER_COPYCONSTRUCTORS(GasEquipment); REGISTER_COPYCONSTRUCTORS(GasEquipmentDefinition); REGISTER_COPYCONSTRUCTORS(GasMixture); + REGISTER_COPYCONSTRUCTORS(GeneratorMicroTurbine); + REGISTER_COPYCONSTRUCTORS(GeneratorMicroTurbineHeatRecovery); REGISTER_COPYCONSTRUCTORS(GeneratorPhotovoltaic); REGISTER_COPYCONSTRUCTORS(GlareSensor); REGISTER_COPYCONSTRUCTORS(GroundHeatExchangerHorizontalTrench); @@ -779,12 +787,14 @@ if (_className::iddObjectType() == typeToCreate) { \ REGISTER_COPYCONSTRUCTORS(LuminaireDefinition); REGISTER_COPYCONSTRUCTORS(MaterialPropertyGlazingSpectralData); REGISTER_COPYCONSTRUCTORS(MasslessOpaqueMaterial); - REGISTER_COPYCONSTRUCTORS(Meter); + REGISTER_COPYCONSTRUCTORS(MeterCustom); + REGISTER_COPYCONSTRUCTORS(MeterCustomDecrement); REGISTER_COPYCONSTRUCTORS(ModelObjectList); REGISTER_COPYCONSTRUCTORS(Node); REGISTER_COPYCONSTRUCTORS(OtherEquipment); REGISTER_COPYCONSTRUCTORS(OtherEquipmentDefinition); REGISTER_COPYCONSTRUCTORS(OutputControlReportingTolerances); + REGISTER_COPYCONSTRUCTORS(OutputMeter); REGISTER_COPYCONSTRUCTORS(OutputVariable); REGISTER_COPYCONSTRUCTORS(OutsideSurfaceConvectionAlgorithm); REGISTER_COPYCONSTRUCTORS(People); @@ -2181,17 +2191,17 @@ void addExampleModelObjects(Model& model) } // add some meters - Meter electricityMeter(model); + OutputMeter electricityMeter(model); electricityMeter.setFuelType(FuelType(FuelType::Electricity)); electricityMeter.setReportingFrequency(ReportingFrequency(ReportingFrequency::Hourly).valueName()); electricityMeter.setInstallLocationType(InstallLocationType(InstallLocationType::Facility)); - Meter gasMeter(model); + OutputMeter gasMeter(model); gasMeter.setFuelType(FuelType(FuelType::Gas)); gasMeter.setReportingFrequency(ReportingFrequency(ReportingFrequency::Hourly).valueName()); gasMeter.setInstallLocationType(InstallLocationType(InstallLocationType::Facility)); - Meter propaneMeter(model); + OutputMeter propaneMeter(model); propaneMeter.setFuelType(FuelType(FuelType::Propane)); propaneMeter.setReportingFrequency(ReportingFrequency(ReportingFrequency::Hourly).valueName()); propaneMeter.setInstallLocationType(InstallLocationType(InstallLocationType::Facility)); diff --git a/openstudiocore/src/model/ModelCore.i b/openstudiocore/src/model/ModelCore.i index 6af4a229cfc..f26e5c6a44a 100644 --- a/openstudiocore/src/model/ModelCore.i +++ b/openstudiocore/src/model/ModelCore.i @@ -152,7 +152,9 @@ MODELOBJECT_TEMPLATES(ResourceObject); UNIQUEMODELOBJECT_TEMPLATES(Version); UNIQUEMODELOBJECT_TEMPLATES(LifeCycleCostParameters); UNIQUEMODELOBJECT_TEMPLATES(RadianceParameters); -MODELOBJECT_TEMPLATES(Meter); +MODELOBJECT_TEMPLATES(OutputMeter); +MODELOBJECT_TEMPLATES(MeterCustom); +MODELOBJECT_TEMPLATES(MeterCustomDecrement); MODELOBJECT_TEMPLATES(LifeCycleCost); MODELOBJECT_TEMPLATES(UtilityBill); MODELEXTENSIBLEGROUP_TEMPLATES(BillingPeriod) @@ -176,7 +178,9 @@ SWIG_MODELOBJECT(ResourceObject, 0); SWIG_UNIQUEMODELOBJECT(Version); SWIG_UNIQUEMODELOBJECT(LifeCycleCostParameters); SWIG_UNIQUEMODELOBJECT(RadianceParameters); -SWIG_MODELOBJECT(Meter, 1); +SWIG_MODELOBJECT(OutputMeter, 1); +SWIG_MODELOBJECT(MeterCustom, 1); +SWIG_MODELOBJECT(MeterCustomDecrement, 1); SWIG_MODELOBJECT(LifeCycleCost, 1); SWIG_MODELOBJECT(UtilityBill, 1); SWIG_MODELEXTENSIBLEGROUP(BillingPeriod); diff --git a/openstudiocore/src/model/ModelGenerators.i b/openstudiocore/src/model/ModelGenerators.i index 3efbc9d5239..11926e81dc3 100644 --- a/openstudiocore/src/model/ModelGenerators.i +++ b/openstudiocore/src/model/ModelGenerators.i @@ -13,6 +13,7 @@ %import %import +// All base classes for PV, Generators, inverters and Electrical Storage %{ #include #include @@ -20,6 +21,8 @@ #include #include #include + #include + #include %} @@ -41,20 +44,30 @@ namespace openstudio { MODELOBJECT_TEMPLATES(PhotovoltaicPerformance); MODELOBJECT_TEMPLATES(Generator); MODELOBJECT_TEMPLATES(Inverter); +MODELOBJECT_TEMPLATES(ElectricalStorage); MODELOBJECT_TEMPLATES(GeneratorPhotovoltaic); +// Puting the GeneratorMicroTurbineHeatRecovery first so that the GeneratorMicroTurbine knows about it +MODELOBJECT_TEMPLATES(GeneratorMicroTurbineHeatRecovery); +MODELOBJECT_TEMPLATES(GeneratorMicroTurbine); MODELOBJECT_TEMPLATES(ElectricLoadCenterDistribution); MODELOBJECT_TEMPLATES(ElectricLoadCenterInverterLookUpTable); MODELOBJECT_TEMPLATES(ElectricLoadCenterInverterSimple); +MODELOBJECT_TEMPLATES(ElectricLoadCenterStorageSimple); MODELOBJECT_TEMPLATES(PhotovoltaicPerformanceEquivalentOneDiode); MODELOBJECT_TEMPLATES(PhotovoltaicPerformanceSimple); SWIG_MODELOBJECT(PhotovoltaicPerformance, 0); SWIG_MODELOBJECT(Generator, 0); SWIG_MODELOBJECT(Inverter, 0); +SWIG_MODELOBJECT(ElectricalStorage, 0); SWIG_MODELOBJECT(GeneratorPhotovoltaic, 1); +// Puting the GeneratorMicroTurbineHeatRecovery first so that the GeneratorMicroTurbine knows about it +SWIG_MODELOBJECT(GeneratorMicroTurbineHeatRecovery, 1); +SWIG_MODELOBJECT(GeneratorMicroTurbine, 1); SWIG_MODELOBJECT(ElectricLoadCenterDistribution, 1); SWIG_MODELOBJECT(ElectricLoadCenterInverterLookUpTable, 1); SWIG_MODELOBJECT(ElectricLoadCenterInverterSimple, 1); +SWIG_MODELOBJECT(ElectricLoadCenterStorageSimple, 1); SWIG_MODELOBJECT(PhotovoltaicPerformanceEquivalentOneDiode, 1); SWIG_MODELOBJECT(PhotovoltaicPerformanceSimple, 1); diff --git a/openstudiocore/src/model/ModelObject.hpp b/openstudiocore/src/model/ModelObject.hpp index b7569a4ee71..e7fab51e5af 100644 --- a/openstudiocore/src/model/ModelObject.hpp +++ b/openstudiocore/src/model/ModelObject.hpp @@ -57,7 +57,7 @@ class ResourceObject; class Schedule; class OutputVariable; -class Meter; +class OutputMeterMeter; class Connection; namespace detail { diff --git a/openstudiocore/src/model/OutputMeter.cpp b/openstudiocore/src/model/OutputMeter.cpp new file mode 100644 index 00000000000..a56a279c0e2 --- /dev/null +++ b/openstudiocore/src/model/OutputMeter.cpp @@ -0,0 +1,643 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include "OutputMeter.hpp" +#include "OutputMeter_Impl.hpp" + +#include "Model.hpp" +#include "Facility.hpp" +#include "Facility_Impl.hpp" +#include "Building.hpp" +#include "Building_Impl.hpp" + +#include + +#include +#include + +#include "../utilities/data/DataEnums.hpp" +#include "../utilities/data/TimeSeries.hpp" +#include "../utilities/sql/SqlFile.hpp" +#include "../utilities/sql/SqlFileEnums.hpp" +#include "../utilities/core/Assert.hpp" + +#include +#include + +namespace openstudio { +namespace model { + +namespace detail { + + OutputMeter_Impl::OutputMeter_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle) + : ModelObject_Impl(idfObject,model,keepHandle) + { + OS_ASSERT(idfObject.iddObject().type() == OutputMeter::iddObjectType()); + } + + OutputMeter_Impl::OutputMeter_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, + bool keepHandle) + : ModelObject_Impl(other,model,keepHandle) + { + OS_ASSERT(other.iddObject().type() == OutputMeter::iddObjectType()); + } + + OutputMeter_Impl::OutputMeter_Impl(const OutputMeter_Impl& other, + Model_Impl* model, + bool keepHandle) + : ModelObject_Impl(other,model,keepHandle) + {} + + const std::vector& OutputMeter_Impl::outputVariableNames() const + { + static std::vector result; + if (result.empty()){ + } + return result; + } + + IddObjectType OutputMeter_Impl::iddObjectType() const { + return OutputMeter::iddObjectType(); + } + + boost::optional OutputMeter_Impl::parent() const + { + boost::optional result; + boost::optional installLocationType = this->installLocationType(); + if(installLocationType){ + switch (installLocationType->value()){ + case InstallLocationType::Facility: + result = this->model().getOptionalUniqueModelObject(); + break; + case InstallLocationType::Building: + result = this->model().building(); + break; + default: + ; + } + + } + return result; + } + + std::string OutputMeter_Impl::name() const { + boost::optional value = getString(OS_Output_MeterFields::Name,true); + OS_ASSERT(value); + return value.get(); + } + + std::string OutputMeter_Impl::reportingFrequency() const { + boost::optional value = getString(OS_Output_MeterFields::ReportingFrequency,true); + OS_ASSERT(value); + return value.get(); + } + + bool OutputMeter_Impl::isReportingFrequencyDefaulted() const { + return isEmpty(OS_Output_MeterFields::ReportingFrequency); + } + + bool OutputMeter_Impl::meterFileOnly() const { + boost::optional value = getString(OS_Output_MeterFields::MeterFileOnly,true); + OS_ASSERT(value); + return openstudio::istringEqual(value.get(), "True"); + } + + bool OutputMeter_Impl::isMeterFileOnlyDefaulted() const { + return isEmpty(OS_Output_MeterFields::MeterFileOnly); + } + + bool OutputMeter_Impl::cumulative() const { + boost::optional value = getString(OS_Output_MeterFields::Cumulative,true); + OS_ASSERT(value); + return openstudio::istringEqual(value.get(), "True"); + } + + bool OutputMeter_Impl::isCumulativeDefaulted() const { + return isEmpty(OS_Output_MeterFields::Cumulative); + } + + boost::optional OutputMeter_Impl::specificEndUse() const + { + boost::optional result; + std::string myName = name(); + boost::smatch matches; + if (boost::regex_search(myName, matches, OutputMeter::meterRegex())) + { + // match is always true but may be empty + if (matches[1].first != matches[1].second){ + result = std::string(matches[1].first, matches[1].second); + } + } + + return result; + } + + boost::optional OutputMeter_Impl::endUseType() const + { + boost::optional result; + std::string myName = name(); + boost::smatch matches; + if (boost::regex_search(myName, matches, OutputMeter::meterRegex())) + { + if (matches[2].matched){ + result = EndUseType(std::string(matches[2].first, matches[2].second)); + } + } + + return result; + } + + boost::optional OutputMeter_Impl::fuelType() const + { + boost::optional result; + std::string myName = name(); + boost::smatch matches; + if (boost::regex_search(myName, matches, OutputMeter::meterRegex())) + { + if (matches[3].matched){ + result = FuelType(std::string(matches[3].first, matches[3].second)); + } + } + + return result; + } + + boost::optional OutputMeter_Impl::installLocationType() const + { + boost::optional result; + std::string myName = name(); + boost::smatch matches; + if (boost::regex_search(myName, matches, OutputMeter::meterRegex())) + { + if (matches[4].matched){ + result = InstallLocationType(std::string(matches[4].first, matches[4].second)); + } + } + + return result; + } + + boost::optional OutputMeter_Impl::specificInstallLocation() const + { + boost::optional result; + std::string myName = name(); + boost::smatch matches; + if (boost::regex_search(myName, matches, OutputMeter::meterRegex())) + { + // match is always true but may be empty + if (matches[5].first != matches[5].second){ + result = std::string(matches[5].first, matches[5].second); + } + } + + return result; + } + + bool OutputMeter_Impl::setName(std::string name) { + return setString(OS_Output_MeterFields::Name, name); + } + + bool OutputMeter_Impl::setReportingFrequency(const std::string& reportingFrequency) { + return setString(OS_Output_MeterFields::ReportingFrequency, reportingFrequency); + } + + void OutputMeter_Impl::resetReportingFrequency() { + bool result = setString(OS_Output_MeterFields::ReportingFrequency, ""); + OS_ASSERT(result); + } + + void OutputMeter_Impl::setMeterFileOnly(bool meterFileOnly) { + bool result = false; + if (meterFileOnly) { + result = setString(OS_Output_MeterFields::MeterFileOnly, "True"); + } else { + result = setString(OS_Output_MeterFields::MeterFileOnly, "False"); + } + OS_ASSERT(result); + } + + void OutputMeter_Impl::resetMeterFileOnly() { + bool result = setString(OS_Output_MeterFields::MeterFileOnly, ""); + OS_ASSERT(result); + } + + void OutputMeter_Impl::setCumulative(bool cumulative) { + bool result = false; + if (cumulative) { + result = setString(OS_Output_MeterFields::Cumulative, "True"); + } else { + result = setString(OS_Output_MeterFields::Cumulative, "False"); + } + OS_ASSERT(result); + } + + void OutputMeter_Impl::resetCumulative() { + bool result = setString(OS_Output_MeterFields::Cumulative, ""); + OS_ASSERT(result); + } + + bool OutputMeter_Impl::setSpecificEndUse(const std::string& endUse) + { + ModelObject object = getObject(); + + std::string name = OutputMeter::getName(endUse, endUseType(), fuelType(), installLocationType(), specificInstallLocation()); + + bool result = object.setString(OS_Output_MeterFields::Name, name); + if (!result){ + LOG(Error, "Could not set name to '" << name << "'"); + } + + return result; + } + + bool OutputMeter_Impl::resetSpecificEndUse() + { + return setSpecificEndUse(""); + } + + bool OutputMeter_Impl::setEndUseType(EndUseType type) + { + ModelObject object = getObject(); + + std::string name = OutputMeter::getName(specificEndUse(), type, fuelType(), installLocationType(), specificInstallLocation()); + + bool result = object.setString(OS_Output_MeterFields::Name, name); + if (!result){ + LOG(Error, "Could not set name to '" << name << "'"); + } + + return result; + } + + bool OutputMeter_Impl::resetEndUseType() + { + ModelObject object = getObject(); + + std::string name = OutputMeter::getName(specificEndUse(), boost::none, fuelType(), installLocationType(), specificInstallLocation()); + + bool result = object.setString(OS_Output_MeterFields::Name, name); + if (!result){ + LOG(Error, "Could not set name to '" << name << "'"); + } + + return result; + } + + bool OutputMeter_Impl::setFuelType(FuelType type) + { + ModelObject object = getObject(); + + std::string name = OutputMeter::getName(specificEndUse(), endUseType(), type, installLocationType(), specificInstallLocation()); + + bool result = object.setString(OS_Output_MeterFields::Name, name); + if (!result){ + LOG(Error, "Could not set name to '" << name << "'"); + } + + return result; + } + + bool OutputMeter_Impl::resetFuelType() + { + ModelObject object = getObject(); + + std::string name = OutputMeter::getName(specificEndUse(), endUseType(), boost::none, installLocationType(), specificInstallLocation()); + + bool result = object.setString(OS_Output_MeterFields::Name, name); + if (!result){ + LOG(Error, "Could not set name to '" << name << "'"); + } + + return result; + } + + bool OutputMeter_Impl::setInstallLocationType(InstallLocationType type) + { + ModelObject object = getObject(); + + std::string name = OutputMeter::getName(specificEndUse(), endUseType(), fuelType(), type, specificInstallLocation()); + + bool result = object.setString(OS_Output_MeterFields::Name, name); + if (!result){ + LOG(Error, "Could not set name to '" << name << "'"); + } + + return result; + } + + bool OutputMeter_Impl::resetInstallLocationType() + { + ModelObject object = getObject(); + + std::string name = OutputMeter::getName(specificEndUse(), endUseType(), fuelType(), boost::none, specificInstallLocation()); + + bool result = object.setString(OS_Output_MeterFields::Name, name); + if (!result){ + LOG(Error, "Could not set name to '" << name << "'"); + } + + return result; + } + + bool OutputMeter_Impl::setSpecificInstallLocation(const std::string& locationName) + { + ModelObject object = getObject(); + + std::string name = OutputMeter::getName(specificEndUse(), endUseType(), fuelType(), installLocationType(), locationName); + + bool result = object.setString(OS_Output_MeterFields::Name, name); + if (!result){ + LOG(Error, "Could not set name to '" << name << "'"); + } + + return result; + } + + bool OutputMeter_Impl::resetSpecificInstallLocation() + { + return setSpecificInstallLocation(""); + } + + openstudio::OptionalTimeSeries OutputMeter_Impl::getData(const std::string& envPeriod) const + { + return getData(envPeriod, specificInstallLocation()); + } + + openstudio::OptionalTimeSeries OutputMeter_Impl::getData(const std::string& envPeriod, const OptionalString& specificInstallLocation) const + { + openstudio::OptionalTimeSeries result; + OptionalSqlFile sqlFile = model().sqlFile(); + + if (sqlFile){ + ModelObject object = getObject(); + + // get name using specific install location passed in + std::string name; + if (specificInstallLocation){ + name = OutputMeter::getName(specificEndUse(), endUseType(), fuelType(), installLocationType(), boost::to_upper_copy(*specificInstallLocation)); + }else{ + name = OutputMeter::getName(specificEndUse(), endUseType(), fuelType(), installLocationType(), specificInstallLocation); + } + + std::string frequency = this->reportingFrequency(); + if (openstudio::istringEqual(frequency, "RunPeriod")){ + frequency = "Run Period"; + }else if (openstudio::istringEqual(frequency, "Timestep")){ + frequency = "Zone Timestep"; + }else if (openstudio::istringEqual(frequency, "Detailed")){ + frequency = "HVAC System Timestep"; + } + + // currently the key value is not associated with the meter, it is part of the name + result = sqlFile->timeSeries(envPeriod, frequency, name, ""); + + if (!result){ + LOG(Debug, "Query for envPeriod = '" << envPeriod << + "', frequency = '" << frequency << + "', name = '" << name << + "', keyValue = '' did not return a TimeSeries"); + + } + } + + return result; + } + + +} // detail + +OutputMeter::OutputMeter(const Model& model) + : ModelObject(OutputMeter::iddObjectType(),model) +{ + OS_ASSERT(getImpl()); +} + +IddObjectType OutputMeter::iddObjectType() { + IddObjectType result(IddObjectType::OS_Output_Meter); + return result; +} + +boost::regex OutputMeter::meterRegex() +{ + // DLM: Must put more specific terms, e.g. HeatingCoils, before less specific terms, e.g. Heating + const static boost::regex result("^(.*?)?:?(InteriorLights|ExteriorLights|InteriorEquipment|ExteriorEquipment|Fans|Pumps|HeatingCoils|Heating|CoolingCoils|Cooling|HeatRejection|Humidifier|HeatRecoveryForCooling|HeatRecoveryForHeating|HeatRecovery|WaterSystems|Cogeneration|Refrigeration|Chillers|Boilers|Baseboard)?:?(Electricity|Gasoline|Gas|Diesel|Coal|FuelOil_1|FuelOil_2|Propane|Water|Steam|DistrictCooling|DistrictHeating|EnergyTransfer)?:?(Facility|Building|HVAC|Zone|System|Plant)?:?([^:]*?)?$"); + return result; +} + +std::string OutputMeter::getName(const boost::optional& specificEndUseType, + const boost::optional& endUseType, + const boost::optional& fuelType, + const boost::optional& installLocationType, + const boost::optional& specificInstallLocation) +{ + std::string result; + + if (specificEndUseType && !specificEndUseType->empty()){ + result += *specificEndUseType; + } + if (endUseType){ + if (!result.empty()){ + result += ":"; + } + result += EndUseType(*endUseType).valueName(); + } + if (fuelType){ + if (!result.empty()){ + result += ":"; + } + result += FuelType(*fuelType).valueName(); + } + if (installLocationType){ + // there is a weird corner case to handle 'InteriorLights:Electricity:Facility' -> 'InteriorLights:Electricity' + // this might not catch all cases + if (installLocationType.get() != InstallLocationType::Facility || !endUseType){ + if (!result.empty()){ + result += ":"; + } + result += InstallLocationType(*installLocationType).valueName(); + } + } + if (specificInstallLocation && !specificInstallLocation->empty()){ + if (!result.empty()){ + result += ":"; + } + result += *specificInstallLocation; + } + LOG(Debug, "getName result = '" << result << "'"); + return result; +} + +std::string OutputMeter::name() const { + return getImpl()->name(); +} + +std::string OutputMeter::reportingFrequency() const { + return getImpl()->reportingFrequency(); +} + +bool OutputMeter::isReportingFrequencyDefaulted() const { + return getImpl()->isReportingFrequencyDefaulted(); +} + +bool OutputMeter::meterFileOnly() const { + return getImpl()->meterFileOnly(); +} + +bool OutputMeter::isMeterFileOnlyDefaulted() const { + return getImpl()->isMeterFileOnlyDefaulted(); +} + +bool OutputMeter::cumulative() const { + return getImpl()->cumulative(); +} + +bool OutputMeter::isCumulativeDefaulted() const { + return getImpl()->isCumulativeDefaulted(); +} + +boost::optional OutputMeter::specificEndUse() const +{ + return getImpl()->specificEndUse(); +} + +boost::optional OutputMeter::endUseType() const +{ + return getImpl()->endUseType(); +} + +boost::optional OutputMeter::fuelType() const +{ + return getImpl()->fuelType(); +} + +boost::optional OutputMeter::installLocationType() const +{ + return getImpl()->installLocationType(); +} + +boost::optional OutputMeter::specificInstallLocation() const +{ + return getImpl()->specificInstallLocation(); +} + +bool OutputMeter::setName(std::string name) { + return getImpl()->setName(name); +} + +bool OutputMeter::setReportingFrequency(const std::string& reportingFrequency) { + return getImpl()->setReportingFrequency(reportingFrequency); +} + +void OutputMeter::resetReportingFrequency() { + getImpl()->resetReportingFrequency(); +} + +void OutputMeter::setMeterFileOnly(bool meterFileOnly) { + getImpl()->setMeterFileOnly(meterFileOnly); +} + +void OutputMeter::resetMeterFileOnly() { + getImpl()->resetMeterFileOnly(); +} + +void OutputMeter::setCumulative(bool cumulative) { + getImpl()->setCumulative(cumulative); +} + +void OutputMeter::resetCumulative() { + getImpl()->resetCumulative(); +} + +bool OutputMeter::setSpecificEndUse(const std::string& endUse) +{ + return getImpl()->setSpecificEndUse(endUse); +} + +bool OutputMeter::resetSpecificEndUse() +{ + return getImpl()->resetSpecificEndUse(); +} + +bool OutputMeter::setEndUseType(EndUseType type) +{ + return getImpl()->setEndUseType(type); +} + +bool OutputMeter::resetEndUseType() +{ + return getImpl()->resetEndUseType(); +} + +bool OutputMeter::setFuelType(FuelType type) +{ + return getImpl()->setFuelType(type); +} + +bool OutputMeter::resetFuelType() +{ + return getImpl()->resetFuelType(); +} + +bool OutputMeter::setInstallLocationType(InstallLocationType type) +{ + return getImpl()->setInstallLocationType(type); +} + +bool OutputMeter::resetInstallLocationType() +{ + return getImpl()->resetInstallLocationType(); +} + +bool OutputMeter::setSpecificInstallLocation(const std::string& locationName) +{ + return getImpl()->setSpecificInstallLocation(locationName); +} + +bool OutputMeter::resetSpecificInstallLocation() +{ + return getImpl()->resetSpecificInstallLocation(); +} + +openstudio::OptionalTimeSeries OutputMeter::getData(const std::string& envPeriod) const +{ + return getImpl()->getData(envPeriod); +} + +openstudio::OptionalTimeSeries OutputMeter::getData(const std::string& envPeriod, const OptionalString& specificInstallLocation) const +{ + return getImpl()->getData(envPeriod, specificInstallLocation); +} + +bool MeterFuelTypeEquals(const OutputMeter& meter,const FuelType& ft) { + OptionalFuelType oft = meter.fuelType(); + if (oft && (oft.get() == ft)) { return true; } + return false; +} + +/// @cond +OutputMeter::OutputMeter(std::shared_ptr impl) + : ModelObject(impl) +{} +/// @endcond + + +} // model +} // openstudio + diff --git a/openstudiocore/src/model/Meter.hpp b/openstudiocore/src/model/OutputMeter.hpp similarity index 84% rename from openstudiocore/src/model/Meter.hpp rename to openstudiocore/src/model/OutputMeter.hpp index 367455f242f..0b7cc1c063a 100644 --- a/openstudiocore/src/model/Meter.hpp +++ b/openstudiocore/src/model/OutputMeter.hpp @@ -17,8 +17,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **********************************************************************/ -#ifndef MODEL_METER_HPP -#define MODEL_METER_HPP +#ifndef MODEL_OUTPUTMETER_HPP +#define MODEL_OUTPUTMETER_HPP #include "ModelAPI.hpp" #include "ModelObject.hpp" @@ -34,28 +34,28 @@ namespace model { namespace detail { - class Meter_Impl; + class OutputMeter_Impl; } // detail -/** Meter is a ModelObject that wraps the OpenStudio IDD object 'OS_Meter'. +/** OutputMeter is a ModelObject that wraps the OpenStudio IDD object 'OS_Output_Meter'. * - * A Meter is a virtual instrument measuring energy use of some fuel type at a particular location. - * Meter objects may be associated with various classes in the building model hierarchy (e.g. Facility, Building, Zone, Plant, etc). - * A Meter can be used to request output data as well as access it from the EnergyPlus SQLite output. - * If the user wants to access measured data from a particular Meter, they must ensure that input objects are present to + * A OutputMeter is a virtual instrument measuring energy use of some fuel type at a particular location. + * OutputMeter objects may be associated with various classes in the building model hierarchy (e.g. Facility, Building, Zone, Plant, etc). + * A OutputMeter can be used to request output data as well as access it from the EnergyPlus SQLite output. + * If the user wants to access measured data from a particular OutputMeter, they must ensure that input objects are present to * trigger EnergyPlus to output the desired data. This is similar to needing to instrument a real * building during field measurements. * */ -class MODEL_API Meter : public ModelObject { +class MODEL_API OutputMeter : public ModelObject { public: /** @name Constructors and Destructors */ //@{ - explicit Meter(const Model& model); + explicit OutputMeter(const Model& model); - virtual ~Meter() {} + virtual ~OutputMeter() {} //@} /** @name Static Methods */ @@ -183,30 +183,30 @@ class MODEL_API Meter : public ModelObject { protected: /// @cond - typedef detail::Meter_Impl ImplType; + typedef detail::OutputMeter_Impl ImplType; friend class Model; friend class openstudio::IdfObject; - explicit Meter(std::shared_ptr impl); + explicit OutputMeter(std::shared_ptr impl); /// @endcond private: - REGISTER_LOGGER("openstudio.model.Meter"); + REGISTER_LOGGER("openstudio.model.OutputMeter"); }; -/** \relates Meter*/ -typedef boost::optional OptionalMeter; +/** \relates OutputMeter*/ +typedef boost::optional OptionalOutputMeter; -/** \relates Meter*/ -typedef std::vector MeterVector; +/** \relates OutputMeter*/ +typedef std::vector OutputMeterVector; -/** Predicate for finding \link Meter Meters \endlink with fuelType() ft. \relates Meter */ -MODEL_API bool MeterFuelTypeEquals(const Meter& meter, const FuelType& ft); +/** Predicate for finding \link OutputMeter OutputMeters \endlink with fuelType() ft. \relates OutputMeter */ +MODEL_API bool MeterFuelTypeEquals(const OutputMeter& meter, const FuelType& ft); } // model } // openstudio -#endif // MODEL_METER_HPP +#endif // MODEL_OUTPUTMETER_HPP diff --git a/openstudiocore/src/model/Meter_Impl.hpp b/openstudiocore/src/model/OutputMeter_Impl.hpp similarity index 81% rename from openstudiocore/src/model/Meter_Impl.hpp rename to openstudiocore/src/model/OutputMeter_Impl.hpp index ce147552943..589eb002c0a 100644 --- a/openstudiocore/src/model/Meter_Impl.hpp +++ b/openstudiocore/src/model/OutputMeter_Impl.hpp @@ -17,12 +17,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **********************************************************************/ -#ifndef MODEL_METER_IMPL_HPP -#define MODEL_METER_IMPL_HPP +#ifndef MODEL_OUTPUTMETER_IMPL_HPP +#define MODEL_OUTPUTMETER_IMPL_HPP #include "ModelAPI.hpp" #include "ModelObject_Impl.hpp" -#include "Meter.hpp" +#include "OutputMeter.hpp" #include "../utilities/core/StaticInitializer.hpp" @@ -35,12 +35,12 @@ class TimeSeries; namespace model { -class Meter; +class OutputMeter; namespace detail { - /** Meter_Impl is a ModelObject_Impl that is the implementation class for Meter.*/ - class MODEL_API Meter_Impl : public ModelObject_Impl { + /** OutputMeter_Impl is a ModelObject_Impl that is the implementation class for OutputMeter.*/ + class MODEL_API OutputMeter_Impl : public ModelObject_Impl { Q_OBJECT; Q_PROPERTY(std::string name READ name WRITE setName); Q_PROPERTY(std::string reportingFrequency READ reportingFrequency WRITE setReportingFrequency RESET resetReportingFrequency); @@ -53,17 +53,17 @@ namespace detail { /** @name Constructors and Destructors */ //@{ - Meter_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle); + OutputMeter_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle); - Meter_Impl(const openstudio::detail::WorkspaceObject_Impl& other, - Model_Impl* model, - bool keepHandle); + OutputMeter_Impl(const openstudio::detail::WorkspaceObject_Impl& other, + Model_Impl* model, + bool keepHandle); - Meter_Impl(const Meter_Impl& other, - Model_Impl* model, - bool keepHandle); + OutputMeter_Impl(const OutputMeter_Impl& other, + Model_Impl* model, + bool keepHandle); - virtual ~Meter_Impl() {} + virtual ~OutputMeter_Impl() {} //@} @@ -153,23 +153,23 @@ namespace detail { protected: private: - REGISTER_LOGGER("openstudio.model.Meter"); + REGISTER_LOGGER("openstudio.model.OutputMeter"); }; - struct MeterRegexInitializer : StaticInitializer + struct OutputMeterRegexInitializer : StaticInitializer { static void initialize() { - openstudio::model::Meter::meterRegex(); + openstudio::model::OutputMeter::meterRegex(); } }; - struct MakeSureMeterRegexInitializerIsInitialized + struct MakeSureOutputMeterRegexInitializerIsInitialized { - MakeSureMeterRegexInitializerIsInitialized() + MakeSureOutputMeterRegexInitializerIsInitialized() {} - MeterRegexInitializer m_i; + OutputMeterRegexInitializer m_i; }; } // detail @@ -177,5 +177,5 @@ namespace detail { } // model } // openstudio -#endif // MODEL_METER_IMPL_HPP +#endif // MODEL_OUTPUTMETER_IMPL_HPP diff --git a/openstudiocore/src/model/ScheduleTypeRegistry.cpp b/openstudiocore/src/model/ScheduleTypeRegistry.cpp index b6ddfc2a087..b6c7418b88b 100644 --- a/openstudiocore/src/model/ScheduleTypeRegistry.cpp +++ b/openstudiocore/src/model/ScheduleTypeRegistry.cpp @@ -228,9 +228,13 @@ ScheduleTypeRegistrySingleton::ScheduleTypeRegistrySingleton() {"DefaultScheduleSet","Other Equipment","otherEquipmentSchedule",true,"",OptionalDouble(),OptionalDouble()}, {"DesignSpecificationOutdoorAir","Outdoor Air Flow Rate","outdoorAirFlowRateFractionSchedule",true,"",0.0,1.0}, {"ElectricEquipment","Electric Equipment","schedule",true,"",0.0,1.0}, - // TODO: when we wrap this field { "ElectricLoadCenterDistribution", "Track Scheme", "trackScheduleSchemeSchedule", , , , }, + {"ElectricLoadCenterDistribution", "Track Scheme", "trackScheduleSchemeSchedule",true,"",0.0,OptionalDouble()}, + {"ElectricLoadCenterDistribution", "Storage Charge Power Fraction", "storageChargePowerFractionSchedule",true,"",0.0,1.0}, + {"ElectricLoadCenterDistribution", "Storage Discharge Power Fraction", "storageDischargePowerFractionSchedule",true,"",0.0,1.0}, + {"ElectricLoadCenterDistribution", "Storage Control Utility Demand Target Fraction", "storageControlUtilityDemandTargetFractionScheduleName",true,"",-1.0,1.0}, {"ElectricLoadCenterInverterLookUpTable","Availability","availabilitySchedule",false,"Availability",0.0,1.0}, {"ElectricLoadCenterInverterSimple","Availability","availabilitySchedule",false,"Availability",0.0,1.0}, + {"ElectricLoadCenterStorageSimple","Availability","availabilitySchedule",false,"Availability",0.0,1.0}, {"EvaporativeCoolerDirectResearchSpecial","Availability","availabilitySchedule",false,"Availability",0.0,1.0}, {"EvaporativeCoolerIndirectResearchSpecial","Availability","availabilitySchedule",false,"Availability",0.0,1.0}, {"EvaporativeFluidCoolerSingleSpeed","Blowdown Makeup Water Usage","blowdownMakeupWaterUsageSchedule",true,"VolumetricFlowRate",0.0,OptionalDouble()}, @@ -244,6 +248,7 @@ ScheduleTypeRegistrySingleton::ScheduleTypeRegistrySingleton() {"FanZoneExhaust","Minimum Zone Temperature Limit","minimumZoneTemperatureLimitSchedule",true,"Temperature",OptionalDouble(),OptionalDouble()}, {"FanZoneExhaust","Balanced Exhaust Fraction","balancedExhaustFractionSchedule",true,"Dimensionless",0.0,1.0}, {"GasEquipment","Gas Equipment","schedule",true,"",0.0,1.0}, + {"GeneratorMicroTurbine","Availability","availabilitySchedule",false,"Availability",0.0,1.0}, {"GeneratorPhotovoltaic","Availability","availabilitySchedule",false,"Availability",0.0,1.0}, {"HeatExchangerAirToAirSensibleAndLatent","Availability","availabilitySchedule",false,"Availability",0.0,1.0}, {"HeatExchangerFluidToFluid","Availability","availabilitySchedule",false,"Availability",0.0,1.0}, @@ -262,8 +267,8 @@ ScheduleTypeRegistrySingleton::ScheduleTypeRegistrySingleton() {"People","Air Velocity","airVelocitySchedule",true,"Velocity",0.0,OptionalDouble()}, {"PhotovoltaicPerformanceSimple","Efficiency","efficiencySchedule",true,"",0.0,1.0}, {"PlantComponentTemperatureSource","Source Temperature","sourceTemperatureSchedule",true,"Temperature",OptionalDouble(),OptionalDouble()}, - { "PipeIndoor", "Ambient Temperature", "ambientTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble() }, - { "PipeIndoor", "Ambient Air Velocity", "ambientAirVelocitySchedule", true, "Velocity", 0.0, OptionalDouble() }, + {"PipeIndoor", "Ambient Temperature", "ambientTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble() }, + {"PipeIndoor", "Ambient Air Velocity", "ambientAirVelocitySchedule", true, "Velocity", 0.0, OptionalDouble() }, {"PumpConstantSpeed","Pump Flow Rate","pumpFlowRateSchedule",true,"",0.0,1.0}, {"PumpVariableSpeed","Pump Flow Rate","pumpFlowRateSchedule",true,"",0.0,1.0}, {"PumpVariableSpeed","Pump RPM","pumpRPMSchedule",true,"RotationsPerMinute",OptionalDouble(),OptionalDouble()}, @@ -384,14 +389,14 @@ ScheduleTypeRegistrySingleton::ScheduleTypeRegistrySingleton() {"ZoneHVACUnitVentilator","Minimum Outdoor Air","minimumOutdoorAirSchedule",true,"",0.0,1.0}, {"ZoneHVACUnitVentilator","Maximum Outdoor Air Fraction or Temperature","maximumOutdoorAirFractionorTemperatureSchedule",true,"",OptionalDouble(),OptionalDouble()}, {"ZoneHVACUnitVentilator","Supply Air Fan Operating Mode","supplyAirFanOperatingModeSchedule",false,"ControlMode",0.0,1.0}, - { "ZoneMixing", "Zone Mixing", "schedule", true, "Dimensionless", 0.0, 1.0}, - { "ZoneMixing", "Delta Temperature", "deltaTemperatureSchedule", true, "DeltaTemperature", OptionalDouble(), OptionalDouble() }, - { "ZoneMixing", "Minimum Zone Temperature", "minimumZoneTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble() }, - { "ZoneMixing", "Maximum Zone Temperature", "maximumZoneTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble() }, - { "ZoneMixing", "Minimum Source Zone Temperature", "minimumSourceZoneTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble() }, - { "ZoneMixing", "Maximum Source Zone Temperature", "maximumSourceZoneTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble() }, - { "ZoneMixing", "Minimum Outdoor Temperature", "minimumOutdoorTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble() }, - { "ZoneMixing", "Maximum Outdoor Temperature", "maximumOutdoorTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble() }, + {"ZoneMixing", "Zone Mixing", "schedule", true, "Dimensionless", 0.0, 1.0}, + {"ZoneMixing", "Delta Temperature", "deltaTemperatureSchedule", true, "DeltaTemperature", OptionalDouble(), OptionalDouble() }, + {"ZoneMixing", "Minimum Zone Temperature", "minimumZoneTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble() }, + {"ZoneMixing", "Maximum Zone Temperature", "maximumZoneTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble() }, + {"ZoneMixing", "Minimum Source Zone Temperature", "minimumSourceZoneTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble() }, + {"ZoneMixing", "Maximum Source Zone Temperature", "maximumSourceZoneTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble() }, + {"ZoneMixing", "Minimum Outdoor Temperature", "minimumOutdoorTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble() }, + {"ZoneMixing", "Maximum Outdoor Temperature", "maximumOutdoorTemperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble() }, {"","","",true,"",OptionalDouble(),OptionalDouble()} }; diff --git a/openstudiocore/src/model/UtilityBill.cpp b/openstudiocore/src/model/UtilityBill.cpp index fceb747b4ba..60aa88772e8 100644 --- a/openstudiocore/src/model/UtilityBill.cpp +++ b/openstudiocore/src/model/UtilityBill.cpp @@ -19,8 +19,8 @@ #include "UtilityBill.hpp" #include "UtilityBill_Impl.hpp" -#include "Meter.hpp" -#include "Meter_Impl.hpp" +#include "OutputMeter.hpp" +#include "OutputMeter_Impl.hpp" #include "RunPeriod.hpp" #include "RunPeriod_Impl.hpp" #include "YearDescription.hpp" @@ -692,7 +692,7 @@ namespace detail { return result; } - Meter UtilityBill_Impl::consumptionMeter() const{ + OutputMeter UtilityBill_Impl::consumptionMeter() const{ FuelType fuelType = this->fuelType(); InstallLocationType meterInstallLocation = this->meterInstallLocation(); boost::optional meterSpecificInstallLocation = this->meterSpecificInstallLocation(); @@ -703,21 +703,21 @@ namespace detail { } boost::optional meterSpecificEndUse = this->meterSpecificEndUse(); - std::string meterName = Meter::getName(meterSpecificEndUse, - meterEndUse, - fuelType, - meterInstallLocation, - meterSpecificInstallLocation); + std::string meterName = OutputMeter::getName(meterSpecificEndUse, + meterEndUse, + fuelType, + meterInstallLocation, + meterSpecificInstallLocation); - boost::optional result; - for (const Meter& meter : this->model().getConcreteModelObjects()){ + boost::optional result; + for (const OutputMeter& meter : this->model().getConcreteModelObjects()){ if ((istringEqual(meter.name(), meterName)) && (istringEqual("Daily", meter.reportingFrequency()))){ return meter; } } - result = Meter(this->model()); + result = OutputMeter(this->model()); result->setReportingFrequency("Daily"); result->setFuelType(fuelType); result->setInstallLocationType(meterInstallLocation); @@ -734,7 +734,7 @@ namespace detail { return result.get(); } - boost::optional UtilityBill_Impl::peakDemandMeter() const{ + boost::optional UtilityBill_Impl::peakDemandMeter() const{ FuelType fuelType = this->fuelType(); InstallLocationType meterInstallLocation = this->meterInstallLocation(); boost::optional meterSpecificInstallLocation = this->meterSpecificInstallLocation(); @@ -749,21 +749,21 @@ namespace detail { return boost::none; } - std::string meterName = Meter::getName(meterSpecificEndUse, - meterEndUse, - fuelType, - meterInstallLocation, - meterSpecificInstallLocation); + std::string meterName = OutputMeter::getName(meterSpecificEndUse, + meterEndUse, + fuelType, + meterInstallLocation, + meterSpecificInstallLocation); - boost::optional result; - for (const Meter& meter : this->model().getConcreteModelObjects()){ + boost::optional result; + for (const OutputMeter& meter : this->model().getConcreteModelObjects()){ if ((istringEqual(meter.name(), meterName)) && (istringEqual("Timestep", meter.reportingFrequency()))){ return meter; } } - result = Meter(this->model()); + result = OutputMeter(this->model()); result->setReportingFrequency("Timestep"); result->setFuelType(fuelType); result->setInstallLocationType(meterInstallLocation); @@ -1174,7 +1174,7 @@ Vector BillingPeriod::modelConsumptionValues() const Vector result; - Meter meter = getImpl()->consumptionMeter(); + OutputMeter meter = getImpl()->consumptionMeter(); Date runPeriodStartDate = Date(runPeriod->getBeginMonth(), runPeriod->getBeginDayOfMonth(), *calendarYear); Date runPeriodEndDate = Date(runPeriod->getEndMonth(), runPeriod->getEndDayOfMonth(), *calendarYear); @@ -1248,7 +1248,7 @@ boost::optional BillingPeriod::modelPeakDemand() const return boost::none; } - boost::optional meter = getImpl()->peakDemandMeter(); + boost::optional meter = getImpl()->peakDemandMeter(); if (!meter){ return boost::none; } @@ -1511,11 +1511,11 @@ void UtilityBill::resetTimestepsInPeakDemandWindow(){ getImpl()->resetTimestepsInPeakDemandWindow(); } -Meter UtilityBill::consumptionMeter() const{ +OutputMeter UtilityBill::consumptionMeter() const{ return getImpl()->consumptionMeter(); } -boost::optional UtilityBill::peakDemandMeter() const{ +boost::optional UtilityBill::peakDemandMeter() const{ return getImpl()->peakDemandMeter(); } diff --git a/openstudiocore/src/model/UtilityBill.hpp b/openstudiocore/src/model/UtilityBill.hpp index 7cba97047c0..373580165cd 100644 --- a/openstudiocore/src/model/UtilityBill.hpp +++ b/openstudiocore/src/model/UtilityBill.hpp @@ -35,7 +35,7 @@ class Date; namespace model { -class Meter; +class OutputMeter; namespace detail { @@ -248,10 +248,10 @@ class MODEL_API UtilityBill : public ModelObject { //@{ /** Gets the meter associated with consumption for this UtilityBill, creates it if it does not exist.*/ - Meter consumptionMeter() const; + OutputMeter consumptionMeter() const; /** Gets the meter associated with peak demand for this UtilityBill, creates it if it does not exist.*/ - boost::optional peakDemandMeter() const; + boost::optional peakDemandMeter() const; /** Number of billing periods used to compute CVRMSE or NMBE.*/ unsigned numberBillingPeriodsInCalculations() const; diff --git a/openstudiocore/src/model/UtilityBill_Impl.hpp b/openstudiocore/src/model/UtilityBill_Impl.hpp index 7f54fef74e4..497ff0784ff 100644 --- a/openstudiocore/src/model/UtilityBill_Impl.hpp +++ b/openstudiocore/src/model/UtilityBill_Impl.hpp @@ -147,9 +147,9 @@ namespace detail { /** @name Other */ //@{ - Meter consumptionMeter() const; + OutputMeter consumptionMeter() const; - boost::optional peakDemandMeter() const; + boost::optional peakDemandMeter() const; unsigned numberBillingPeriodsInCalculations() const; diff --git a/openstudiocore/src/model/test/ElectricLoadCenterDistribution_GTest.cpp b/openstudiocore/src/model/test/ElectricLoadCenterDistribution_GTest.cpp index 9f67aa586dc..d4aff632d18 100644 --- a/openstudiocore/src/model/test/ElectricLoadCenterDistribution_GTest.cpp +++ b/openstudiocore/src/model/test/ElectricLoadCenterDistribution_GTest.cpp @@ -19,10 +19,14 @@ #include #include "ModelFixture.hpp" +#include "../Schedule.hpp" +#include "../ScheduleCompact.hpp" #include "../ElectricLoadCenterDistribution.hpp" #include "../GeneratorPhotovoltaic.hpp" +//#include "../GeneratorMicroTurbine.hpp" // In a different branch right now... #include "../ElectricLoadCenterInverterSimple.hpp" #include "../ElectricLoadCenterInverterLookUpTable.hpp" +#include "../ElectricLoadCenterStorageSimple.hpp" using namespace openstudio::model; @@ -173,4 +177,219 @@ TEST_F(ModelFixture, ElectricLoadCenterDistribution_Inverters2) { EXPECT_TRUE(elcd2.inverter()); ASSERT_TRUE(inverter.electricLoadCenterDistribution()); EXPECT_EQ(elcd2.handle(), inverter.electricLoadCenterDistribution()->handle()); +} + +TEST_F(ModelFixture, ElectricLoadCenterDistribution_newFields) { + + Model model; + + ElectricLoadCenterDistribution elcd(model); + EXPECT_EQ(0u, elcd.generators().size()); + EXPECT_EQ("Baseload", elcd.generatorOperationSchemeType()); + EXPECT_TRUE(elcd.isGeneratorOperationSchemeTypeDefaulted()); + EXPECT_EQ("DirectCurrentWithInverter", elcd.electricalBussType()); + EXPECT_TRUE(elcd.isElectricalBussTypeDefaulted()); + EXPECT_FALSE(elcd.inverter()); + + EXPECT_TRUE(elcd.setGeneratorOperationSchemeType("FollowThermal")); + EXPECT_EQ("FollowThermal", elcd.generatorOperationSchemeType()); + EXPECT_FALSE(elcd.isGeneratorOperationSchemeTypeDefaulted()); + elcd.resetGeneratorOperationSchemeType(); + EXPECT_TRUE(elcd.isGeneratorOperationSchemeTypeDefaulted()); + + /* GeneratorMicroTurbine mt(model); + GeneratorPhotovoltaic pv(model); + EXPECT_TRUE(elcd.addGenerator(mt)); + ASSERT_EQ(1u, elcd.generators().size()); + EXPECT_EQ(mt.handle(), elcd.generators()[0].handle()); + EXPECT_TRUE(elcd.addGenerator(pv)); + ASSERT_EQ(2u, elcd.generators().size()); + EXPECT_EQ(mt.handle(), elcd.generators()[0].handle()); + EXPECT_EQ(pv.handle(), elcd.generators()[1].handle()); + EXPECT_TRUE(elcd.removeGenerator(mt)); + ASSERT_EQ(1u, elcd.generators().size()); + EXPECT_EQ(panel2.handle(), elcd.generators()[0].handle()); + EXPECT_TRUE(elcd.removeGenerator(pv)); + ASSERT_EQ(0u, elcd.generators().size()); + + // can't remove something not already there + EXPECT_FALSE(elcd.removeGenerator(pv)); + + // can't add something twice + EXPECT_TRUE(elcd.addGenerator(mt)); + EXPECT_FALSE(elcd.addGenerator(mt)); */ + + GeneratorPhotovoltaic panel1 = GeneratorPhotovoltaic::simple(model); + GeneratorPhotovoltaic panel2 = GeneratorPhotovoltaic::simple(model); + EXPECT_TRUE(elcd.addGenerator(panel1)); + ASSERT_EQ(1u, elcd.generators().size()); + EXPECT_EQ(panel1.handle(), elcd.generators()[0].handle()); + EXPECT_TRUE(elcd.addGenerator(panel2)); + ASSERT_EQ(2u, elcd.generators().size()); + EXPECT_EQ(panel1.handle(), elcd.generators()[0].handle()); + EXPECT_EQ(panel2.handle(), elcd.generators()[1].handle()); + EXPECT_TRUE(elcd.removeGenerator(panel1)); + ASSERT_EQ(1u, elcd.generators().size()); + EXPECT_EQ(panel2.handle(), elcd.generators()[0].handle()); + EXPECT_TRUE(elcd.removeGenerator(panel2)); + ASSERT_EQ(0u, elcd.generators().size()); + + // can't remove something not already there + EXPECT_FALSE(elcd.removeGenerator(panel1)); + + // can't add something twice + EXPECT_TRUE(elcd.addGenerator(panel1)); + EXPECT_FALSE(elcd.addGenerator(panel1)); + + + // Demand Limit Scheme Purchased Electric Demand Limit, Optional + EXPECT_FALSE(elcd.demandLimitSchemePurchasedElectricDemandLimit()); + EXPECT_TRUE(elcd.setDemandLimitSchemePurchasedElectricDemandLimit(100500)); + ASSERT_TRUE(elcd.demandLimitSchemePurchasedElectricDemandLimit()); + EXPECT_EQ(100500, elcd.demandLimitSchemePurchasedElectricDemandLimit().get()); + elcd.resetDemandLimitSchemePurchasedElectricDemandLimit(); + ASSERT_FALSE(elcd.demandLimitSchemePurchasedElectricDemandLimit()); + + // Generator Track Schedule Name Scheme Schedule Name, Optional + Schedule sch = model.alwaysOnDiscreteSchedule(); + EXPECT_FALSE(elcd.trackScheduleSchemeSchedule()); + EXPECT_TRUE(elcd.setTrackScheduleSchemeSchedule(sch)); + ASSERT_TRUE(elcd.trackScheduleSchemeSchedule()); + EXPECT_EQ(sch.handle(), (elcd.trackScheduleSchemeSchedule())->handle()); + elcd.resetTrackScheduleSchemeSchedule(); + ASSERT_FALSE(elcd.trackScheduleSchemeSchedule()); + + // Generator Track Meter Scheme Meter Name, Optional String + EXPECT_FALSE(elcd.trackMeterSchemeMeterName()); + EXPECT_TRUE(elcd.setTrackMeterSchemeMeterName("Electricity:Facility")); + ASSERT_TRUE(elcd.trackMeterSchemeMeterName()); + ASSERT_EQ("Electricity:Facility", elcd.trackMeterSchemeMeterName().get()); + elcd.resetTrackMeterSchemeMeterName(); + ASSERT_FALSE(elcd.trackMeterSchemeMeterName()); + + // Electrical Buss type, defaults to DirectCurrentWithInverter + EXPECT_EQ("DirectCurrentWithInverter", elcd.electricalBussType()); + EXPECT_TRUE(elcd.isElectricalBussTypeDefaulted()); + EXPECT_TRUE(elcd.setElectricalBussType("AlternatingCurrentWithStorage")); + ASSERT_FALSE(elcd.isElectricalBussTypeDefaulted()); + ASSERT_EQ("AlternatingCurrentWithStorage", elcd.electricalBussType()); + elcd.resetElectricalBussType(); + ASSERT_TRUE(elcd.isElectricalBussTypeDefaulted()); + + + + // Test inverter + ElectricLoadCenterInverterSimple inverter(model); + EXPECT_TRUE(inverter.name()); + EXPECT_TRUE(elcd.setInverter(inverter)); + ASSERT_TRUE(elcd.inverter()); + EXPECT_EQ(inverter.handle(), elcd.inverter()->handle()); + elcd.resetInverter(); + ASSERT_FALSE(elcd.inverter()); + + // Test Storage + ElectricLoadCenterStorageSimple battery(model); + ASSERT_FALSE(elcd.electricalStorage()); + EXPECT_TRUE(battery.name()); + EXPECT_TRUE(elcd.setElectricalStorage(battery)); + ASSERT_TRUE(elcd.electricalStorage()); + EXPECT_EQ(battery.handle(), elcd.electricalStorage()->handle()); + elcd.resetElectricalStorage(); + ASSERT_FALSE(elcd.electricalStorage()); + + // Test Transformer: not yet + + + // Storage Operation Scheme, defaults + EXPECT_TRUE(elcd.isStorageOperationSchemeDefaulted()); + EXPECT_EQ("TrackFacilityElectricDemandStoreExcessOnSite", elcd.storageOperationScheme()); + ASSERT_TRUE(elcd.setStorageOperationScheme("FacilityDemandLeveling")); + ASSERT_FALSE(elcd.isStorageOperationSchemeDefaulted()); + ASSERT_EQ("FacilityDemandLeveling", elcd.storageOperationScheme()); + elcd.resetStorageOperationScheme(); + ASSERT_TRUE(elcd.isStorageOperationSchemeDefaulted()); + + // Storage Control Track Meter Name, Optional String + EXPECT_FALSE(elcd.storageControlTrackMeterName()); + ASSERT_TRUE(elcd.setStorageControlTrackMeterName("Electricity:Building")); + ASSERT_TRUE(elcd.storageControlTrackMeterName()); + ASSERT_EQ("Electricity:Building", elcd.storageControlTrackMeterName().get()); + elcd.resetStorageControlTrackMeterName(); + EXPECT_FALSE(elcd.storageControlTrackMeterName()); + + // Storage Converter: not yet + + + // Maximum Storage State of Charge Fraction, defaults + EXPECT_TRUE( elcd.isMaximumStorageStateofChargeFractionDefaulted() ); + EXPECT_EQ(1.0, elcd.maximumStorageStateofChargeFraction()); + ASSERT_TRUE(elcd.setMaximumStorageStateofChargeFraction(0.85)); + ASSERT_FALSE( elcd.isMaximumStorageStateofChargeFractionDefaulted() ); + ASSERT_EQ(0.85, elcd.maximumStorageStateofChargeFraction()); + elcd.resetMaximumStorageStateofChargeFraction(); + ASSERT_TRUE( elcd.isMaximumStorageStateofChargeFractionDefaulted() ); + + // Minimum Storage State of Charge Fraction, defaults + EXPECT_TRUE( elcd.isMinimumStorageStateofChargeFractionDefaulted() ); + EXPECT_EQ(0.0, elcd.minimumStorageStateofChargeFraction()); + ASSERT_TRUE(elcd.setMinimumStorageStateofChargeFraction(0.05)); + ASSERT_FALSE( elcd.isMinimumStorageStateofChargeFractionDefaulted() ); + ASSERT_EQ(0.05, elcd.minimumStorageStateofChargeFraction()); + elcd.resetMinimumStorageStateofChargeFraction(); + ASSERT_TRUE( elcd.isMinimumStorageStateofChargeFractionDefaulted() ); + + + // Design Storage Control Charge Power, Optional Double + EXPECT_FALSE(elcd.designStorageControlChargePower()); + EXPECT_TRUE(elcd.setDesignStorageControlChargePower(100000)); + ASSERT_TRUE(elcd.designStorageControlChargePower()); + EXPECT_EQ(100000, elcd.designStorageControlChargePower().get()); + elcd.resetDesignStorageControlChargePower(); + ASSERT_FALSE(elcd.designStorageControlChargePower()); + + // Storage Charge Power Fraction Schedule Name, optional Schedule + ScheduleCompact schChP = ScheduleCompact(model); + EXPECT_FALSE(elcd.storageChargePowerFractionSchedule()); + EXPECT_TRUE(elcd.setStorageChargePowerFractionSchedule(schChP)); + ASSERT_TRUE(elcd.storageChargePowerFractionSchedule()); + EXPECT_EQ(schChP.handle(), elcd.storageChargePowerFractionSchedule()->handle()); + elcd.resetStorageChargePowerFractionSchedule(); + ASSERT_FALSE(elcd.storageChargePowerFractionSchedule()); + + // Design Storage Control Discharge Power, Optional Double + EXPECT_FALSE(elcd.designStorageControlDischargePower()); + EXPECT_TRUE(elcd.setDesignStorageControlDischargePower(100000)); + ASSERT_TRUE(elcd.designStorageControlDischargePower()); + EXPECT_EQ(100000, elcd.designStorageControlDischargePower().get()); + elcd.resetDesignStorageControlDischargePower(); + ASSERT_FALSE(elcd.designStorageControlDischargePower()); + + // Storage Discharge Power Fraction Schedule Name, optional Schedule + ScheduleCompact schDisChP = ScheduleCompact(model); + EXPECT_FALSE(elcd.storageDischargePowerFractionSchedule()); + EXPECT_TRUE(elcd.setStorageDischargePowerFractionSchedule(schDisChP)); + ASSERT_TRUE(elcd.storageDischargePowerFractionSchedule()); + EXPECT_EQ(schDisChP.handle(), elcd.storageDischargePowerFractionSchedule()->handle()); + elcd.resetStorageDischargePowerFractionSchedule(); + ASSERT_FALSE(elcd.storageDischargePowerFractionSchedule()); + + // Storage Control Utility Demand Target, optional double + EXPECT_FALSE(elcd.storageControlUtilityDemandTarget()); + EXPECT_TRUE(elcd.setStorageControlUtilityDemandTarget(50000)); + ASSERT_TRUE(elcd.storageControlUtilityDemandTarget()); + EXPECT_EQ(50000, elcd.storageControlUtilityDemandTarget().get()); + elcd.resetStorageControlUtilityDemandTarget(); + ASSERT_FALSE(elcd.storageControlUtilityDemandTarget()); + + // Storage Control Utility Demand Target Fraction Schedule, defaults to alwaysOnDiscrete + ScheduleCompact schSControl = ScheduleCompact(model); + EXPECT_TRUE( elcd.isStorageControlUtilityDemandTargetFractionScheduleDefaulted() ); + EXPECT_EQ(model.alwaysOnDiscreteSchedule().handle(), elcd.storageControlUtilityDemandTargetFractionSchedule().handle()); + EXPECT_TRUE(elcd.setStorageControlUtilityDemandTargetFractionSchedule(schSControl)); + ASSERT_FALSE( elcd.isStorageControlUtilityDemandTargetFractionScheduleDefaulted() ); + EXPECT_EQ(schSControl.handle(), elcd.storageControlUtilityDemandTargetFractionSchedule().handle()); + elcd.resetStorageControlUtilityDemandTargetFractionSchedule(); + ASSERT_TRUE( elcd.isStorageControlUtilityDemandTargetFractionScheduleDefaulted() ); + + } \ No newline at end of file diff --git a/openstudiocore/src/model/test/ElectricLoadCenterStorageSimple_GTest.cpp b/openstudiocore/src/model/test/ElectricLoadCenterStorageSimple_GTest.cpp new file mode 100644 index 00000000000..d1f8f93a144 --- /dev/null +++ b/openstudiocore/src/model/test/ElectricLoadCenterStorageSimple_GTest.cpp @@ -0,0 +1,104 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include + +#include + +#include "../ElectricLoadCenterStorageSimple.hpp" +#include "../ElectricLoadCenterStorageSimple_Impl.hpp" +#include "../Schedule.hpp" +#include "../ScheduleCompact.hpp" + + +using namespace openstudio; +using namespace openstudio::model; + +TEST_F(ModelFixture, ElectricLoadCenterStorageSimple_Instantiate) { + + Model model; + ThermalZone thermalZone(model); + + ElectricLoadCenterStorageSimple elcStorSimple(model); + + // Availability Schedule, defaults to model.alwaysOnDiscrete + EXPECT_EQ(elcStorSimple.availabilitySchedule(), model.alwaysOnDiscreteSchedule()); + ScheduleCompact scheduleCompact(model); + EXPECT_TRUE(elcStorSimple.setAvailabilitySchedule(scheduleCompact)); + EXPECT_EQ(elcStorSimple.availabilitySchedule(), scheduleCompact); + elcStorSimple.resetAvailabilitySchedule(); + EXPECT_EQ(elcStorSimple.availabilitySchedule(), model.alwaysOnDiscreteSchedule()); + + // ZoneName + EXPECT_FALSE(elcStorSimple.thermalZone()); + EXPECT_TRUE(elcStorSimple.setThermalZone(thermalZone)); + ASSERT_TRUE(elcStorSimple.thermalZone()); + + // Radiative Fraction, defaults + EXPECT_TRUE(elcStorSimple.isRadiativeFractionforZoneHeatGainsDefaulted()); + EXPECT_TRUE(elcStorSimple.setRadiativeFractionforZoneHeatGains(0.3)); + EXPECT_FALSE(elcStorSimple.isRadiativeFractionforZoneHeatGainsDefaulted()); + EXPECT_EQ(elcStorSimple.radiativeFractionforZoneHeatGains(), 0.3); + elcStorSimple.resetRadiativeFractionforZoneHeatGains(); + EXPECT_TRUE(elcStorSimple.isRadiativeFractionforZoneHeatGainsDefaulted()); + + // nominalEnergeticEfficiencyforCharging, defaults + EXPECT_FALSE(elcStorSimple.isNominalEnergeticEfficiencyforChargingDefaulted()); + EXPECT_TRUE(elcStorSimple.setNominalEnergeticEfficiencyforCharging(0.875)); + EXPECT_FALSE(elcStorSimple.isNominalEnergeticEfficiencyforChargingDefaulted()); + EXPECT_EQ(elcStorSimple.nominalEnergeticEfficiencyforCharging(), 0.875); + elcStorSimple.resetNominalEnergeticEfficiencyforCharging(); + EXPECT_TRUE(elcStorSimple.isNominalEnergeticEfficiencyforChargingDefaulted()); + + // nominalEnergeticEfficiencyforDischarging, defaults + EXPECT_FALSE(elcStorSimple.isNominalDischargingEnergeticEfficiencyDefaulted()); + EXPECT_TRUE(elcStorSimple.setNominalDischargingEnergeticEfficiency(0.855)); + EXPECT_FALSE(elcStorSimple.isNominalDischargingEnergeticEfficiencyDefaulted()); + EXPECT_EQ(elcStorSimple.nominalDischargingEnergeticEfficiency(), 0.855); + elcStorSimple.resetNominalDischargingEnergeticEfficiency(); + EXPECT_TRUE(elcStorSimple.isNominalDischargingEnergeticEfficiencyDefaulted()); + + // maximumStorageCapacity, required, assigned in ctor + EXPECT_TRUE(elcStorSimple.maximumStorageCapacity()); + EXPECT_EQ(1.0E13, elcStorSimple.maximumStorageCapacity()); + EXPECT_TRUE(elcStorSimple.setMaximumStorageCapacity(1.0E12)); + EXPECT_EQ(1.0E12, elcStorSimple.maximumStorageCapacity()); + + // maximumPowerforDischarging, required, assigned in ctor + EXPECT_TRUE(elcStorSimple.maximumPowerforDischarging()); + EXPECT_EQ(1.0E6, elcStorSimple.maximumPowerforDischarging()); + EXPECT_TRUE(elcStorSimple.setMaximumPowerforDischarging(1.8E6)); + EXPECT_EQ(1.8E6, elcStorSimple.maximumPowerforDischarging()); + + // maximumPowerforCharging, required, assigned in ctor + EXPECT_TRUE(elcStorSimple.maximumPowerforCharging()); + EXPECT_EQ(1.0E6, elcStorSimple.maximumPowerforCharging()); + EXPECT_TRUE(elcStorSimple.setMaximumPowerforCharging(1.5E6)); + EXPECT_EQ(1.5E6, elcStorSimple.maximumPowerforCharging()); + + // Initial State of Charge + EXPECT_TRUE(elcStorSimple.isInitialStateofChargeDefaulted()); + EXPECT_EQ(elcStorSimple.initialStateofCharge(), elcStorSimple.maximumStorageCapacity() / 2.0); + EXPECT_TRUE(elcStorSimple.setInitialStateofCharge(1E5)); + EXPECT_FALSE(elcStorSimple.isInitialStateofChargeDefaulted()); + EXPECT_EQ(elcStorSimple.initialStateofCharge(), 1E5); + elcStorSimple.resetInitialStateofCharge(); + EXPECT_TRUE(elcStorSimple.isInitialStateofChargeDefaulted()); + +} \ No newline at end of file diff --git a/openstudiocore/src/model/test/Facility_GTest.cpp b/openstudiocore/src/model/test/Facility_GTest.cpp index 1c471d27ea4..a06811cbd28 100644 --- a/openstudiocore/src/model/test/Facility_GTest.cpp +++ b/openstudiocore/src/model/test/Facility_GTest.cpp @@ -25,8 +25,8 @@ #include "../ComponentCostAdjustments_Impl.hpp" #include "../Facility.hpp" #include "../Facility_Impl.hpp" -#include "../Meter.hpp" -#include "../Meter_Impl.hpp" +#include "../OutputMeter.hpp" +#include "../OutputMeter_Impl.hpp" #include "../RunPeriod.hpp" #include "../RunPeriod_Impl.hpp" #include "../LifeCycleCostParameters.hpp" @@ -516,10 +516,10 @@ TEST_F(ModelFixture, Facility_EconomicsTest_EmptyModel) { EXPECT_EQ(0u, facility.meters().size()); - boost::optional electricMeter = facility.getMeterByFuelType(FuelType::Electricity, "Hourly"); + boost::optional electricMeter = facility.getMeterByFuelType(FuelType::Electricity, "Hourly"); EXPECT_FALSE(electricMeter); - Meter meter(model); + OutputMeter meter(model); meter.setFuelType(FuelType::Electricity); meter.setInstallLocationType(InstallLocationType::Facility); meter.setReportingFrequency("Hourly"); diff --git a/openstudiocore/src/model/test/GeneratorMicroTurbine_GTest.cpp b/openstudiocore/src/model/test/GeneratorMicroTurbine_GTest.cpp new file mode 100644 index 00000000000..64787c528df --- /dev/null +++ b/openstudiocore/src/model/test/GeneratorMicroTurbine_GTest.cpp @@ -0,0 +1,557 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include + +#include + +#include "../Model.hpp" + +// Need the Generator:MicroTurbine, the Generator:MicroTurbine:HeatRecovery and an ElectricalLoadCenterDistribution object +#include "../GeneratorMicroTurbine.hpp" +#include "../GeneratorMicroTurbine_Impl.hpp" +#include "../GeneratorMicroTurbineHeatRecovery.hpp" +#include "../GeneratorMicroTurbineHeatRecovery_Impl.hpp" +#include "../Schedule.hpp" +#include "../ElectricLoadCenterDistribution.hpp" + +// Curves +#include "../Curve.hpp" +#include "../CurveBiquadratic.hpp" +#include "../CurveBiquadratic_Impl.hpp" +#include "../CurveCubic.hpp" +#include "../CurveCubic_Impl.hpp" +#include "../CurveQuadratic.hpp" +#include "../CurveQuadratic_Impl.hpp" + + + +// PlantLoop and Node for Heat Recovery module (and AirLoop to make sure you can't put it on one) +#include "../AirLoopHVAC.hpp" +#include "../AirLoopHVACZoneSplitter.hpp" +#include "../PlantLoop.hpp" +#include "../Node.hpp" +#include "../Node_Impl.hpp" + + +using namespace openstudio; +using namespace openstudio::model; + +//Test construction of the GeneratorMicroTurbine, then check that fields in default constructor +//are being set to the expected values +TEST_F(ModelFixture, GeneratorMicroTurbine_DefaultsSettersGetters) { + + //create a model to use in testing this code. + Model model; + + // test constructor for Generator:MicroTurbine + GeneratorMicroTurbine mchp = GeneratorMicroTurbine(model); + + // Test default values that I've set in the constructors + // Reference Electrical Power Output + ASSERT_EQ(65000, mchp.referenceElectricalPowerOutput()); + mchp.setReferenceElectricalPowerOutput(60000); + ASSERT_EQ(60000, mchp.referenceElectricalPowerOutput()); + + // Reference Electrical Efficiency Using Lower Heating Value + ASSERT_EQ(0.29, mchp.referenceElectricalEfficiencyUsingLowerHeatingValue()); + mchp.setReferenceElectricalEfficiencyUsingLowerHeatingValue(0.35); + ASSERT_EQ(0.35, mchp.referenceElectricalEfficiencyUsingLowerHeatingValue()); + + // Check that the curves have been properly defaulted + + //ElectricalPowerFunctionofTemperatureandElevationCurve Name + ASSERT_EQ(1.2027697,mchp.electricalPowerFunctionofTemperatureandElevationCurve().cast().coefficient1Constant()); + ASSERT_EQ(8.797885E-07,mchp.electricalPowerFunctionofTemperatureandElevationCurve().cast().coefficient6xTIMESY()); + + //ElectricalEfficiencyFunctionofTemperatureCurve + ASSERT_EQ(1.0402217,mchp.electricalEfficiencyFunctionofTemperatureCurve().cast().coefficient1Constant()); + ASSERT_EQ(5.133175E-07,mchp.electricalEfficiencyFunctionofTemperatureCurve().cast().coefficient4xPOW3()); + + //ElectricalEfficiencyFunctionofPartLoadRatioCurve + ASSERT_EQ(0.215290,mchp.electricalEfficiencyFunctionofPartLoadRatioCurve().cast().coefficient1Constant()); + ASSERT_EQ(1.497306,mchp.electricalEfficiencyFunctionofPartLoadRatioCurve().cast().coefficient4xPOW3()); + + // Check curve setters + // Test curve setters to see if set at the right place + CurveBiquadratic elecPowerFTempElevation(model); + elecPowerFTempElevation.setCoefficient1Constant(1); + elecPowerFTempElevation.setCoefficient2x(0.1); + elecPowerFTempElevation.setCoefficient3xPOW2(0.01); + mchp.setElectricalPowerFunctionofTemperatureandElevationCurve(elecPowerFTempElevation); + CurveCubic elecEffFT(model); + elecEffFT.setCoefficient1Constant(2); + elecEffFT.setCoefficient2x(0.2); + elecEffFT.setCoefficient3xPOW2(0.02); + mchp.setElectricalEfficiencyFunctionofTemperatureCurve(elecEffFT); + CurveCubic elecEffFPLR(model); + elecEffFPLR.setCoefficient1Constant(3); + elecEffFPLR.setCoefficient2x(0.3); + elecEffFPLR.setCoefficient3xPOW2(0.03); + mchp.setElectricalEfficiencyFunctionofPartLoadRatioCurve(elecEffFPLR); + + // Verify the setter + ASSERT_EQ(1,mchp.electricalPowerFunctionofTemperatureandElevationCurve().cast().coefficient1Constant()); + ASSERT_EQ(2,mchp.electricalEfficiencyFunctionofTemperatureCurve().cast().coefficient1Constant()); + ASSERT_EQ(3,mchp.electricalEfficiencyFunctionofPartLoadRatioCurve().cast().coefficient1Constant()); + + + // Test defaulted values + EXPECT_FALSE(mchp.availabilitySchedule()); + Schedule schedule = model.alwaysOnDiscreteSchedule(); + EXPECT_TRUE(mchp.setAvailabilitySchedule(schedule)); + ASSERT_TRUE(mchp.availabilitySchedule()); + + + EXPECT_TRUE(mchp.isMinimumFullLoadElectricalPowerOutputDefaulted()); + EXPECT_EQ(0.0, mchp.minimumFullLoadElectricalPowerOutput()); + mchp.setMinimumFullLoadElectricalPowerOutput(10); + EXPECT_EQ(10.0, mchp.minimumFullLoadElectricalPowerOutput()); + EXPECT_FALSE(mchp.isMinimumFullLoadElectricalPowerOutputDefaulted()); + mchp.resetMinimumFullLoadElectricalPowerOutput(); + EXPECT_TRUE(mchp.isMinimumFullLoadElectricalPowerOutputDefaulted()); + + // Maximum Full Load Electrical Power Output => defaulted to referenceElectricalPowerOutput + EXPECT_TRUE(mchp.isMaximumFullLoadElectricalPowerOutputDefaulted()); + EXPECT_EQ(mchp.referenceElectricalPowerOutput(), mchp.maximumFullLoadElectricalPowerOutput()); + mchp.setMaximumFullLoadElectricalPowerOutput(55000); + EXPECT_EQ(55000.0, mchp.maximumFullLoadElectricalPowerOutput()); + EXPECT_FALSE(mchp.isMaximumFullLoadElectricalPowerOutputDefaulted()); + mchp.resetMaximumFullLoadElectricalPowerOutput(); + EXPECT_TRUE(mchp.isMaximumFullLoadElectricalPowerOutputDefaulted()); + + // Reference Combustion Air Inlet Temperature defaults to 15 + EXPECT_TRUE(mchp.isReferenceCombustionAirInletTemperatureDefaulted()); + EXPECT_EQ(15.0, mchp.referenceCombustionAirInletTemperature()); + mchp.setReferenceCombustionAirInletTemperature(18); + EXPECT_EQ(18.0, mchp.referenceCombustionAirInletTemperature()); + EXPECT_FALSE(mchp.isReferenceCombustionAirInletTemperatureDefaulted()); + mchp.resetReferenceCombustionAirInletTemperature(); + EXPECT_TRUE(mchp.isReferenceCombustionAirInletTemperatureDefaulted()); + + // Reference Combustion Air Inlet Humidity Ratio, defaults to 0.00638 + EXPECT_TRUE(mchp.isReferenceCombustionAirInletHumidityRatioDefaulted()); + EXPECT_EQ(0.00638, mchp.referenceCombustionAirInletHumidityRatio()); + mchp.setReferenceCombustionAirInletHumidityRatio(0.008); + EXPECT_EQ(0.008, mchp.referenceCombustionAirInletHumidityRatio()); + EXPECT_FALSE(mchp.isReferenceCombustionAirInletHumidityRatioDefaulted()); + mchp.resetReferenceCombustionAirInletHumidityRatio(); + EXPECT_TRUE(mchp.isReferenceCombustionAirInletHumidityRatioDefaulted()); + + // Reference Elevation + EXPECT_TRUE(mchp.isReferenceElevationDefaulted()); + EXPECT_EQ(0.0, mchp.referenceElevation()); + mchp.setReferenceElevation(10); + EXPECT_EQ(10.0, mchp.referenceElevation()); + EXPECT_FALSE(mchp.isReferenceElevationDefaulted()); + mchp.resetReferenceElevation(); + EXPECT_TRUE(mchp.isReferenceElevationDefaulted()); + + //Fuel Type + EXPECT_TRUE(mchp.isFuelTypeDefaulted()); + EXPECT_EQ("NaturalGas", mchp.fuelType()); + mchp.setFuelType("PropaneGas"); + EXPECT_EQ("PropaneGas", mchp.fuelType()); + EXPECT_FALSE(mchp.isFuelTypeDefaulted()); + mchp.resetFuelType(); + EXPECT_TRUE(mchp.isFuelTypeDefaulted()); + + // FuelHigherHeatingValue + // \default 50000 + EXPECT_TRUE(mchp.isFuelHigherHeatingValueDefaulted()); + EXPECT_EQ(50000.0, mchp.fuelHigherHeatingValue()); + mchp.setFuelHigherHeatingValue(45000); + EXPECT_EQ(45000, mchp.fuelHigherHeatingValue()); + EXPECT_FALSE(mchp.isFuelHigherHeatingValueDefaulted()); + mchp.resetFuelHigherHeatingValue(); + EXPECT_TRUE(mchp.isFuelHigherHeatingValueDefaulted()); + + //N9, \field Fuel Lower Heating Value + // \default 45450 + EXPECT_TRUE(mchp.isFuelLowerHeatingValueDefaulted()); + EXPECT_EQ(45450.0, mchp.fuelLowerHeatingValue()); + mchp.setFuelLowerHeatingValue(45000); + EXPECT_EQ(45000, mchp.fuelLowerHeatingValue()); + EXPECT_FALSE(mchp.isFuelLowerHeatingValueDefaulted()); + mchp.resetFuelLowerHeatingValue(); + EXPECT_TRUE(mchp.isFuelLowerHeatingValueDefaulted()); + + // N10, \field Standby Power + // \default 0.0 + EXPECT_TRUE(mchp.isStandbyPowerDefaulted()); + EXPECT_EQ(0.0, mchp.standbyPower()); + mchp.setStandbyPower(10); + EXPECT_EQ(10.0, mchp.standbyPower()); + EXPECT_FALSE(mchp.isStandbyPowerDefaulted()); + mchp.resetStandbyPower(); + EXPECT_TRUE(mchp.isStandbyPowerDefaulted()); + + + // N11, \field Ancillary Power + // \default 0.0 + EXPECT_TRUE(mchp.isAncillaryPowerDefaulted()); + EXPECT_EQ(0.0, mchp.ancillaryPower()); + mchp.setAncillaryPower(10); + EXPECT_EQ(10.0, mchp.ancillaryPower()); + EXPECT_FALSE(mchp.isAncillaryPowerDefaulted()); + mchp.resetAncillaryPower(); + EXPECT_TRUE(mchp.isAncillaryPowerDefaulted()); + + + // \field Ancillary Power Function of Fuel Input Curve Name + // \object-list QuadraticCurves + EXPECT_FALSE(mchp.ancillaryPowerFunctionofFuelInputCurve()); + CurveQuadratic ancPFfuelInputCurve(model); + mchp.setAncillaryPowerFunctionofFuelInputCurve(ancPFfuelInputCurve); + ASSERT_TRUE(mchp.ancillaryPowerFunctionofFuelInputCurve()); + if( boost::optional setCurve = mchp.ancillaryPowerFunctionofFuelInputCurve() ) { + EXPECT_EQ(ancPFfuelInputCurve.handle(), setCurve->handle()); + } + + + // Optional Generator:MicroTurbine:HeatRecovery + // \field Generator MicroTurbine Heat Recovery Name + // I'll check the setter and getter in a separate function where I also test all of this object + EXPECT_FALSE(mchp.generatorMicroTurbineHeatRecovery()); + + // TODO: Check return type. From object lists, some candidates are: Connection. + //boost::optional combustionAirInletNode() const; + + // TODO: Check return type. From object lists, some candidates are: Connection. + // boost::optional combustionAirOutletNode() const; + + // N12, \field Reference Exhaust Air Mass Flow Rate + EXPECT_FALSE(mchp.referenceExhaustAirMassFlowRate()); + mchp.setReferenceExhaustAirMassFlowRate(100); + boost::optional testrefEAmdotR = mchp.referenceExhaustAirMassFlowRate(); + EXPECT_EQ((*testrefEAmdotR),100); + + // A12, \field Exhaust Air Flow Rate Function of Temperature Curve Name + // TODO: Check return type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + EXPECT_FALSE(mchp.exhaustAirFlowRateFunctionofTemperatureCurve()); + CurveQuadratic exhaustAirFlowFT(model); + mchp.setExhaustAirFlowRateFunctionofTemperatureCurve(exhaustAirFlowFT); + ASSERT_TRUE(mchp.exhaustAirFlowRateFunctionofTemperatureCurve()); + if( boost::optional setCurve = mchp.exhaustAirFlowRateFunctionofTemperatureCurve() ) { + EXPECT_EQ(exhaustAirFlowFT.handle(), setCurve->handle()); + } + + + + + // A13, \field Exhaust Air Flow Rate Function of Part Load Ratio Curve Name + // TODO: Check return type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + // Exhaust Air Flow Rate Function of Part Load Ratio Curve Name + EXPECT_FALSE(mchp.exhaustAirFlowRateFunctionofPartLoadRatioCurve()); + CurveQuadratic exhaustAirFlowFPLR(model); + mchp.setExhaustAirFlowRateFunctionofPartLoadRatioCurve(exhaustAirFlowFPLR); + ASSERT_TRUE(mchp.exhaustAirFlowRateFunctionofPartLoadRatioCurve()); + if( boost::optional setCurve = mchp.exhaustAirFlowRateFunctionofPartLoadRatioCurve() ) { + EXPECT_EQ(exhaustAirFlowFPLR.handle(), setCurve->handle()); + } + + + // N13, \field Nominal Exhaust Air Outlet Temperature + EXPECT_FALSE(mchp.nominalExhaustAirOutletTemperature()); + mchp.setNominalExhaustAirOutletTemperature(100); + boost::optional testnomEAmdotR = mchp.nominalExhaustAirOutletTemperature(); + EXPECT_EQ((*testnomEAmdotR),100); + + // A14, \field Exhaust Air Temperature Function of Temperature Curve Name + // TODO: Check return type. From object lists, some candidates are: QuadraticCubicCurves, UniVariateTables. + EXPECT_FALSE(mchp.exhaustAirTemperatureFunctionofPartLoadRatioCurve()); + CurveQuadratic exhaustAirTempFPLR(model); + mchp.setExhaustAirTemperatureFunctionofPartLoadRatioCurve(exhaustAirTempFPLR); + ASSERT_TRUE(mchp.exhaustAirTemperatureFunctionofPartLoadRatioCurve()); + if( boost::optional setCurve = mchp.exhaustAirTemperatureFunctionofPartLoadRatioCurve() ) { + EXPECT_EQ(exhaustAirTempFPLR.handle(), setCurve->handle()); + } + +} + +// TODO: Do I need to test the Generator:icroTurbine:HeatRecovery here or in its own file? +TEST_F(ModelFixture, GeneratorMicroTurbine_HeatRecovery) { + + //create a model to use in testing this code. + Model model; + + // test constructor for Generator:MicroTurbine + GeneratorMicroTurbine mchp = GeneratorMicroTurbine(model); + + // A3, \field Heat Recovery Water Inlet Node Name + + // A4, \field Heat Recovery Water Outlet Node Name + + + GeneratorMicroTurbineHeatRecovery mchpHR = GeneratorMicroTurbineHeatRecovery(model, mchp); + + // Check if the parent mchp does have this mchpHR set + EXPECT_EQ(mchpHR, mchp.generatorMicroTurbineHeatRecovery().get()); + + + // Check if we can get the parent mchp from the mchpHR + EXPECT_EQ(mchp, mchpHR.generatorMicroTurbine()); + + //N1 , \field Reference Thermal Efficiency Using Lower Heat Value + // \default 0.0 but overriden in construction to 0.4975 + EXPECT_FALSE(mchpHR.isReferenceThermalEfficiencyUsingLowerHeatValueDefaulted()); + EXPECT_EQ(0.4975, mchpHR.referenceThermalEfficiencyUsingLowerHeatValue()); + mchpHR.setReferenceThermalEfficiencyUsingLowerHeatValue(0.5); + EXPECT_EQ(0.5, mchpHR.referenceThermalEfficiencyUsingLowerHeatValue()); + EXPECT_FALSE(mchpHR.isReferenceThermalEfficiencyUsingLowerHeatValueDefaulted()); + mchpHR.resetReferenceThermalEfficiencyUsingLowerHeatValue(); + EXPECT_TRUE(mchpHR.isReferenceThermalEfficiencyUsingLowerHeatValueDefaulted()); + + // N2 , \field Reference Inlet Water Temperature = 60 in constructor + // boost::optional referenceInletWaterTemperature() const; + EXPECT_EQ(60.0, mchpHR.referenceInletWaterTemperature()); + mchpHR.setReferenceInletWaterTemperature(65); + EXPECT_EQ(65.0, mchpHR.referenceInletWaterTemperature()); + + + // A5 , \field Heat Recovery Water Flow Operating Mode + // \default PlantControl + EXPECT_TRUE(mchpHR.isHeatRecoveryWaterFlowOperatingModeDefaulted()); + EXPECT_EQ("PlantControl", mchpHR.heatRecoveryWaterFlowOperatingMode()); + mchpHR.setHeatRecoveryWaterFlowOperatingMode("InternalControl"); + EXPECT_EQ("InternalControl", mchpHR.heatRecoveryWaterFlowOperatingMode()); + EXPECT_FALSE(mchpHR.isHeatRecoveryWaterFlowOperatingModeDefaulted()); + mchpHR.resetHeatRecoveryWaterFlowOperatingMode(); + EXPECT_TRUE(mchpHR.isHeatRecoveryWaterFlowOperatingModeDefaulted()); + + // N6 , \field Reference Heat Recovery Water Flow Rate = 0.00252362 + EXPECT_EQ(0.00252362, mchpHR.referenceHeatRecoveryWaterFlowRate()); + mchpHR.setReferenceHeatRecoveryWaterFlowRate(0.005); + EXPECT_EQ(0.005, mchpHR.referenceHeatRecoveryWaterFlowRate()); + + // A6 , \field Heat Recovery Water Flow Rate Function of Temperature and Power Curve Name + // BiquadraticCurves, BiVariateTables. + // boost::optional heatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve() const; + // \note If left blank, model assumes the heat recovery water flow rate + EXPECT_FALSE(mchpHR.heatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve()); + CurveBiquadratic hrWaterFlowFTP(model); + mchpHR.setHeatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve(hrWaterFlowFTP); + ASSERT_TRUE(mchpHR.heatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve()); + if( boost::optional setCurve = mchpHR.heatRecoveryWaterFlowRateFunctionofTemperatureandPowerCurve() ) { + EXPECT_EQ(hrWaterFlowFTP.handle(), setCurve->handle()); + } + + + // A7 , \field Thermal Efficiency Function of Temperature and Elevation Curve Name + // \object-list BicubicBiquadraticCurves, BiVariateTables + // boost::optional thermalEfficiencyFunctionofTemperatureandElevationCurve() const; + EXPECT_FALSE(mchpHR.thermalEfficiencyFunctionofTemperatureandElevationCurve()); + CurveBiquadratic hrEffFTempElev(model); + mchpHR.setThermalEfficiencyFunctionofTemperatureandElevationCurve(hrEffFTempElev); + ASSERT_TRUE(mchpHR.thermalEfficiencyFunctionofTemperatureandElevationCurve()); + if( boost::optional setCurve = mchpHR.thermalEfficiencyFunctionofTemperatureandElevationCurve() ) { + EXPECT_EQ(hrEffFTempElev.handle(), setCurve->handle()); + } + + // A8 , \field Heat Recovery Rate Function of Part Load Ratio Curve Name + // QuadraticCubicCurves, UniVariateTables + // boost::optional heatRecoveryRateFunctionofPartLoadRatioCurve() const; + EXPECT_FALSE(mchpHR.heatRecoveryRateFunctionofPartLoadRatioCurve()); + CurveCubic hrRRWaterFlowFPLR(model); + mchpHR.setHeatRecoveryRateFunctionofPartLoadRatioCurve(hrRRWaterFlowFPLR); + ASSERT_TRUE(mchpHR.heatRecoveryRateFunctionofPartLoadRatioCurve()); + if( boost::optional setCurve = mchpHR.heatRecoveryRateFunctionofPartLoadRatioCurve() ) { + EXPECT_EQ(hrRRWaterFlowFPLR.handle(), setCurve->handle()); + } + + + + // A9 , \field Heat Recovery Rate Function of Inlet Water Temperature Curve Name + // QuadraticCurves, UniVariateTables + // boost::optional heatRecoveryRateFunctionofInletWaterTemperatureCurve() const; + EXPECT_FALSE(mchpHR.heatRecoveryRateFunctionofInletWaterTemperatureCurve()); + CurveQuadratic hrRRFInletTemp(model); + mchpHR.setHeatRecoveryRateFunctionofInletWaterTemperatureCurve(hrRRFInletTemp); + ASSERT_TRUE(mchpHR.heatRecoveryRateFunctionofInletWaterTemperatureCurve()); + if( boost::optional setCurve = mchpHR.heatRecoveryRateFunctionofInletWaterTemperatureCurve() ) { + EXPECT_EQ(hrRRFInletTemp.handle(), setCurve->handle()); + } + + + // A10, \field Heat Recovery Rate Function of Water Flow Rate Curve Name + // QuadraticCurves, UniVariateTables. + // boost::optional heatRecoveryRateFunctionofWaterFlowRateCurve() const; + EXPECT_FALSE(mchpHR.heatRecoveryRateFunctionofWaterFlowRateCurve()); + CurveQuadratic hrRRFWaterFlow(model); + mchpHR.setHeatRecoveryRateFunctionofWaterFlowRateCurve(hrRRFWaterFlow); + ASSERT_TRUE(mchpHR.heatRecoveryRateFunctionofWaterFlowRateCurve()); + if( boost::optional setCurve = mchpHR.heatRecoveryRateFunctionofWaterFlowRateCurve() ) { + EXPECT_EQ(hrRRFWaterFlow.handle(), setCurve->handle()); + } + + + // N7, \field Minimum Heat Recovery Water Flow Rate + EXPECT_TRUE(mchpHR.isMinimumHeatRecoveryWaterFlowRateDefaulted()); + EXPECT_EQ(0, mchpHR.minimumHeatRecoveryWaterFlowRate()); + mchpHR.setMinimumHeatRecoveryWaterFlowRate(0.001); + EXPECT_EQ(0.001, mchpHR.minimumHeatRecoveryWaterFlowRate()); + EXPECT_FALSE(mchpHR.isMinimumHeatRecoveryWaterFlowRateDefaulted()); + mchpHR.resetMinimumHeatRecoveryWaterFlowRate(); + EXPECT_TRUE(mchpHR.isMinimumHeatRecoveryWaterFlowRateDefaulted()); + + // N8, \field Maximum Heat Recovery Water Flow Rate + // TODO: I think I should really make this default to reference hr water flow rate times 1.5 + EXPECT_TRUE(mchpHR.isMaximumHeatRecoveryWaterFlowRateDefaulted()); + //EXPECT_EQ("PlantControl", mchpHR.maximumHeatRecoveryWaterFlowRate()); + mchpHR.setMaximumHeatRecoveryWaterFlowRate(0.003); + EXPECT_EQ(0.003, mchpHR.maximumHeatRecoveryWaterFlowRate()); + EXPECT_FALSE(mchpHR.isMaximumHeatRecoveryWaterFlowRateDefaulted()); + mchpHR.resetMaximumHeatRecoveryWaterFlowRate(); + EXPECT_TRUE(mchpHR.isMaximumHeatRecoveryWaterFlowRateDefaulted()); + + // N9; \field Maximum Heat Recovery Water Temperature + // boost::optional maximumHeatRecoveryWaterTemperature() const; + EXPECT_FALSE(mchpHR.maximumHeatRecoveryWaterTemperature()); + mchpHR.setMaximumHeatRecoveryWaterTemperature(90); + boost::optional testmaxHRWT = mchpHR.maximumHeatRecoveryWaterTemperature(); + EXPECT_EQ((*testmaxHRWT),90); + + // Test setRatedThermaltoElectricalPowerRatio + mchpHR.setRatedThermaltoElectricalPowerRatio(1.72); + EXPECT_EQ(1.72, mchpHR.ratedThermaltoElectricalPowerRatio()); + + // Test the accessor from the mchp + boost::optional ratedThermaltoElectricalPowerRatio = mchp.ratedThermaltoElectricalPowerRatio(); + EXPECT_EQ((*ratedThermaltoElectricalPowerRatio),1.72); + + // Test setting it to a microturbine and resetting + /*mchp.setGeneratorMicroTurbineHeatRecovery(mchpHR); + ASSERT_TRUE(mchp.generatorMicroTurbineHeatRecovery()); + boost::optional setmchpHR = mchp.generatorMicroTurbineHeatRecovery(); + EXPECT_EQ(mchpHR.handle(), setmchpHR->handle()); + mchp.resetGeneratorMicroTurbineHeatRecovery(); + ASSERT_FALSE(mchp.generatorMicroTurbineHeatRecovery());*/ + + // Try deleting the mchpHR and see if the mchp no longer has a mchpHR or not + mchpHR.remove(); + + EXPECT_FALSE(mchp.generatorMicroTurbineHeatRecovery()); + + + +} + + +//Test cloning the MicroTurbine +// Todo: Need to handle that properly, check if the HR was cloned too +TEST_F(ModelFixture,GeneratorMicroTurbine_Clone) +{ + + Model model; + + // test constructor for Generator:MicroTurbine + GeneratorMicroTurbine mchp = GeneratorMicroTurbine(model); + + // Test curve setters to see if set at the right place + CurveBiquadratic elecPowerFTempElevation(model); + elecPowerFTempElevation.setCoefficient1Constant(1); + elecPowerFTempElevation.setCoefficient2x(0.1); + elecPowerFTempElevation.setCoefficient3xPOW2(0.01); + mchp.setElectricalPowerFunctionofTemperatureandElevationCurve(elecPowerFTempElevation); + CurveCubic elecEffFT(model); + elecEffFT.setCoefficient1Constant(2); + elecEffFT.setCoefficient2x(0.2); + elecEffFT.setCoefficient3xPOW2(0.02); + mchp.setElectricalEfficiencyFunctionofTemperatureCurve(elecEffFT); + CurveCubic elecEffFPLR(model); + elecEffFPLR.setCoefficient1Constant(3); + elecEffFPLR.setCoefficient2x(0.3); + elecEffFPLR.setCoefficient3xPOW2(0.03); + mchp.setElectricalEfficiencyFunctionofPartLoadRatioCurve(elecEffFPLR); + + // Verify the setter is already done above... + + //Clone into the same model + GeneratorMicroTurbine mchpClone = mchp.clone(model).cast(); + + ASSERT_EQ(1,mchpClone.electricalPowerFunctionofTemperatureandElevationCurve().cast().coefficient1Constant()); + ASSERT_EQ(2,mchpClone.electricalEfficiencyFunctionofTemperatureCurve().cast().coefficient1Constant()); + ASSERT_EQ(3,mchpClone.electricalEfficiencyFunctionofPartLoadRatioCurve().cast().coefficient1Constant()); + + // Add a MicroTurbine:HeatRecovery and clone again + GeneratorMicroTurbineHeatRecovery mchpHR = GeneratorMicroTurbineHeatRecovery(model, mchp); + + // Clone in same model and verify that the mCHPHR is also cloned + GeneratorMicroTurbine mchpClone1 = mchp.clone(model).cast(); + ASSERT_TRUE(mchpClone1.generatorMicroTurbineHeatRecovery()); + // Make sure it's not just pointing to the same one + boost::optional mchpHRclone = mchpClone1.generatorMicroTurbineHeatRecovery(); + EXPECT_NE(mchpHR.handle(), mchpHRclone->handle()); + + + //Clone into another model + Model model2; + GeneratorMicroTurbine mchpClone2 = mchp.clone(model2).cast(); + + // Check that curves have been carried with it + ASSERT_EQ(1,mchpClone2.electricalPowerFunctionofTemperatureandElevationCurve().cast().coefficient1Constant()); + ASSERT_EQ(2,mchpClone2.electricalEfficiencyFunctionofTemperatureCurve().cast().coefficient1Constant()); + ASSERT_EQ(3,mchpClone2.electricalEfficiencyFunctionofPartLoadRatioCurve().cast().coefficient1Constant()); + + // Check that the heatRecovery module has been clone into the model too + ASSERT_TRUE(mchpClone2.generatorMicroTurbineHeatRecovery()); + // Make sure it's not just pointing to the same one + boost::optional mchpHRclone2 = mchpClone1.generatorMicroTurbineHeatRecovery(); + EXPECT_NE(mchpHR.handle(), mchpHRclone2->handle()); + +} + + +TEST_F(ModelFixture,GeneratorMicroTurbine_HeatRecovery_addToNode) { + Model model; + + GeneratorMicroTurbine mchp = GeneratorMicroTurbine(model); + + GeneratorMicroTurbineHeatRecovery mchpHR = GeneratorMicroTurbineHeatRecovery(model, mchp); + + AirLoopHVAC airLoop = AirLoopHVAC(model); + + Node supplyOutletNode = airLoop.supplyOutletNode(); + + EXPECT_FALSE(mchpHR.addToNode(supplyOutletNode)); + EXPECT_EQ( (unsigned)2, airLoop.supplyComponents().size() ); + + Node inletNode = airLoop.zoneSplitter().lastOutletModelObject()->cast(); + + EXPECT_FALSE(mchpHR.addToNode(inletNode)); + EXPECT_EQ((unsigned)5, airLoop.demandComponents().size()); + + PlantLoop plantLoop(model); + + // This should de settable to the supply side + supplyOutletNode = plantLoop.supplyOutletNode(); + EXPECT_TRUE(mchpHR.addToNode(supplyOutletNode)); + EXPECT_EQ( (unsigned)7, plantLoop.supplyComponents().size() ); + + // This should be settable to the demand side too + Node demandOutletNode = plantLoop.demandOutletNode(); + EXPECT_TRUE(mchpHR.addToNode(demandOutletNode)); + EXPECT_EQ( (unsigned)7, plantLoop.demandComponents().size() ); + + GeneratorMicroTurbineHeatRecovery mchpHRClone = mchpHR.clone(model).cast(); + EXPECT_EQ((unsigned)5, plantLoop.supplyComponents().size()); + EXPECT_TRUE(mchpHRClone.addToNode(supplyOutletNode)); + EXPECT_EQ( (unsigned)7, plantLoop.supplyComponents().size() ); +} + diff --git a/openstudiocore/src/model/test/GeneratorPhotovoltaic_GTest.cpp b/openstudiocore/src/model/test/GeneratorPhotovoltaic_GTest.cpp index 1a002e8dd8d..2b78d5f09d7 100644 --- a/openstudiocore/src/model/test/GeneratorPhotovoltaic_GTest.cpp +++ b/openstudiocore/src/model/test/GeneratorPhotovoltaic_GTest.cpp @@ -49,7 +49,7 @@ TEST_F(ModelFixture, GeneratorPhotovoltaic_Simple) { EXPECT_FALSE(panel.ratedElectricPowerOutput()); EXPECT_FALSE(panel.availabilitySchedule()); - EXPECT_FALSE(panel.ratedThermalToElectricalPowerRatio()); + EXPECT_FALSE(panel.ratedThermaltoElectricalPowerRatio()); EXPECT_FALSE(panel.electricLoadCenterDistribution()); Point3dVector points; @@ -105,7 +105,7 @@ TEST_F(ModelFixture, GeneratorPhotovoltaic_OneDiode) { EXPECT_FALSE(panel.ratedElectricPowerOutput()); EXPECT_FALSE(panel.availabilitySchedule()); - EXPECT_FALSE(panel.ratedThermalToElectricalPowerRatio()); + EXPECT_FALSE(panel.ratedThermaltoElectricalPowerRatio()); EXPECT_FALSE(panel.electricLoadCenterDistribution()); Point3dVector points; diff --git a/openstudiocore/src/model/test/MeterCustomDecrement_GTest.cpp b/openstudiocore/src/model/test/MeterCustomDecrement_GTest.cpp new file mode 100644 index 00000000000..80c30220a54 --- /dev/null +++ b/openstudiocore/src/model/test/MeterCustomDecrement_GTest.cpp @@ -0,0 +1,107 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include +#include "ModelFixture.hpp" +#include "../MeterCustomDecrement.hpp" +#include "../MeterCustomDecrement_Impl.hpp" + +using namespace openstudio; +using namespace openstudio::model; + +TEST_F(ModelFixture, MeterCustomDecrement_DefaultConstructor) +{ + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + + ASSERT_EXIT ( + { + Model model; + MeterCustomDecrement testObject(model, "Electricity:Facility"); + + exit(0); + } , + ::testing::ExitedWithCode(0), "" ); +} + + +TEST_F(ModelFixture, MeterCustomDecrement_Remove) +{ + Model model; + MeterCustomDecrement testObject(model, "Electricity:Facility"); + + EXPECT_EQ((unsigned)1, model.getModelObjects().size()); + + testObject.remove(); + EXPECT_EQ((unsigned)0, model.getModelObjects().size()); +} + +TEST_F(ModelFixture, MeterCustomDecrement_KeyVarGroups) +{ + Model model; + MeterCustomDecrement testObject(model, "Electricity:Facility"); + + EXPECT_EQ("Electricity:Facility", testObject.sourceMeterName()); + testObject.setSourceMeterName("Electricity:Building"); + EXPECT_EQ("Electricity:Building", testObject.sourceMeterName()); + + std::vector< std::pair > keyVarGroups = testObject.keyVarGroups(); + + EXPECT_TRUE(testObject.addKeyVarGroup("SPACE1-1 Lights 1", "Lights Electric Energy")); + keyVarGroups = testObject.keyVarGroups(); + EXPECT_EQ(1, keyVarGroups.size()); + // Also test the numKeyVarGroups method + EXPECT_EQ(1, testObject.numKeyVarGroups()); + + testObject.removeAllKeyVarGroups(); + EXPECT_EQ(0, testObject.numKeyVarGroups()); + + EXPECT_TRUE(testObject.addKeyVarGroup("SPACE1-1 Lights 1", "Lights Electric Energy")); + EXPECT_EQ(1, testObject.numKeyVarGroups()); + + EXPECT_TRUE(testObject.addKeyVarGroup("SPACE1-1 Equipment 1", "Equipment Electric Energy")); + EXPECT_EQ(2, testObject.numKeyVarGroups()); + + // Try removing at index 0 + testObject.removeKeyVarGroup(0); + keyVarGroups = testObject.keyVarGroups(); + EXPECT_EQ(1, keyVarGroups.size()); + + EXPECT_EQ("SPACE1-1 Equipment 1", keyVarGroups[0].first); + EXPECT_EQ("Equipment Electric Energy", keyVarGroups[0].second); + + // Try changing the keyName at index 0 + testObject.setKeyName(0, "A new key name"); + keyVarGroups = testObject.keyVarGroups(); + EXPECT_EQ("A new key name", keyVarGroups[0].first); + + // Try changing the setOutputVariableorMeterName at index 0 + testObject.setOutputVariableorMeterName(0, "A new output var name"); + keyVarGroups = testObject.keyVarGroups(); + EXPECT_EQ("A new output var name", keyVarGroups[0].second); + + + testObject.removeAllKeyVarGroups(); + for (int i=0; i<100; i++) { + testObject.addKeyVarGroup("key " + std::to_string(i), "var " + std::to_string(i)); + } + keyVarGroups = testObject.keyVarGroups(); + EXPECT_EQ(100, keyVarGroups.size()); + EXPECT_EQ(100, testObject.numKeyVarGroups()); + +} diff --git a/openstudiocore/src/model/test/MeterCustom_GTest.cpp b/openstudiocore/src/model/test/MeterCustom_GTest.cpp new file mode 100644 index 00000000000..9bc8ea1dc70 --- /dev/null +++ b/openstudiocore/src/model/test/MeterCustom_GTest.cpp @@ -0,0 +1,103 @@ +/********************************************************************** + * Copyright (c) 2008-2016, Alliance for Sustainable Energy. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + **********************************************************************/ + +#include +#include "ModelFixture.hpp" +#include "../MeterCustom.hpp" +#include "../MeterCustom_Impl.hpp" + +using namespace openstudio; +using namespace openstudio::model; + +TEST_F(ModelFixture, MeterCustom_DefaultConstructor) +{ + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + + ASSERT_EXIT ( + { + Model model; + MeterCustom testObject(model); + + exit(0); + } , + ::testing::ExitedWithCode(0), "" ); +} + + +TEST_F(ModelFixture, MeterCustom_Remove) +{ + Model model; + MeterCustom testObject(model); + + EXPECT_EQ((unsigned)1, model.getModelObjects().size()); + + testObject.remove(); + EXPECT_EQ((unsigned)0, model.getModelObjects().size()); +} + +TEST_F(ModelFixture, MeterCustom_KeyVarGroups) +{ + Model model; + MeterCustom testObject(model); + + std::vector< std::pair > keyVarGroups = testObject.keyVarGroups(); + + EXPECT_TRUE(testObject.addKeyVarGroup("SPACE1-1 Lights 1", "Lights Electric Energy")); + keyVarGroups = testObject.keyVarGroups(); + EXPECT_EQ(1, keyVarGroups.size()); + // Also test the numKeyVarGroups method + EXPECT_EQ(1, testObject.numKeyVarGroups()); + + testObject.removeAllKeyVarGroups(); + EXPECT_EQ(0, testObject.numKeyVarGroups()); + + EXPECT_TRUE(testObject.addKeyVarGroup("SPACE1-1 Lights 1", "Lights Electric Energy")); + EXPECT_EQ(1, testObject.numKeyVarGroups()); + + EXPECT_TRUE(testObject.addKeyVarGroup("SPACE1-1 Equipment 1", "Equipment Electric Energy")); + EXPECT_EQ(2, testObject.numKeyVarGroups()); + + // Try removing at index 0 + testObject.removeKeyVarGroup(0); + keyVarGroups = testObject.keyVarGroups(); + EXPECT_EQ(1, keyVarGroups.size()); + + EXPECT_EQ("SPACE1-1 Equipment 1", keyVarGroups[0].first); + EXPECT_EQ("Equipment Electric Energy", keyVarGroups[0].second); + + // Try changing the keyName at index 0 + testObject.setKeyName(0, "A new key name"); + keyVarGroups = testObject.keyVarGroups(); + EXPECT_EQ("A new key name", keyVarGroups[0].first); + + // Try changing the setOutputVariableorMeterName at index 0 + testObject.setOutputVariableorMeterName(0, "A new output var name"); + keyVarGroups = testObject.keyVarGroups(); + EXPECT_EQ("A new output var name", keyVarGroups[0].second); + + + testObject.removeAllKeyVarGroups(); + for (int i=0; i<100; i++) { + testObject.addKeyVarGroup("key " + std::to_string(i), "var " + std::to_string(i)); + } + keyVarGroups = testObject.keyVarGroups(); + EXPECT_EQ(100, keyVarGroups.size()); + EXPECT_EQ(100, testObject.numKeyVarGroups()); + +} diff --git a/openstudiocore/src/model/test/Meter_GTest.cpp b/openstudiocore/src/model/test/OutputMeter_GTest.cpp similarity index 82% rename from openstudiocore/src/model/test/Meter_GTest.cpp rename to openstudiocore/src/model/test/OutputMeter_GTest.cpp index fbacd73ee1d..4d491b9064a 100644 --- a/openstudiocore/src/model/test/Meter_GTest.cpp +++ b/openstudiocore/src/model/test/OutputMeter_GTest.cpp @@ -22,15 +22,15 @@ #include "ModelFixture.hpp" #include "../Facility.hpp" #include "../Facility_Impl.hpp" -#include "../Meter.hpp" -#include "../Meter_Impl.hpp" +#include "../OutputMeter.hpp" +#include "../OutputMeter_Impl.hpp" #include "../Model_Impl.hpp" #include "../../utilities/sql/SqlFileEnums.hpp" #include "../../utilities/data/TimeSeries.hpp" #include "../../utilities/core/Compare.hpp" -#include +#include #include #include @@ -52,7 +52,7 @@ TEST_F(ModelFixture, MeterRegex) string subject; subject = "Facility"; - ASSERT_TRUE(boost::regex_search(subject, matches, Meter::meterRegex())); + ASSERT_TRUE(boost::regex_search(subject, matches, OutputMeter::meterRegex())); ASSERT_TRUE(matches[1].matched); EXPECT_FALSE(matches[2].matched); EXPECT_FALSE(matches[3].matched); @@ -63,7 +63,7 @@ TEST_F(ModelFixture, MeterRegex) EXPECT_EQ("", string(matches[5].first, matches[5].second)); subject = "Electricity"; - ASSERT_TRUE(boost::regex_search(subject, matches, Meter::meterRegex())); + ASSERT_TRUE(boost::regex_search(subject, matches, OutputMeter::meterRegex())); ASSERT_TRUE(matches[1].matched); EXPECT_FALSE(matches[2].matched); ASSERT_TRUE(matches[3].matched); @@ -74,7 +74,7 @@ TEST_F(ModelFixture, MeterRegex) EXPECT_EQ("", string(matches[5].first, matches[5].second)); subject = "Electricity:Facility"; - ASSERT_TRUE(boost::regex_search(subject, matches, Meter::meterRegex())); + ASSERT_TRUE(boost::regex_search(subject, matches, OutputMeter::meterRegex())); ASSERT_TRUE(matches[1].matched); EXPECT_FALSE(matches[2].matched); ASSERT_TRUE(matches[3].matched); @@ -86,7 +86,7 @@ TEST_F(ModelFixture, MeterRegex) EXPECT_EQ("", string(matches[5].first, matches[5].second)); subject = "Gas:Facility"; - ASSERT_TRUE(boost::regex_search(subject, matches, Meter::meterRegex())); + ASSERT_TRUE(boost::regex_search(subject, matches, OutputMeter::meterRegex())); ASSERT_TRUE(matches[1].matched); EXPECT_FALSE(matches[2].matched); ASSERT_TRUE(matches[3].matched); @@ -98,7 +98,7 @@ TEST_F(ModelFixture, MeterRegex) EXPECT_EQ("", string(matches[5].first, matches[5].second)); subject = "EnergyTransfer:Plant"; - ASSERT_TRUE(boost::regex_search(subject, matches, Meter::meterRegex())); + ASSERT_TRUE(boost::regex_search(subject, matches, OutputMeter::meterRegex())); ASSERT_TRUE(matches[1].matched); EXPECT_FALSE(matches[2].matched); ASSERT_TRUE(matches[3].matched); @@ -110,7 +110,7 @@ TEST_F(ModelFixture, MeterRegex) EXPECT_EQ("", string(matches[5].first, matches[5].second)); subject = "InteriorLights:Electricity"; - ASSERT_TRUE(boost::regex_search(subject, matches, Meter::meterRegex())); + ASSERT_TRUE(boost::regex_search(subject, matches, OutputMeter::meterRegex())); ASSERT_TRUE(matches[1].matched); ASSERT_TRUE(matches[2].matched); ASSERT_TRUE(matches[3].matched); @@ -122,7 +122,7 @@ TEST_F(ModelFixture, MeterRegex) EXPECT_EQ("", string(matches[5].first, matches[5].second)); subject = "InteriorLights:Electricity:Facility"; - ASSERT_TRUE(boost::regex_search(subject, matches, Meter::meterRegex())); + ASSERT_TRUE(boost::regex_search(subject, matches, OutputMeter::meterRegex())); ASSERT_TRUE(matches[1].matched); ASSERT_TRUE(matches[2].matched); ASSERT_TRUE(matches[3].matched); @@ -135,7 +135,7 @@ TEST_F(ModelFixture, MeterRegex) EXPECT_EQ("", string(matches[5].first, matches[5].second)); subject = "General:InteriorLights:Electricity:Facility"; - ASSERT_TRUE(boost::regex_search(subject, matches, Meter::meterRegex())); + ASSERT_TRUE(boost::regex_search(subject, matches, OutputMeter::meterRegex())); ASSERT_TRUE(matches[1].matched); ASSERT_TRUE(matches[2].matched); ASSERT_TRUE(matches[3].matched); @@ -148,7 +148,7 @@ TEST_F(ModelFixture, MeterRegex) EXPECT_EQ("", string(matches[5].first, matches[5].second)); subject = "InteriorLights:Electricity:Zone:North Zone"; - ASSERT_TRUE(boost::regex_search(subject, matches, Meter::meterRegex())); + ASSERT_TRUE(boost::regex_search(subject, matches, OutputMeter::meterRegex())); ASSERT_TRUE(matches[1].matched); ASSERT_TRUE(matches[2].matched); ASSERT_TRUE(matches[3].matched); @@ -161,7 +161,7 @@ TEST_F(ModelFixture, MeterRegex) EXPECT_EQ("North Zone", string(matches[5].first, matches[5].second)); subject = "General:InteriorLights:Electricity:Zone:North Zone"; - ASSERT_TRUE(boost::regex_search(subject, matches, Meter::meterRegex())); + ASSERT_TRUE(boost::regex_search(subject, matches, OutputMeter::meterRegex())); ASSERT_TRUE(matches[1].matched); ASSERT_TRUE(matches[2].matched); ASSERT_TRUE(matches[3].matched); @@ -179,7 +179,7 @@ TEST_F(ModelFixture, MeterConstructor) { Model model; - Meter meter(model); + OutputMeter meter(model); EXPECT_FALSE(meter.specificEndUse()); EXPECT_FALSE(meter.endUseType()); @@ -193,7 +193,7 @@ TEST_F(ModelFixture, MeterConstructor) // check order of operations // this is a corner case of EnergyPlus, there is no 'Heating:Gas:Facility', it is just 'Heating:Gas' - meter = Meter(model); + meter = OutputMeter(model); EXPECT_TRUE(meter.setFuelType(FuelType::Gas)); EXPECT_TRUE(meter.setInstallLocationType(InstallLocationType::Facility)); EXPECT_TRUE(meter.setEndUseType(EndUseType::Heating)); @@ -203,7 +203,7 @@ TEST_F(ModelFixture, MeterConstructor) ASSERT_TRUE(meter.endUseType()); EXPECT_EQ(EndUseType::Heating, meter.endUseType().get().value()); - meter = Meter(model); + meter = OutputMeter(model); EXPECT_TRUE(meter.setInstallLocationType(InstallLocationType::Facility)); EXPECT_TRUE(meter.setFuelType(FuelType::Gas)); EXPECT_TRUE(meter.setEndUseType(EndUseType::Heating)); @@ -213,7 +213,7 @@ TEST_F(ModelFixture, MeterConstructor) ASSERT_TRUE(meter.endUseType()); EXPECT_EQ(EndUseType::Heating, meter.endUseType().get().value()); - meter = Meter(model); + meter = OutputMeter(model); EXPECT_TRUE(meter.setEndUseType(EndUseType::Heating)); EXPECT_TRUE(meter.setInstallLocationType(InstallLocationType::Facility)); EXPECT_TRUE(meter.setFuelType(FuelType::Gas)); @@ -224,7 +224,7 @@ TEST_F(ModelFixture, MeterConstructor) EXPECT_EQ(EndUseType::Heating, meter.endUseType().get().value()); // make sure we don't mix up gasoline with gas - meter = Meter(model); + meter = OutputMeter(model); EXPECT_TRUE(meter.setFuelType(FuelType::Gasoline)); EXPECT_TRUE(meter.setInstallLocationType(InstallLocationType::Facility)); ASSERT_TRUE(meter.fuelType()); @@ -233,7 +233,7 @@ TEST_F(ModelFixture, MeterConstructor) EXPECT_EQ(InstallLocationType::Facility, meter.installLocationType().get().value()); // make sure we can get FuelOil1 - meter = Meter(model); + meter = OutputMeter(model); EXPECT_TRUE(meter.setFuelType(FuelType::FuelOil_1)); EXPECT_TRUE(meter.setInstallLocationType(InstallLocationType::Facility)); ASSERT_TRUE(meter.fuelType()); @@ -249,36 +249,36 @@ TEST_F(ModelFixture, MeterFromModel) IdfObjectVector idfObjects; - idfObjects.push_back(IdfObject(IddObjectType::OS_Meter)); - idfObjects.back().setString(OS_MeterFields::Name,"Electricity:Facility"); - idfObjects.back().setString(OS_MeterFields::ReportingFrequency,"monthly"); - idfObjects.back().setString(OS_MeterFields::MeterFileOnly,"false"); + idfObjects.push_back(IdfObject(IddObjectType::OS_Output_Meter)); + idfObjects.back().setString(OS_Output_MeterFields::Name,"Electricity:Facility"); + idfObjects.back().setString(OS_Output_MeterFields::ReportingFrequency,"monthly"); + idfObjects.back().setString(OS_Output_MeterFields::MeterFileOnly,"false"); - LOG(Debug,"Meter text: " << std::endl << idfObjects.back()); + LOG(Debug,"OutputMeter text: " << std::endl << idfObjects.back()); - idfObjects.push_back(IdfObject(IddObjectType::OS_Meter)); - idfObjects.back().setString(OS_MeterFields::Name,"Gas:Building"); - idfObjects.back().setString(OS_MeterFields::ReportingFrequency,"hourly"); + idfObjects.push_back(IdfObject(IddObjectType::OS_Output_Meter)); + idfObjects.back().setString(OS_Output_MeterFields::Name,"Gas:Building"); + idfObjects.back().setString(OS_Output_MeterFields::ReportingFrequency,"hourly"); - idfObjects.push_back(IdfObject(IddObjectType::OS_Meter)); - idfObjects.back().setString(OS_MeterFields::Name,"InteriorLights:Electricity"); - idfObjects.back().setString(OS_MeterFields::ReportingFrequency,"runperiod"); - idfObjects.back().setString(OS_MeterFields::MeterFileOnly,"false"); - idfObjects.back().setString(OS_MeterFields::Cumulative,"true"); + idfObjects.push_back(IdfObject(IddObjectType::OS_Output_Meter)); + idfObjects.back().setString(OS_Output_MeterFields::Name,"InteriorLights:Electricity"); + idfObjects.back().setString(OS_Output_MeterFields::ReportingFrequency,"runperiod"); + idfObjects.back().setString(OS_Output_MeterFields::MeterFileOnly,"false"); + idfObjects.back().setString(OS_Output_MeterFields::Cumulative,"true"); - idfObjects.push_back(IdfObject(IddObjectType::OS_Meter)); - idfObjects.back().setString(OS_MeterFields::Name,"General:InteriorLights:Electricity:Zone:North Zone"); - idfObjects.back().setString(OS_MeterFields::ReportingFrequency,"daily"); - idfObjects.back().setString(OS_MeterFields::Cumulative,"true"); + idfObjects.push_back(IdfObject(IddObjectType::OS_Output_Meter)); + idfObjects.back().setString(OS_Output_MeterFields::Name,"General:InteriorLights:Electricity:Zone:North Zone"); + idfObjects.back().setString(OS_Output_MeterFields::ReportingFrequency,"daily"); + idfObjects.back().setString(OS_Output_MeterFields::Cumulative,"true"); EXPECT_EQ(static_cast(4), idfObjects.size()); HandleVector handles = getHandles(model.addObjects(idfObjects)); ASSERT_EQ(static_cast(4), handles.size()); - EXPECT_EQ(static_cast(4), model.getModelObjects().size()); + EXPECT_EQ(static_cast(4), model.getModelObjects().size()); - //"Output:Meter,Electricity:Facility,monthly;" - OptionalMeter meter = model.getModelObject(handles[0]); + //"Output:OutputMeter,Electricity:Facility,monthly;" + OptionalOutputMeter meter = model.getModelObject(handles[0]); ASSERT_TRUE(meter); EXPECT_EQ("Electricity:Facility", meter->name()); EXPECT_FALSE(meter->cumulative()); @@ -290,8 +290,8 @@ TEST_F(ModelFixture, MeterFromModel) EXPECT_EQ(InstallLocationType::Facility, meter->installLocationType().get().value()); EXPECT_FALSE(meter->specificInstallLocation()); - //"Output:Meter:MeterFileOnly,Gas:Building,hourly;" - meter = model.getModelObject(handles[1]); + //"Output:OutputMeter:MeterFileOnly,Gas:Building,hourly;" + meter = model.getModelObject(handles[1]); ASSERT_TRUE(meter); EXPECT_EQ("Gas:Building", meter->name()); EXPECT_FALSE(meter->cumulative()); @@ -303,8 +303,8 @@ TEST_F(ModelFixture, MeterFromModel) EXPECT_EQ(InstallLocationType::Building, meter->installLocationType().get().value()); EXPECT_FALSE(meter->specificInstallLocation()); - //"Output:Meter:Cumulative,InteriorLights:Electricity,runperiod;" - meter = model.getModelObject(handles[2]); + //"Output:OutputMeter:Cumulative,InteriorLights:Electricity,runperiod;" + meter = model.getModelObject(handles[2]); ASSERT_TRUE(meter); EXPECT_EQ("InteriorLights:Electricity", meter->name()); EXPECT_TRUE(meter->cumulative()); @@ -316,8 +316,8 @@ TEST_F(ModelFixture, MeterFromModel) EXPECT_FALSE(meter->installLocationType()); EXPECT_FALSE(meter->specificInstallLocation()); - //"Output:Meter:Cumulative:MeterFileOnly,General:InteriorLights:Electricity:Zone:North Zone,daily;" - meter = model.getModelObject(handles[3]); + //"Output:OutputMeter:Cumulative:MeterFileOnly,General:InteriorLights:Electricity:Zone:North Zone,daily;" + meter = model.getModelObject(handles[3]); ASSERT_TRUE(meter); EXPECT_EQ("General:InteriorLights:Electricity:Zone:North Zone", meter->name()); EXPECT_TRUE(meter->cumulative()); @@ -339,7 +339,7 @@ TEST_F(ModelFixture, MeterEnumValues) std::set installLocationTypes = InstallLocationType::getValues(); for (int installLocationType : installLocationTypes){ - Meter meter(model); + OutputMeter meter(model); EXPECT_TRUE(meter.setInstallLocationType(InstallLocationType(installLocationType))) << InstallLocationType(installLocationType).valueName(); ASSERT_TRUE(meter.installLocationType()) << InstallLocationType(installLocationType).valueName(); EXPECT_EQ(installLocationType, meter.installLocationType().get().value()) << InstallLocationType(installLocationType).valueName() << " != " << meter.installLocationType().get().valueName(); @@ -347,7 +347,7 @@ TEST_F(ModelFixture, MeterEnumValues) std::set fuelTypes = FuelType::getValues(); for (int fuelType : fuelTypes){ - Meter meter(model); + OutputMeter meter(model); EXPECT_TRUE(meter.setFuelType(FuelType(fuelType))) << FuelType(fuelType).valueName(); ASSERT_TRUE(meter.fuelType()) << FuelType(fuelType).valueName(); EXPECT_EQ(fuelType, meter.fuelType().get().value()) << FuelType(fuelType).valueName() << " != " << meter.fuelType().get().valueName(); @@ -355,7 +355,7 @@ TEST_F(ModelFixture, MeterEnumValues) std::set endUseTypes = EndUseType::getValues(); for (int endUseType : endUseTypes){ - Meter meter(model); + OutputMeter meter(model); EXPECT_TRUE(meter.setEndUseType(EndUseType(endUseType))) << EndUseType(endUseType).valueName(); ASSERT_TRUE(meter.endUseType()) << EndUseType(endUseType).valueName(); EXPECT_EQ(endUseType, meter.endUseType().get().value()) << EndUseType(endUseType).valueName() << " != " << meter.endUseType().get().valueName(); @@ -364,12 +364,12 @@ TEST_F(ModelFixture, MeterEnumValues) for (int installLocationType : installLocationTypes){ for (int fuelType : fuelTypes){ for (int endUseType : endUseTypes){ - Meter meter(model); + OutputMeter meter(model); EXPECT_TRUE(meter.setInstallLocationType(InstallLocationType(installLocationType))) << InstallLocationType(installLocationType).valueName(); EXPECT_TRUE(meter.setFuelType(FuelType(fuelType))) << FuelType(fuelType).valueName(); EXPECT_TRUE(meter.setEndUseType(EndUseType(endUseType))) << EndUseType(endUseType).valueName(); - // this is a specific case handled by Meter + // this is a specific case handled by OutputMeter if (installLocationType != InstallLocationType::Facility){ ASSERT_TRUE(meter.installLocationType()) << InstallLocationType(installLocationType).valueName(); EXPECT_EQ(installLocationType, meter.installLocationType().get().value()) << InstallLocationType(installLocationType).valueName() << " != " << meter.installLocationType().get().valueName(); @@ -392,7 +392,7 @@ class GetMeterRegex : public QRunnable { std::string subject = "Electricity:Facility"; boost::smatch matches; - boost::regex_search(subject, matches, Meter::meterRegex()); + boost::regex_search(subject, matches, OutputMeter::meterRegex()); } }; diff --git a/openstudiocore/src/model/test/UtilityBill_GTest.cpp b/openstudiocore/src/model/test/UtilityBill_GTest.cpp index 34a2c9120b5..a19e6aa9810 100644 --- a/openstudiocore/src/model/test/UtilityBill_GTest.cpp +++ b/openstudiocore/src/model/test/UtilityBill_GTest.cpp @@ -24,8 +24,8 @@ #include "../UtilityBill.hpp" #include "../YearDescription.hpp" #include "../YearDescription_Impl.hpp" -#include "../Meter.hpp" -#include "../Meter_Impl.hpp" +#include "../OutputMeter.hpp" +#include "../OutputMeter_Impl.hpp" using namespace openstudio; using namespace openstudio::model; @@ -104,9 +104,9 @@ TEST_F(ModelFixture, UtilityBill_Electricity) { EXPECT_EQ(8, bp1.numberOfDays()); EXPECT_EQ(Date(1,8,1999), bp1.endDate()); - EXPECT_EQ(0u, model.getModelObjects().size()); - Meter meter = utilityBill.consumptionMeter(); - EXPECT_EQ(1u, model.getModelObjects().size()); + EXPECT_EQ(0u, model.getModelObjects().size()); + OutputMeter meter = utilityBill.consumptionMeter(); + EXPECT_EQ(1u, model.getModelObjects().size()); EXPECT_EQ("Daily", meter.reportingFrequency()); ASSERT_TRUE(meter.fuelType()); EXPECT_EQ(FuelType::Electricity, meter.fuelType()->value()); @@ -116,33 +116,33 @@ TEST_F(ModelFixture, UtilityBill_Electricity) { EXPECT_EQ(InstallLocationType::Facility, meter.installLocationType()->value()); EXPECT_FALSE(meter.specificInstallLocation()); - Meter meter2 = utilityBill.consumptionMeter(); - EXPECT_EQ(1u, model.getModelObjects().size()); + OutputMeter meter2 = utilityBill.consumptionMeter(); + EXPECT_EQ(1u, model.getModelObjects().size()); - Meter meter3 = utilityBill.consumptionMeter(); - EXPECT_EQ(1u, model.getModelObjects().size()); + OutputMeter meter3 = utilityBill.consumptionMeter(); + EXPECT_EQ(1u, model.getModelObjects().size()); - Meter meter4 = utilityBill.consumptionMeter(); - EXPECT_EQ(1u, model.getModelObjects().size()); + OutputMeter meter4 = utilityBill.consumptionMeter(); + EXPECT_EQ(1u, model.getModelObjects().size()); - boost::optional meter5 = utilityBill.peakDemandMeter(); + boost::optional meter5 = utilityBill.peakDemandMeter(); ASSERT_TRUE(meter5); - EXPECT_EQ(2u, model.getModelObjects().size()); + EXPECT_EQ(2u, model.getModelObjects().size()); - boost::optional meter6 = utilityBill.peakDemandMeter(); + boost::optional meter6 = utilityBill.peakDemandMeter(); ASSERT_TRUE(meter5); - EXPECT_EQ(2u, model.getModelObjects().size()); + EXPECT_EQ(2u, model.getModelObjects().size()); - boost::optional meter7 = utilityBill.peakDemandMeter(); + boost::optional meter7 = utilityBill.peakDemandMeter(); ASSERT_TRUE(meter6); - EXPECT_EQ(2u, model.getModelObjects().size()); + EXPECT_EQ(2u, model.getModelObjects().size()); - Meter meter8 = utilityBill.consumptionMeter(); - EXPECT_EQ(2u, model.getModelObjects().size()); + OutputMeter meter8 = utilityBill.consumptionMeter(); + EXPECT_EQ(2u, model.getModelObjects().size()); - boost::optional meter9 = utilityBill.peakDemandMeter(); + boost::optional meter9 = utilityBill.peakDemandMeter(); ASSERT_TRUE(meter9); - EXPECT_EQ(2u, model.getModelObjects().size()); + EXPECT_EQ(2u, model.getModelObjects().size()); } @@ -246,7 +246,7 @@ TEST_F(ModelFixture, UtilityBill_Coverage) { EXPECT_FALSE(utilityBill.consumptionUnitValues().empty()); for (const std::string& consumptionUnit : utilityBill.consumptionUnitValues()){ - Meter meter = utilityBill.consumptionMeter(); + OutputMeter meter = utilityBill.consumptionMeter(); EXPECT_TRUE(utilityBill.setConsumptionUnit(consumptionUnit)) << fuelType.valueName() << ", " << consumptionUnit; EXPECT_EQ(consumptionUnit, utilityBill.consumptionUnit()); @@ -255,7 +255,7 @@ TEST_F(ModelFixture, UtilityBill_Coverage) { for (const std::string& peakDemandUnit : utilityBill.peakDemandUnitValues()){ - boost::optional peakDemandMeter = utilityBill.peakDemandMeter(); + boost::optional peakDemandMeter = utilityBill.peakDemandMeter(); EXPECT_TRUE(utilityBill.setPeakDemandUnit(peakDemandUnit)) << fuelType.valueName() << ", " << peakDemandUnit; ASSERT_TRUE(utilityBill.peakDemandUnit()); diff --git a/openstudiocore/src/openstudio_app/OpenStudioApp.cpp b/openstudiocore/src/openstudio_app/OpenStudioApp.cpp index b51266fe0d7..ca67b4e6f6e 100644 --- a/openstudiocore/src/openstudio_app/OpenStudioApp.cpp +++ b/openstudiocore/src/openstudio_app/OpenStudioApp.cpp @@ -68,6 +68,8 @@ #include "../model/FanOnOff.hpp" #include "../model/FanVariableVolume.hpp" #include "../model/FanZoneExhaust.hpp" +// TODO: Not sure if I need to include GeneratorMicroTurbine.hpp, GeneratorMicroTurbineHeatRecovery.hpp or both +#include "../model/GeneratorMicroTurbineHeatRecovery.hpp" #include "../model/Model.hpp" #include "../model/ScheduleCompact.hpp" #include "../model/SetpointManagerMixedAir.hpp" @@ -302,12 +304,24 @@ void OpenStudioApp::buildCompLibraries() path p = resourcesPath() / toPath("MinimalTemplate.osm"); OS_ASSERT(exists(p)); boost::optional temp = versionTranslator.loadModel(p); + if (!temp){ + LOG_FREE(Error, "OpenStudioApp", "Failed to load MinimalTemplate"); + for (const auto& error : versionTranslator.errors()){ + LOG_FREE(Error, "OpenStudioApp", error.logMessage()); + } + } OS_ASSERT(temp); m_compLibrary = temp.get(); p = resourcesPath() / toPath("hvaclibrary/hvac_library.osm"); OS_ASSERT(exists(p)); temp = versionTranslator.loadModel(p); + if (!temp){ + LOG_FREE(Error, "OpenStudioApp", "Failed to load hvaclibrary"); + for (const auto& error : versionTranslator.errors()){ + LOG_FREE(Error, "OpenStudioApp", error.logMessage()); + } + } OS_ASSERT(temp); m_hvacCompLibrary = temp.get(); } diff --git a/openstudiocore/src/openstudio_app/Resources/hvaclibrary/hvac_library.osm b/openstudiocore/src/openstudio_app/Resources/hvaclibrary/hvac_library.osm index 83ee70f8537..75aef16ebd6 100644 --- a/openstudiocore/src/openstudio_app/Resources/hvaclibrary/hvac_library.osm +++ b/openstudiocore/src/openstudio_app/Resources/hvaclibrary/hvac_library.osm @@ -1,7 +1,7 @@ OS:Version, {d39ef75f-e352-424a-af0f-2c00d6612a2b}, !- Handle - 1.12.0; !- Version Identifier + 1.12.1; !- Version Identifier OS:Schedule:Constant, {9f54092d-a4a8-41b8-a381-c4c332ecb843}, !- Handle @@ -10455,3 +10455,183 @@ OS:HeatPump:WaterToWater:EquationFit:Heating, -0.21629222, !- Heating Compressor Power Coefficient 4 0.033862378; !- Heating Compressor Power Coefficient 5 +OS:Generator:MicroTurbine, + {5f037e71-1ba0-4b22-9d0d-0ab372356d49}, !- Handle + Capstone C65, !- Name + , !- Availability Schedule Name + 65000, !- Reference Electrical Power Output {W} + 29900, !- Minimum Full Load Electrical Power Output {W} + 65000, !- Maximum Full Load Electrical Power Output {W} + 0.29, !- Reference Electrical Efficiency Using Lower Heating Value + 15, !- Reference Combustion Air Inlet Temperature {C} + 0.00638, !- Reference Combustion Air Inlet Humidity Ratio {kgWater/kgDryAir} + , !- Reference Elevation {m} + {e0f0a783-2029-4a89-9ef3-3febbe8ec948}, !- Electrical Power Function of Temperature and Elevation Curve Name + {e56c9532-c449-4090-9abe-33484088874e}, !- Electrical Efficiency Function of Temperature Curve Name + {62f04b09-700d-4cbd-9182-ca43e5970d82}, !- Electrical Efficiency Function of Part Load Ratio Curve Name + NaturalGas, !- Fuel Type + 50000, !- Fuel Higher Heating Value {kJ/kg} + 45450, !- Fuel Lower Heating Value {kJ/kg} + 300, !- Standby Power {W} + 4500, !- Ancillary Power {W} + , !- Ancillary Power Function of Fuel Input Curve Name + {92830969-a01b-48c2-83fc-ffccfb0f3bfe}, !- Generator MicroTurbine Heat Recovery Name + , !- Combustion Air Inlet Node Name + , !- Combustion Air Outlet Node Name + 0.489885, !- Reference Exhaust Air Mass Flow Rate {kg/s} + {0c0f1c72-e8f7-466a-ba83-fd76f57f76e1}, !- Exhaust Air Flow Rate Function of Temperature Curve Name + {a3d5ef42-9ebb-48ec-9bba-9dbbcef38f0f}, !- Exhaust Air Flow Rate Function of Part Load Ratio Curve Name + 308.9, !- Nominal Exhaust Air Outlet Temperature + {2283f3f3-71db-417c-aece-caebc307f0d4}, !- Exhaust Air Temperature Function of Temperature Curve Name + {630f6ec6-2976-4e11-bb18-582c07614b6a}; !- Exhaust Air Temperature Function of Part Load Ratio Curve Name + +OS:Generator:MicroTurbine:HeatRecovery, + {92830969-a01b-48c2-83fc-ffccfb0f3bfe}, !- Handle + Capstone C65 Heat Recovery, !- Name + , !- Heat Recovery Water Inlet Node Name + , !- Heat Recovery Water Outlet Node Name + 0.4975, !- Reference Thermal Efficiency Using Lower Heat Value + 60, !- Reference Inlet Water Temperature {C} + PlantControl, !- Heat Recovery Water Flow Operating Mode + 0.00252362, !- Reference Heat Recovery Water Flow Rate {m3/s} + , !- Heat Recovery Water Flow Rate Function of Temperature and Power Curve Name + {3dd89b8f-8a48-4659-8042-db1fbe47e1c5}, !- Thermal Efficiency Function of Temperature and Elevation Curve Name + {0ddf9857-8f07-49ae-a6e4-ecd92c11a6f4}, !- Heat Recovery Rate Function of Part Load Ratio Curve Name + {11955a2d-4206-4d53-a270-56b9f3ad84e7}, !- Heat Recovery Rate Function of Inlet Water Temperature Curve Name + {24bdbfe6-466e-4412-91f8-008a13c1a20b}, !- Heat Recovery Rate Function of Water Flow Rate Curve Name + 0.001577263, !- Minimum Heat Recovery Water Flow Rate {m3/s} + 0.003785432, !- Maximum Heat Recovery Water Flow Rate {m3/s} + 82.2, !- Maximum Heat Recovery Water Temperature {C} + 1.72; !- Rated Thermal to Electrical Power Ratio + +OS:Curve:Biquadratic, + {e0f0a783-2029-4a89-9ef3-3febbe8ec948}, !- Handle + Capstone C65 Power_vs_Temp_Elev, !- Name + 1.2027697, !- Coefficient1 Constant + -0.009671305, !- Coefficient2 x + -4.860793e-006, !- Coefficient3 x**2 + -0.0001542394, !- Coefficient4 y + 9.111418e-009, !- Coefficient5 y**2 + 8.797885e-007, !- Coefficient6 x*y + -17.8, !- Minimum Value of x + 50, !- Maximum Value of x + 0, !- Minimum Value of y + 3050; !- Maximum Value of y + +OS:Curve:Cubic, + {e56c9532-c449-4090-9abe-33484088874e}, !- Handle + Capstone C65 Efficiency_vs_Temp, !- Name + 1.0402217, !- Coefficient1 Constant + -0.0017314, !- Coefficient2 x + -6.49704e-005, !- Coefficient3 x**2 + 5.133175e-007, !- Coefficient4 x**3 + -20, !- Minimum Value of x + 50; !- Maximum Value of x + +OS:Curve:Cubic, + {62f04b09-700d-4cbd-9182-ca43e5970d82}, !- Handle + Capstone C65 Efficiency_vs_PLR, !- Name + 0.21529, !- Coefficient1 Constant + 2.561463, !- Coefficient2 x + -3.24613, !- Coefficient3 x**2 + 1.497306, !- Coefficient4 x**3 + 0.03, !- Minimum Value of x + 1; !- Maximum Value of x + +OS:Curve:Bicubic, + {3dd89b8f-8a48-4659-8042-db1fbe47e1c5}, !- Handle + Capstone C65 ThermalEff_vs_Temp_Elev, !- Name + 0.93553794, !- Coefficient1 Constant + 0.00541992, !- Coefficient2 x + -7.8902e-005, !- Coefficient3 x**2 + -1.74338e-005, !- Coefficient4 y + -2.51197e-008, !- Coefficient5 y**2 + -4.50373e-006, !- Coefficient6 x*y + 1.49283e-006, !- Coefficient7 x**3 + 2.16866e-012, !- Coefficient8 y**3 + 1.93982e-008, !- Coefficient9 x**2*y + 6.73429e-010, !- Coefficient10 x*y**2 + -17.8, !- Minimum Value of x + 48.9, !- Maximum Value of x + 0, !- Minimum Value of y + 3048; !- Maximum Value of y + +OS:Curve:Quadratic, + {0ddf9857-8f07-49ae-a6e4-ecd92c11a6f4}, !- Handle + Capstone C65 HeatRecoveryRate_vs_PLR, !- Name + 0, !- Coefficient1 Constant + 1, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 0.03, !- Minimum Value of x + 1; !- Maximum Value of x + +OS:Curve:Quadratic, + {11955a2d-4206-4d53-a270-56b9f3ad84e7}, !- Handle + Capstone C65 HeatRecoveryRate_vs_InletTemp, !- Name + 0.7516, !- Coefficient1 Constant + 0.00414, !- Coefficient2 x + 0, !- Coefficient3 x**2 + 29.44, !- Minimum Value of x + 85, !- Maximum Value of x + , !- Minimum Curve Output + , !- Maximum Curve Output + Temperature, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + +OS:Curve:Quadratic, + {24bdbfe6-466e-4412-91f8-008a13c1a20b}, !- Handle + Capstone C65 HeatRecoveryRate_vs_WaterFlow, !- Name + 0.83, !- Coefficient1 Constant + 88.76138, !- Coefficient2 x + -8541.831, !- Coefficient3 x**2 + 0.001577263, !- Minimum Value of x + 0.003785432, !- Maximum Value of x + , !- Minimum Curve Output + , !- Maximum Curve Output + VolumetricFlow, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + +OS:Curve:Cubic, + {0c0f1c72-e8f7-466a-ba83-fd76f57f76e1}, !- Handle + Capstone C65 ExhAirFlowRate_vs_InletTemp, !- Name + 0.9837417, !- Coefficient1 Constant + 6.76623e-005, !- Coefficient2 x + 5.35766e-005, !- Coefficient3 x**2 + -2.12819e-006, !- Coefficient4 x**3 + -20, !- Minimum Value of x + 50, !- Maximum Value of x + , !- Minimum Curve Output + , !- Maximum Curve Output + Temperature, !- Input Unit Type for X + Dimensionless; !- Output Unit Type + +OS:Curve:Cubic, + {a3d5ef42-9ebb-48ec-9bba-9dbbcef38f0f}, !- Handle + Capstone C65 ExhAirFlowRate_vs_PLR, !- Name + 0.272074, !- Coefficient1 Constant + 1.313337, !- Coefficient2 x + -1.0480845, !- Coefficient3 x**2 + 0.46216638, !- Coefficient4 x**3 + 0.03, !- Minimum Value of x + 1; !- Maximum Value of x + +OS:Curve:Cubic, + {2283f3f3-71db-417c-aece-caebc307f0d4}, !- Handle + Capstone C65 ExhaustTemp_vs_InletTemp, !- Name + 0.9246362, !- Coefficient1 Constant + 0.0052553, !- Coefficient2 x + -1.97367e-005, !- Coefficient3 x**2 + -5.66196e-007, !- Coefficient4 x**3 + -20, !- Minimum Value of x + 50; !- Maximum Value of x + +OS:Curve:Cubic, + {630f6ec6-2976-4e11-bb18-582c07614b6a}, !- Handle + Capstone C65 ExhaustTemp_vs_PLR, !- Name + 0.59175, !- Coefficient1 Constant + 0.87874, !- Coefficient2 x + -0.880443, !- Coefficient3 x**2 + 0.4107131, !- Coefficient4 x**3 + 0.03, !- Minimum Value of x + 1; !- Maximum Value of x + diff --git a/openstudiocore/src/openstudio_lib/IconLibrary.cpp b/openstudiocore/src/openstudio_lib/IconLibrary.cpp index 5207c1656d9..10c767e145d 100644 --- a/openstudiocore/src/openstudio_lib/IconLibrary.cpp +++ b/openstudiocore/src/openstudio_lib/IconLibrary.cpp @@ -132,6 +132,7 @@ IconLibrary::IconLibrary() m_icons[openstudio::IddObjectType(openstudio::IddObjectType::OS_Humidifier_Steam_Electric).value()] = new QPixmap(":images/electric_humidifier.png"); m_icons[openstudio::IddObjectType(openstudio::IddObjectType::OS_EvaporativeFluidCooler_SingleSpeed).value()] = new QPixmap(":images/evap_fluid_cooler.png"); m_icons[openstudio::IddObjectType(openstudio::IddObjectType::OS_EvaporativeFluidCooler_TwoSpeed).value()] = new QPixmap(":images/evap_fluid_cooler_two_speed.png"); + m_icons[openstudio::IddObjectType(openstudio::IddObjectType::OS_Generator_MicroTurbine_HeatRecovery).value()] = new QPixmap(":images/generator_microturbine_heatrecovery.png"); m_icons[openstudio::IddObjectType(openstudio::IddObjectType::OS_LoadProfile_Plant).value()] = new QPixmap(":images/plant_profile.png"); m_icons[openstudio::IddObjectType(openstudio::IddObjectType::OS_Pipe_Adiabatic).value()] = new QPixmap(":images/pipe.png"); m_icons[openstudio::IddObjectType(openstudio::IddObjectType::OS_Pipe_Indoor).value()] = new QPixmap(":images/pipe_indoor.png"); @@ -203,6 +204,7 @@ IconLibrary::IconLibrary() m_miniIcons[openstudio::IddObjectType(openstudio::IddObjectType::OS_FluidCooler_TwoSpeed).value()] = new QPixmap(":images/mini_icons/mini_fluid_cooler_two.png"); m_miniIcons[openstudio::IddObjectType(openstudio::IddObjectType::OS_GasEquipment).value()] = new QPixmap(":images/mini_icons/gas_equipment.png"); m_miniIcons[openstudio::IddObjectType(openstudio::IddObjectType::OS_GasEquipment_Definition).value()] = new QPixmap(":images/mini_icons/gas_equipment_definition.png"); + m_miniIcons[openstudio::IddObjectType(openstudio::IddObjectType::OS_Generator_MicroTurbine_HeatRecovery).value()] = new QPixmap(":images/mini_icons/generator_microturbine_heatrecovery.png"); m_miniIcons[openstudio::IddObjectType(openstudio::IddObjectType::OS_GroundHeatExchanger_HorizontalTrench).value()] = new QPixmap(":images/mini_icons/mini_ground_heat_exchanger_horizontal.png"); m_miniIcons[openstudio::IddObjectType(openstudio::IddObjectType::OS_GroundHeatExchanger_Vertical).value()] = new QPixmap(":images/mini_icons/ground_heat_exchanger_vertical.png"); m_miniIcons[openstudio::IddObjectType(openstudio::IddObjectType::OS_HeaderedPumps_ConstantSpeed).value()] = new QPixmap(":images/mini_icons/mini_headered_pumps_constant.png"); diff --git a/openstudiocore/src/openstudio_lib/MainRightColumnController.cpp b/openstudiocore/src/openstudio_lib/MainRightColumnController.cpp index 5095a0ee9e5..95231250145 100644 --- a/openstudiocore/src/openstudio_lib/MainRightColumnController.cpp +++ b/openstudiocore/src/openstudio_lib/MainRightColumnController.cpp @@ -1040,6 +1040,7 @@ void MainRightColumnController::configureForHVACSystemsSubTab(int subTabID) libraryWidget->addModelObjectType(IddObjectType::OS_HeatPump_WaterToWater_EquationFit_Cooling,"Heat Pump - Water to Water - Cooling"); libraryWidget->addModelObjectType(IddObjectType::OS_HeatExchanger_FluidToFluid,"Heat Exchanger Fluid To Fluid"); libraryWidget->addModelObjectType(IddObjectType::OS_HeatExchanger_AirToAir_SensibleAndLatent,"Heat Exchanger Air To Air Sensible and Latent"); + libraryWidget->addModelObjectType(IddObjectType::OS_Generator_MicroTurbine_HeatRecovery,"Generator MicroTurbine - Heat Recovery"); libraryWidget->addModelObjectType(IddObjectType::OS_GroundHeatExchanger_Vertical, "Ground Heat Exchanger - Vertical "); libraryWidget->addModelObjectType(IddObjectType::OS_GroundHeatExchanger_HorizontalTrench,"Ground Heat Exchanger - Horizontal"); libraryWidget->addModelObjectType(IddObjectType::OS_FluidCooler_SingleSpeed,"Fluid Cooler Single Speed"); diff --git a/openstudiocore/src/openstudio_lib/images/generator_microturbine_heatrecovery.png b/openstudiocore/src/openstudio_lib/images/generator_microturbine_heatrecovery.png new file mode 100644 index 00000000000..0841b0a8b55 Binary files /dev/null and b/openstudiocore/src/openstudio_lib/images/generator_microturbine_heatrecovery.png differ diff --git a/openstudiocore/src/openstudio_lib/images/mini_icons/generator_microturbine_heatrecovery.png b/openstudiocore/src/openstudio_lib/images/mini_icons/generator_microturbine_heatrecovery.png new file mode 100644 index 00000000000..6f8f1be89cb Binary files /dev/null and b/openstudiocore/src/openstudio_lib/images/mini_icons/generator_microturbine_heatrecovery.png differ diff --git a/openstudiocore/src/openstudio_lib/library/OpenStudioPolicy.xml b/openstudiocore/src/openstudio_lib/library/OpenStudioPolicy.xml index 1a93f22e794..5cba9f55a3f 100644 --- a/openstudiocore/src/openstudio_lib/library/OpenStudioPolicy.xml +++ b/openstudiocore/src/openstudio_lib/library/OpenStudioPolicy.xml @@ -1557,4 +1557,8 @@ + + + + diff --git a/openstudiocore/src/openstudio_lib/openstudio.qrc b/openstudiocore/src/openstudio_lib/openstudio.qrc index c02914a17bf..5f0b5fa232e 100644 --- a/openstudiocore/src/openstudio_lib/openstudio.qrc +++ b/openstudiocore/src/openstudio_lib/openstudio.qrc @@ -116,6 +116,7 @@ images/furnace_multi_stage.png images/ground_heat_exchanger_horizontal.png images/ground_heat_exchanger_vertical.png + images/generator_microturbine_heatrecovery.png images/header-backgnd-1px-wide.png images/headered_pumps_constant.png images/headered_pumps_variable.png @@ -381,6 +382,7 @@ images/mini_icons/furnace.png images/mini_icons/gas_equipment.png images/mini_icons/gas_equipment_definition.png + images/mini_icons/generator_microturbine_heatrecovery.png images/mini_icons/glare_sensor.png images/mini_icons/grassanddirt.png images/mini_icons/ground_heat_exchanger_vertical.png diff --git a/openstudiocore/src/osversion/VersionTranslator.cpp b/openstudiocore/src/osversion/VersionTranslator.cpp index 85681fd9af1..e549f9c2434 100644 --- a/openstudiocore/src/osversion/VersionTranslator.cpp +++ b/openstudiocore/src/osversion/VersionTranslator.cpp @@ -106,7 +106,8 @@ VersionTranslator::VersionTranslator() m_updateMethods[VersionString("1.10.6")] = &VersionTranslator::update_1_10_5_to_1_10_6; m_updateMethods[VersionString("1.11.4")] = &VersionTranslator::update_1_11_3_to_1_11_4; m_updateMethods[VersionString("1.11.5")] = &VersionTranslator::update_1_11_4_to_1_11_5; - m_updateMethods[VersionString("1.12.1")] = &VersionTranslator::defaultUpdate; + m_updateMethods[VersionString("1.12.1")] = &VersionTranslator::update_1_12_0_to_1_12_1; + m_updateMethods[VersionString("1.12.2")] = &VersionTranslator::defaultUpdate; // List of previous versions that may be updated to this one. @@ -3278,6 +3279,41 @@ std::string VersionTranslator::update_1_11_4_to_1_11_5(const IdfFile& idf_1_11_4 return ss.str(); } +std::string VersionTranslator::update_1_12_0_to_1_12_1(const IdfFile& idf_1_12_0, const IddFileAndFactoryWrapper& idd_1_12_1) { + std::stringstream ss; + + ss << idf_1_12_0.header() << std::endl << std::endl; + + // new version object + IdfFile targetIdf(idd_1_12_1.iddFile()); + ss << targetIdf.versionObject().get(); + + for (const IdfObject& object : idf_1_12_0.objects()) { + auto iddname = object.iddObject().name(); + + if (iddname == "OS:Meter") { + auto iddObject = idd_1_12_1.getObject("OS:Output:Meter"); + IdfObject newObject(iddObject.get()); + + size_t newi = 0; + for( size_t i = 0; i < object.numNonextensibleFields(); ++i ) { + if( auto s = object.getString(i) ) { + newObject.setString(newi,s.get()); + } + ++newi; + } + + m_refactored.push_back( std::pair(object,newObject) ); + ss << newObject; + } else { + ss << object; + } + } + + return ss.str(); +} + + } // osversion } // openstudio diff --git a/openstudiocore/src/osversion/VersionTranslator.hpp b/openstudiocore/src/osversion/VersionTranslator.hpp index 9331dcb71a2..703e69ef7c2 100644 --- a/openstudiocore/src/osversion/VersionTranslator.hpp +++ b/openstudiocore/src/osversion/VersionTranslator.hpp @@ -202,6 +202,7 @@ class OSVERSION_API VersionTranslator { std::string update_1_10_5_to_1_10_6(const IdfFile& idf_1_10_5, const IddFileAndFactoryWrapper& idd_1_10_6); std::string update_1_11_3_to_1_11_4(const IdfFile& idf_1_11_3, const IddFileAndFactoryWrapper& idd_1_11_4); std::string update_1_11_4_to_1_11_5(const IdfFile& idf_1_11_4, const IddFileAndFactoryWrapper& idd_1_11_5); + std::string update_1_12_0_to_1_12_1(const IdfFile& idf_1_12_0, const IddFileAndFactoryWrapper& idd_1_12_1); IdfObject updateUrlField_0_7_1_to_0_7_2(const IdfObject& object, unsigned index); diff --git a/openstudiocore/src/sdd/ForwardTranslator.cpp b/openstudiocore/src/sdd/ForwardTranslator.cpp index 0ca50b5dd73..f583da97e30 100644 --- a/openstudiocore/src/sdd/ForwardTranslator.cpp +++ b/openstudiocore/src/sdd/ForwardTranslator.cpp @@ -83,7 +83,7 @@ #include "../model/LifeCycleCostParameters.hpp" #include "../model/LightingDesignDay.hpp" #include "../model/LightingSimulationControl.hpp" -#include "../model/Meter.hpp" +#include "../model/OutputMeter.hpp" #include "../model/ModelObjectList.hpp" #include "../model/OutputControlReportingTolerances.hpp" #include "../model/OutputVariable.hpp" @@ -510,10 +510,10 @@ namespace sdd { m_ignoreTypes.push_back(model::LifeCycleCostParameters::iddObjectType()); m_ignoreTypes.push_back(model::LightingDesignDay::iddObjectType()); m_ignoreTypes.push_back(model::LightingSimulationControl::iddObjectType()); - m_ignoreTypes.push_back(model::Meter::iddObjectType()); m_ignoreTypes.push_back(model::ModelObjectList::iddObjectType()); m_ignoreTypes.push_back(model::Node::iddObjectType()); m_ignoreTypes.push_back(model::OutputControlReportingTolerances::iddObjectType()); + m_ignoreTypes.push_back(model::OutputMeter::iddObjectType()); m_ignoreTypes.push_back(model::OutputVariable::iddObjectType()); m_ignoreTypes.push_back(model::OutsideSurfaceConvectionAlgorithm::iddObjectType()); m_ignoreTypes.push_back(model::PortList::iddObjectType()); diff --git a/openstudiocore/src/sdd/ReverseTranslator.cpp b/openstudiocore/src/sdd/ReverseTranslator.cpp index 05b9e16e7de..f658201ee54 100644 --- a/openstudiocore/src/sdd/ReverseTranslator.cpp +++ b/openstudiocore/src/sdd/ReverseTranslator.cpp @@ -51,7 +51,7 @@ #include "../model/PlantLoop_Impl.hpp" #include "../model/Timestep.hpp" #include "../model/Timestep_Impl.hpp" -#include "../model/Meter.hpp" +#include "../model/OutputMeter.hpp" #include "../model/OutputVariable.hpp" #include "../model/SimulationControl.hpp" #include "../model/SimulationControl_Impl.hpp" @@ -884,7 +884,7 @@ namespace sdd { } // overall meter for this fuel type - model::Meter meter(*result); + model::OutputMeter meter(*result); meter.setFuelType(FuelType(fuelType)); meter.setInstallLocationType(InstallLocationType::Facility); meter.setReportingFrequency("Hourly"); @@ -904,7 +904,7 @@ namespace sdd { // meter for this fuel type and end use // DLM: many of these will not be applicable and will cause E+ warnings - model::Meter meter(*result); + model::OutputMeter meter(*result); meter.setFuelType(FuelType(fuelType)); meter.setEndUseType(EndUseType(endUseType)); meter.setInstallLocationType(InstallLocationType::Facility); @@ -914,49 +914,49 @@ namespace sdd { // request specific meters // ElectricEquipment - Receptacle, Process, Refrig - model::Meter meter(*result); + model::OutputMeter meter(*result); meter.setFuelType(FuelType::Electricity); meter.setEndUseType(EndUseType::InteriorEquipment); meter.setSpecificEndUse("Receptacle"); meter.setInstallLocationType(InstallLocationType::Facility); meter.setReportingFrequency("Hourly"); - meter = model::Meter(*result); + meter = model::OutputMeter(*result); meter.setFuelType(FuelType::Electricity); meter.setEndUseType(EndUseType::InteriorEquipment); meter.setSpecificEndUse("Process"); meter.setInstallLocationType(InstallLocationType::Facility); meter.setReportingFrequency("Hourly"); - meter = model::Meter(*result); + meter = model::OutputMeter(*result); meter.setFuelType(FuelType::Electricity); meter.setEndUseType(EndUseType::InteriorEquipment); meter.setSpecificEndUse("Refrig"); meter.setInstallLocationType(InstallLocationType::Facility); meter.setReportingFrequency("Hourly"); - meter = model::Meter(*result); + meter = model::OutputMeter(*result); meter.setFuelType(FuelType::Electricity); meter.setEndUseType(EndUseType::InteriorEquipment); meter.setSpecificEndUse("Internal Transport"); meter.setInstallLocationType(InstallLocationType::Facility); meter.setReportingFrequency("Hourly"); - meter = model::Meter(*result); + meter = model::OutputMeter(*result); meter.setFuelType(FuelType::Electricity); meter.setEndUseType(EndUseType::ExteriorEquipment); meter.setSpecificEndUse("Receptacle"); meter.setInstallLocationType(InstallLocationType::Facility); meter.setReportingFrequency("Hourly"); - meter = model::Meter(*result); + meter = model::OutputMeter(*result); meter.setFuelType(FuelType::Electricity); meter.setEndUseType(EndUseType::ExteriorEquipment); meter.setSpecificEndUse("Process"); meter.setInstallLocationType(InstallLocationType::Facility); meter.setReportingFrequency("Hourly"); - meter = model::Meter(*result); + meter = model::OutputMeter(*result); meter.setFuelType(FuelType::Electricity); meter.setEndUseType(EndUseType::ExteriorEquipment); meter.setSpecificEndUse("Refrig"); @@ -964,28 +964,28 @@ namespace sdd { meter.setReportingFrequency("Hourly"); // GasEquipment - Receptacle, Process - meter = model::Meter(*result); + meter = model::OutputMeter(*result); meter.setFuelType(FuelType::Gas); meter.setEndUseType(EndUseType::InteriorEquipment); meter.setSpecificEndUse("Receptacle"); meter.setInstallLocationType(InstallLocationType::Facility); meter.setReportingFrequency("Hourly"); - meter = model::Meter(*result); + meter = model::OutputMeter(*result); meter.setFuelType(FuelType::Gas); meter.setEndUseType(EndUseType::InteriorEquipment); meter.setSpecificEndUse("Process"); meter.setInstallLocationType(InstallLocationType::Facility); meter.setReportingFrequency("Hourly"); - meter = model::Meter(*result); + meter = model::OutputMeter(*result); meter.setFuelType(FuelType::Gas); meter.setEndUseType(EndUseType::ExteriorEquipment); meter.setSpecificEndUse("Receptacle"); meter.setInstallLocationType(InstallLocationType::Facility); meter.setReportingFrequency("Hourly"); - meter = model::Meter(*result); + meter = model::OutputMeter(*result); meter.setFuelType(FuelType::Gas); meter.setEndUseType(EndUseType::ExteriorEquipment); meter.setSpecificEndUse("Process"); @@ -993,14 +993,14 @@ namespace sdd { meter.setReportingFrequency("Hourly"); // Lights - ComplianceLtg, NonComplianceLtg - meter = model::Meter(*result); + meter = model::OutputMeter(*result); meter.setFuelType(FuelType::Electricity); meter.setEndUseType(EndUseType::InteriorLights); meter.setSpecificEndUse("ComplianceLtg"); meter.setInstallLocationType(InstallLocationType::Facility); meter.setReportingFrequency("Hourly"); - meter = model::Meter(*result); + meter = model::OutputMeter(*result); meter.setFuelType(FuelType::Electricity); meter.setEndUseType(EndUseType::InteriorLights); meter.setSpecificEndUse("NonComplianceLtg"); @@ -1008,14 +1008,14 @@ namespace sdd { meter.setReportingFrequency("Hourly"); // Exterior Lights - Reg Ltg, NonReg Ltg - meter = model::Meter(*result); + meter = model::OutputMeter(*result); meter.setFuelType(FuelType::Electricity); meter.setEndUseType(EndUseType::ExteriorLights); meter.setSpecificEndUse("Reg Ltg"); meter.setInstallLocationType(InstallLocationType::Facility); meter.setReportingFrequency("Hourly"); - meter = model::Meter(*result); + meter = model::OutputMeter(*result); meter.setFuelType(FuelType::Electricity); meter.setEndUseType(EndUseType::ExteriorLights); meter.setSpecificEndUse("NonReg Ltg");