boost::optional<IdfObject> ForwardTranslator::translateRefrigerationSubcoolerMechanical( RefrigerationSubcoolerMechanical & modelObject )
{
  OptionalModelObject temp;
  OptionalString optS;
  boost::optional<std::string> s;
  boost::optional<double> d;

  // Name
  IdfObject subcoolerMechanical = createRegisterAndNameIdfObject(openstudio::IddObjectType::Refrigeration_Subcooler, modelObject);

  subcoolerMechanical.setString(Refrigeration_SubcoolerFields::SubcoolerType, "Mechanical");
  
  // Capacity-Providing System
  boost::optional<RefrigerationSystem> capacityProvidingSystem = modelObject.capacityProvidingSystem();

  if( capacityProvidingSystem )
  {
    boost::optional<IdfObject> _capacityProvidingSystem = translateAndMapModelObject(capacityProvidingSystem.get());

    if( _capacityProvidingSystem && _capacityProvidingSystem->name() )
    {
      subcoolerMechanical.setString(Refrigeration_SubcoolerFields::CapacityProvidingSystem,_capacityProvidingSystem->name().get());
    }
  }
   
  // Outlet Control Temperature
  d = modelObject.outletControlTemperature();
  if (d) {
    subcoolerMechanical.setDouble(Refrigeration_SubcoolerFields::OutletControlTemperature,d.get());
  }
  
  return subcoolerMechanical;
}
boost::optional<IdfObject> ForwardTranslator::translateRefrigerationSubcoolerLiquidSuction( RefrigerationSubcoolerLiquidSuction & modelObject )
{
  OptionalModelObject temp;
  OptionalString optS;
  boost::optional<std::string> s;
  boost::optional<double> d;

  // Name
  IdfObject subcoolerLiquidSuction = createRegisterAndNameIdfObject(openstudio::IddObjectType::Refrigeration_Subcooler, modelObject);

  // Subcooler Type
  subcoolerLiquidSuction.setString(Refrigeration_SubcoolerFields::SubcoolerType, "LiquidSuction");

  // Liquid Suction Design Subcooling Temperature Difference
  d = modelObject.liquidSuctionDesignSubcoolingTemperatureDifference();
  if (d) {
    subcoolerLiquidSuction.setDouble(Refrigeration_SubcoolerFields::LiquidSuctionDesignSubcoolingTemperatureDifference,d.get());
  }

  // Design Liquid Inlet Temperature
  d = modelObject.designLiquidInletTemperature();
  if (d) {
    subcoolerLiquidSuction.setDouble(Refrigeration_SubcoolerFields::DesignLiquidInletTemperature,d.get());
  }

  // Design Vapor Inlet Temperature
  d = modelObject.designVaporInletTemperature();
  if (d) {
    subcoolerLiquidSuction.setDouble(Refrigeration_SubcoolerFields::DesignVaporInletTemperature,d.get());
  }

  return subcoolerLiquidSuction;
}
boost::optional<IdfObject> ForwardTranslator::translateElectricLoadCenterInverterSimple(model::ElectricLoadCenterInverterSimple & modelObject)
{
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::ElectricLoadCenter_Inverter_Simple, modelObject);

  if (modelObject.name()) {
    idfObject.setString(ElectricLoadCenter_Inverter_SimpleFields::Name, modelObject.name().get());
  }

  if (modelObject.availabilitySchedule() && modelObject.availabilitySchedule().get().name()) {
    idfObject.setString(ElectricLoadCenter_Inverter_SimpleFields::AvailabilityScheduleName, modelObject.availabilitySchedule().get().name().get());
  }

  if (modelObject.thermalZone() && modelObject.thermalZone().get().name()) {
    idfObject.setString(ElectricLoadCenter_Inverter_SimpleFields::ZoneName, modelObject.thermalZone().get().name().get());
  }

  if (modelObject.radiativeFraction()) {
    idfObject.setDouble(ElectricLoadCenter_Inverter_SimpleFields::RadiativeFraction, modelObject.radiativeFraction().get());
  }

  if (modelObject.inverterEfficiency()) {
    idfObject.setDouble(ElectricLoadCenter_Inverter_SimpleFields::InverterEfficiency, modelObject.inverterEfficiency().get());
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateSetpointManagerSingleZoneHumidityMinimum( SetpointManagerSingleZoneHumidityMinimum & modelObject )
{
  boost::optional<double> d;

  // Name
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::SetpointManager_SingleZone_Humidity_Minimum, modelObject);

  // ControlVariable \deprecated
  // ScheduleName \deprecated

  // ControlZoneAirNodeName
  if( boost::optional<ThermalZone> thermalZone = modelObject.controlZone() )
  {
    auto node = thermalZone->zoneAirNode();
    idfObject.setString(SetpointManager_SingleZone_Humidity_MinimumFields::ControlZoneAirNodeName,node.name().get());
  }

  // Setpoint Node or NodeList Name
  if( boost::optional<Node> node = modelObject.setpointNode() )
  {
    idfObject.setString(SetpointManager_SingleZone_Humidity_MinimumFields::SetpointNodeorNodeListName,node->name().get());
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateGeneratorPVWatts(model::GeneratorPVWatts & modelObject)
{
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::Generator_PVWatts, modelObject);

  idfObject.setString(Generator_PVWattsFields::PVWattsVersion, modelObject.pvWattsVersion());

  idfObject.setDouble(Generator_PVWattsFields::DCSystemCapacity, modelObject.dcSystemCapacity());

  idfObject.setString(Generator_PVWattsFields::ModuleType, modelObject.moduleType());

  idfObject.setString(Generator_PVWattsFields::ArrayType, modelObject.arrayType());

  idfObject.setDouble(Generator_PVWattsFields::SystemLosses, modelObject.systemLosses());

  boost::optional<PlanarSurface> surface = modelObject.surface();
  if (surface){
    boost::optional<IdfObject> surfaceIdf = translateAndMapModelObject(*surface);
    if (surfaceIdf){
      idfObject.setString(Generator_PVWattsFields::ArrayGeometryType, "Surface");
      idfObject.setString(Generator_PVWattsFields::SurfaceName, surfaceIdf->name().get());
    }
  } else {
    idfObject.setString(Generator_PVWattsFields::ArrayGeometryType, "TiltAzimuth");
    idfObject.setDouble(Generator_PVWattsFields::TiltAngle, modelObject.tiltAngle());
    idfObject.setDouble(Generator_PVWattsFields::AzimuthAngle, modelObject.azimuthAngle());
  }

  idfObject.setDouble(Generator_PVWattsFields::GroundCoverageRatio, modelObject.groundCoverageRatio());

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateZoneControlHumidistat( ZoneControlHumidistat& modelObject )
{
  // Name
  IdfObject object = createRegisterAndNameIdfObject(openstudio::IddObjectType::ZoneControl_Humidistat, modelObject);

  // Zone Name
  // set by ThermalZone

  // Humidifying Relative Humidity Setpoint Schedule Name
  if( OptionalSchedule humidifyingSchedule = modelObject.humidifyingRelativeHumiditySetpointSchedule() )
  {
    boost::optional<IdfObject> _humidifyingSchedule = translateAndMapModelObject(humidifyingSchedule.get());

    if( _humidifyingSchedule && _humidifyingSchedule->name() )
    {
      object.setString(ZoneControl_HumidistatFields::HumidifyingRelativeHumiditySetpointScheduleName,_humidifyingSchedule->name().get());
    }
  }

  // Dehumidifying Relative Humidity Setpoint Schedule Name
  if( OptionalSchedule dehumidifyingSchedule = modelObject.dehumidifyingRelativeHumiditySetpointSchedule() )
  {
    boost::optional<IdfObject> _dehumidifyingSchedule = translateAndMapModelObject(dehumidifyingSchedule.get());

    if( _dehumidifyingSchedule && _dehumidifyingSchedule->name() )
    {
      object.setString(ZoneControl_HumidistatFields::DehumidifyingRelativeHumiditySetpointScheduleName,_dehumidifyingSchedule->name().get());
    }
  }

  return object;
}
boost::optional<IdfObject> ForwardTranslator::translateSetpointManagerSingleZoneOneStageCooling( SetpointManagerSingleZoneOneStageCooling & modelObject )
{
  std::string s;
  double n;
  boost::optional<Node> node;

  // Name
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::SetpointManager_SingleZone_OneStageCooling, modelObject);

  // CoolingStageOnSupplyAirSetpointTemperature
  n = modelObject.coolingStageOnSupplyAirSetpointTemperature();
  idfObject.setDouble(SetpointManager_SingleZone_OneStageCoolingFields::CoolingStageOnSupplyAirSetpointTemperature,n);

  // CoolingStageOffSupplyAirSetpointTemperature
  n = modelObject.coolingStageOffSupplyAirSetpointTemperature();
  idfObject.setDouble(SetpointManager_SingleZone_OneStageCoolingFields::CoolingStageOffSupplyAirSetpointTemperature,n);

  // ControlZoneName
  boost::optional<ThermalZone> thermalZone = modelObject.controlZone();
  if( thermalZone )
  {
    idfObject.setString(SetpointManager_SingleZone_OneStageCoolingFields::ControlZoneName,thermalZone->name().get());
  }

  // SetpointNodeorNodeListName
  node = modelObject.setpointNode();
  if( node )
  {
    idfObject.setString(SetpointManager_SingleZone_OneStageCoolingFields::SetpointNodeorNodeListName,node->name().get());
  }
  
  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateSetpointManagerMultiZoneMinimumHumidityAverage( SetpointManagerMultiZoneMinimumHumidityAverage & modelObject )
{
    boost::optional<double> d;

    // Name
    IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::SetpointManager_MultiZone_MinimumHumidity_Average, modelObject);

    // HVACAirLoopName
    if( boost::optional<AirLoopHVAC> airloop = modelObject.airLoopHVAC() )
    {
        idfObject.setString(SetpointManager_MultiZone_MinimumHumidity_AverageFields::HVACAirLoopName,airloop->name().get());
    }

    // Minimum Setpoint Humidity Ratio
    d = modelObject.minimumSetpointHumidityRatio();
    if( d )
    {
        idfObject.setDouble(SetpointManager_MultiZone_MinimumHumidity_AverageFields::MinimumSetpointHumidityRatio,d.get());
    }

    // Maximum Setpoint Humidity Ratio
    d = modelObject.maximumSetpointHumidityRatio();
    if( d )
    {
        idfObject.setDouble(SetpointManager_MultiZone_MinimumHumidity_AverageFields::MaximumSetpointHumidityRatio,d.get());
    }

    // Setpoint Node or NodeList Name
    if( boost::optional<Node> node = modelObject.setpointNode() )
    {
        idfObject.setString(SetpointManager_MultiZone_MinimumHumidity_AverageFields::SetpointNodeorNodeListName,node->name().get());
    }

    return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateElectricLoadCenterInverterLookUpTable(model::ElectricLoadCenterInverterLookUpTable & modelObject)
{
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::ElectricLoadCenter_Inverter_LookUpTable, modelObject);

  if (modelObject.name()) {
    idfObject.setString(ElectricLoadCenter_Inverter_LookUpTableFields::Name, modelObject.name().get());
  }

  if (modelObject.availabilitySchedule() && modelObject.availabilitySchedule().get().name()) {
    idfObject.setString(ElectricLoadCenter_Inverter_LookUpTableFields::AvailabilityScheduleName, modelObject.availabilitySchedule().get().name().get());
  }

  if (modelObject.thermalZone() && modelObject.thermalZone().get().name()) {
    idfObject.setString(ElectricLoadCenter_Inverter_LookUpTableFields::ZoneName, modelObject.thermalZone().get().name().get());
  }

  if (modelObject.radiativeFraction()) {
    idfObject.setDouble(ElectricLoadCenter_Inverter_LookUpTableFields::RadiativeFraction, modelObject.radiativeFraction().get());
  }

  if (modelObject.ratedMaximumContinuousOutputPower()) {
    idfObject.setDouble(ElectricLoadCenter_Inverter_LookUpTableFields::RatedMaximumContinuousOutputPower, modelObject.ratedMaximumContinuousOutputPower().get());
  }

  if (modelObject.nightTareLossPower()) {
    idfObject.setDouble(ElectricLoadCenter_Inverter_LookUpTableFields::NightTareLossPower, modelObject.nightTareLossPower().get());
  }

  if (modelObject.nominalVoltageInput()) {
    idfObject.setDouble(ElectricLoadCenter_Inverter_LookUpTableFields::NominalVoltageInput, modelObject.nominalVoltageInput().get());
  }

  if (modelObject.efficiencyAt10PowerAndNominalVoltage()) {
    idfObject.setDouble(ElectricLoadCenter_Inverter_LookUpTableFields::Efficiencyat10_PowerandNominalVoltage, modelObject.efficiencyAt10PowerAndNominalVoltage().get());
  }

  if (modelObject.efficiencyAt20PowerAndNominalVoltage()) {
    idfObject.setDouble(ElectricLoadCenter_Inverter_LookUpTableFields::Efficiencyat20_PowerandNominalVoltage, modelObject.efficiencyAt20PowerAndNominalVoltage().get());
  }

  if (modelObject.efficiencyAt30PowerAndNominalVoltage()) {
    idfObject.setDouble(ElectricLoadCenter_Inverter_LookUpTableFields::Efficiencyat30_PowerandNominalVoltage, modelObject.efficiencyAt30PowerAndNominalVoltage().get());
  }

  if (modelObject.efficiencyAt50PowerAndNominalVoltage()) {
    idfObject.setDouble(ElectricLoadCenter_Inverter_LookUpTableFields::Efficiencyat50_PowerandNominalVoltage, modelObject.efficiencyAt50PowerAndNominalVoltage().get());
  }

  if (modelObject.efficiencyAt75PowerAndNominalVoltage()) {
    idfObject.setDouble(ElectricLoadCenter_Inverter_LookUpTableFields::Efficiencyat75_PowerandNominalVoltage, modelObject.efficiencyAt75PowerAndNominalVoltage().get());
  }

  if (modelObject.efficiencyAt100PowerAndNominalVoltage()) {
    idfObject.setDouble(ElectricLoadCenter_Inverter_LookUpTableFields::Efficiencyat100_PowerandNominalVoltage, modelObject.efficiencyAt100PowerAndNominalVoltage().get());
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateSurfacePropertyOtherSideConditionsModel(model::SurfacePropertyOtherSideConditionsModel & modelObject)
{
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::SurfaceProperty_OtherSideConditionsModel,
                                                       modelObject);

  idfObject.setString(SurfaceProperty_OtherSideConditionsModelFields::TypeofModeling, modelObject.typeOfModeling());
  
  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateRefrigerationCondenserCascade( RefrigerationCondenserCascade & modelObject )
{
  OptionalModelObject temp;
  OptionalString optS;
  boost::optional<std::string> s;
  boost::optional<double> d;

  // Name
  IdfObject cascade = createRegisterAndNameIdfObject(openstudio::IddObjectType::Refrigeration_Condenser_Cascade, modelObject);

  // Rated Condensing Temperature
  d = modelObject.ratedCondensingTemperature();
  if (d) {
    cascade.setDouble(Refrigeration_Condenser_CascadeFields::RatedCondensingTemperature,d.get());
  }

  // Rated Approach Temperature Difference
  d = modelObject.ratedApproachTemperatureDifference();
  if (d) {
    cascade.setDouble(Refrigeration_Condenser_CascadeFields::RatedApproachTemperatureDifference,d.get());
  }

  // Rated Effective Total Heat Rejection Rate
  d = modelObject.ratedEffectiveTotalHeatRejectionRate();
  if (d) {
    cascade.setDouble(Refrigeration_Condenser_CascadeFields::RatedEffectiveTotalHeatRejectionRate,d.get());
  }

  // Condensing Temperature Control Type
  s = modelObject.condensingTemperatureControlType();
  if (s) {
    cascade.setString(Refrigeration_Condenser_CascadeFields::CondensingTemperatureControlType,s.get());
  }

  // Condenser Refrigerant Operating Charge Inventory
  d = modelObject.condenserRefrigerantOperatingChargeInventory();
  if (d) {
    cascade.setDouble(Refrigeration_Condenser_CascadeFields::CondenserRefrigerantOperatingChargeInventory,d.get());
  }

  // Condensate Receiver Refrigerant Inventory
  d = modelObject.condensateReceiverRefrigerantInventory();
  if (d) {
    cascade.setDouble(Refrigeration_Condenser_CascadeFields::CondensateReceiverRefrigerantInventory,d.get());
  }

  // Condensate Piping Refrigerant Inventory
  d = modelObject.condensatePipingRefrigerantInventory();
  if (d) {
    cascade.setDouble(Refrigeration_Condenser_CascadeFields::CondensatePipingRefrigerantInventory,d.get());
  }
  
  return cascade;

}
boost::optional<IdfObject> ForwardTranslator::translateAvailabilityManagerScheduledOff(
    AvailabilityManagerScheduledOff & modelObject)
{
  IdfObject idfObject = createRegisterAndNameIdfObject(IddObjectType::AvailabilityManager_ScheduledOff, modelObject);

  // Schedule
  {
    Schedule sch = modelObject.schedule();
    idfObject.setString(AvailabilityManager_ScheduledOffFields::ScheduleName, sch.name().get());
  }
  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateScheduleDay( ScheduleDay & modelObject )
{
  IdfObject scheduleDay = createRegisterAndNameIdfObject(openstudio::IddObjectType::Schedule_Day_Interval,
                                                         modelObject);

  boost::optional<ScheduleTypeLimits> scheduleTypeLimits = modelObject.scheduleTypeLimits();
  if (scheduleTypeLimits){
    boost::optional<IdfObject> idfScheduleTypeLimits = translateAndMapModelObject(*scheduleTypeLimits);
    if (idfScheduleTypeLimits){
      scheduleDay.setString(Schedule_Day_IntervalFields::ScheduleTypeLimitsName, idfScheduleTypeLimits->name().get());
    }
  }

  if (modelObject.interpolatetoTimestep()){
    scheduleDay.setString(Schedule_Day_IntervalFields::InterpolatetoTimestep, "Yes");
  }else{
    scheduleDay.setString(Schedule_Day_IntervalFields::InterpolatetoTimestep, "No");
  }

  std::vector<double> values = modelObject.values();
  std::vector<openstudio::Time> times = modelObject.times();
  
  unsigned N = values.size();
  OS_ASSERT(N == times.size());

  scheduleDay.clearExtensibleGroups();

  for (unsigned i = 0; i < N; ++i){
    IdfExtensibleGroup group = scheduleDay.pushExtensibleGroup();

    std::string hourPrefix;
    std::string minutePrefix;

    int hours = times[i].hours() + 24*times[i].days();
    if (hours < 10){
      hourPrefix = "0";
    }

    int minutes = times[i].minutes() + floor((times[i].seconds()/60.0) + 0.5);
    if (minutes < 10){
      minutePrefix = "0";
    }

    std::stringstream ss;
    ss << hourPrefix << hours << ":" << minutePrefix << minutes;

    group.setString(Schedule_Day_IntervalExtensibleFields::Time, ss.str());
    group.setDouble(Schedule_Day_IntervalExtensibleFields::ValueUntilTime, values[i]);
  }

  return scheduleDay;
}
boost::optional<IdfObject> ForwardTranslator::translateSetpointManagerFollowGroundTemperature( 
                              SetpointManagerFollowGroundTemperature & modelObject )
{
  boost::optional<Node> node;
  boost::optional<std::string> s;
  boost::optional<double> d;

  // Name
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::SetpointManager_FollowGroundTemperature, modelObject);

  // ControlVariable
  s = modelObject.controlVariable();
  if( s )
  {
    idfObject.setString(SetpointManager_FollowGroundTemperatureFields::ControlVariable,s.get());
  }

  // ReferenceGroundTemperatureObjectType
  idfObject.setString(SetpointManager_FollowGroundTemperatureFields::ReferenceGroundTemperatureObjectType,"Site:GroundTemperature:BuildingSurface");

  // OffsetTemperatureDifference
  d = modelObject.offsetTemperatureDifference();
  if( d )
  {
    idfObject.setDouble(SetpointManager_FollowGroundTemperatureFields::OffsetTemperatureDifference,d.get());
  }

  // MaximumSetpointTemperature
  d = modelObject.maximumSetpointTemperature();
  if( d )
  {
    idfObject.setDouble(SetpointManager_FollowGroundTemperatureFields::MaximumSetpointTemperature,d.get());
  }
  
  // MinimumSetpointTemperature
  d = modelObject.minimumSetpointTemperature();
  if( d )
  {
    idfObject.setDouble(SetpointManager_FollowGroundTemperatureFields::MinimumSetpointTemperature,d.get());
  }

  // SetpointNodeorNodeListName
  node = modelObject.setpointNode();
  if( node )
  {
    idfObject.setString(SetpointManager_FollowGroundTemperatureFields::SetpointNodeorNodeListName,node->name().get());
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translatePhotovoltaicPerformanceEquivalentOneDiode(model::PhotovoltaicPerformanceEquivalentOneDiode & modelObject)
{
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::PhotovoltaicPerformance_EquivalentOneDiode, modelObject);

  if (modelObject.name()) {
    idfObject.setString(PhotovoltaicPerformance_EquivalentOneDiodeFields::Name, modelObject.name().get());
  }

  idfObject.setString(PhotovoltaicPerformance_EquivalentOneDiodeFields::Celltype, modelObject.celltype());

  idfObject.setInt(PhotovoltaicPerformance_EquivalentOneDiodeFields::NumberofCellsinSeries, modelObject.numberOfCellsInSeries());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::ActiveArea, modelObject.activeArea());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::TransmittanceAbsorptanceProduct, modelObject.transmittanceAbsorptanceProduct());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::SemiconductorBandgap, modelObject.semiconductorBandgap());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::ShuntResistance, modelObject.shuntResistance());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::ShortCircuitCurrent, modelObject.shortCircuitCurrent());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::OpenCircuitVoltage, modelObject.openCircuitVoltage());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::ReferenceTemperature, modelObject.referenceTemperature());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::ReferenceInsolation, modelObject.referenceInsolation());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::ModuleCurrentatMaximumPower, modelObject.moduleCurrentatMaximumPower());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::ModuleVoltageatMaximumPower, modelObject.moduleVoltageatMaximumPower());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::TemperatureCoefficientofShortCircuitCurrent, modelObject.temperatureCoefficientofShortCircuitCurrent());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::TemperatureCoefficientofOpenCircuitVoltage, modelObject.temperatureCoefficientofOpenCircuitVoltage());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::NominalOperatingCellTemperatureTestAmbientTemperature, modelObject.nominalOperatingCellTemperatureTestAmbientTemperature());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::NominalOperatingCellTemperatureTestCellTemperature, modelObject.nominalOperatingCellTemperatureTestCellTemperature());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::NominalOperatingCellTemperatureTestInsolation, modelObject.nominalOperatingCellTemperatureTestInsolation());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::ModuleHeatLossCoefficient, modelObject.moduleHeatLossCoefficient());

  idfObject.setDouble(PhotovoltaicPerformance_EquivalentOneDiodeFields::TotalHeatCapacity, modelObject.totalHeatCapacity());

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateScheduleYear( ScheduleYear & modelObject )
{
  IdfObject scheduleYear = createRegisterAndNameIdfObject(openstudio::IddObjectType::Schedule_Year,
                                                          modelObject);

  std::vector<ScheduleWeek> scheduleWeeks = modelObject.scheduleWeeks();
  std::vector<openstudio::Date> dates = modelObject.dates();
  
  unsigned N = scheduleWeeks.size();

  if( N != dates.size() )
  {
    LOG(Error,"Could not translate " << modelObject.briefDescription() << ", because the number of week schedules does not match the number of dates.");

    return boost::none;
  }

  boost::optional<ScheduleTypeLimits> scheduleTypeLimits = modelObject.scheduleTypeLimits();
  if (scheduleTypeLimits){
    boost::optional<IdfObject> idfScheduleTypeLimits = translateAndMapModelObject(*scheduleTypeLimits);
    if (idfScheduleTypeLimits){
      scheduleYear.setString(Schedule_YearFields::ScheduleTypeLimitsName, idfScheduleTypeLimits->name().get());
    }
  }

  openstudio::Date startDate(MonthOfYear::Jan, 1);

  scheduleYear.clearExtensibleGroups();

  for (unsigned i = 0; i < N; ++i){
    IdfExtensibleGroup group = scheduleYear.pushExtensibleGroup();

    boost::optional<IdfObject> idfScheduleWeek = translateAndMapModelObject(scheduleWeeks[i]);
    if (idfScheduleWeek){
      group.setString(Schedule_YearExtensibleFields::Schedule_WeekName, idfScheduleWeek->name().get());
    }

    group.setInt(Schedule_YearExtensibleFields::StartMonth, startDate.monthOfYear().value());
    group.setUnsigned(Schedule_YearExtensibleFields::StartDay, startDate.dayOfMonth());
    group.setInt(Schedule_YearExtensibleFields::EndMonth, dates[i].monthOfYear().value());
    group.setUnsigned(Schedule_YearExtensibleFields::EndDay, dates[i].dayOfMonth());

    startDate = dates[i] + openstudio::Time(1,0,0);
  }

  return scheduleYear;
}
boost::optional<IdfObject> ForwardTranslator::translateSetpointManagerColdest( SetpointManagerColdest & modelObject )
{
  boost::optional<Node> node;
  boost::optional<double> value;
  std::string s;

  // Name
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::SetpointManager_Coldest, modelObject);

  // ControlVariable
  s = modelObject.controlVariable();
  idfObject.setString(SetpointManager_ColdestFields::ControlVariable,s);

  // MinimumSetpointTemperature
  value = modelObject.minimumSetpointTemperature();
  if( value )
  {
    idfObject.setDouble(SetpointManager_ColdestFields::MinimumSetpointTemperature,value.get());
  }

  // MaximumSetpointTemperature
  value = modelObject.maximumSetpointTemperature();
  if( value )
  {
    idfObject.setDouble(SetpointManager_ColdestFields::MaximumSetpointTemperature,value.get());
  }

  // Strategy
  s = modelObject.strategy();
  idfObject.setString(SetpointManager_ColdestFields::Strategy,s);

  // SetpointNodeorNodeListName
  node = modelObject.setpointNode();
  if( node )
  {
    idfObject.setString(SetpointManager_ColdestFields::SetpointNodeorNodeListName,node->name().get());

    // HVACAirLoopName
    if( boost::optional<model::AirLoopHVAC> airLoop = node->airLoopHVAC() )
    {
      idfObject.setString(SetpointManager_ColdestFields::HVACAirLoopName,airLoop->name().get());
    }
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateZoneAirMassFlowConservation(
    ZoneAirMassFlowConservation & modelObject)
{
  // Makes sure the modelObject gets put in the map, and that the new idfObject gets put in 
  // the final file. Also set's the idfObject's name.
  IdfObject idfObject = createRegisterAndNameIdfObject(IddObjectType::ZoneAirMassFlowConservation, modelObject);

  if (modelObject.adjustZoneMixingForZoneAirMassFlowBalance()){
    idfObject.setString(ZoneAirMassFlowConservationFields::AdjustZoneMixingForZoneAirMassFlowBalance, "Yes");
  }else{
    idfObject.setString(ZoneAirMassFlowConservationFields::AdjustZoneMixingForZoneAirMassFlowBalance, "No");
  }

  idfObject.setString(ZoneAirMassFlowConservationFields::SourceZoneInfiltrationTreatment, modelObject.sourceZoneInfiltrationTreatment());
  
  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateSetpointManagerScheduledDualSetpoint( SetpointManagerScheduledDualSetpoint & modelObject )
{
  // Name
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::SetpointManager_Scheduled_DualSetpoint, modelObject);

  // ControlVariable
  std::string s = modelObject.controlVariable();
  idfObject.setString(SetpointManager_Scheduled_DualSetpointFields::ControlVariable,s);

  // High Setpoint Schedule Name
  if( boost::optional<Schedule> highSetpointSchedule = modelObject.highSetpointSchedule() )
  {
    boost::optional<IdfObject> _highSetpointSchedule = translateAndMapModelObject(highSetpointSchedule.get());
    if( _highSetpointSchedule && _highSetpointSchedule->name() )
    {
      idfObject.setString(SetpointManager_Scheduled_DualSetpointFields::HighSetpointScheduleName,_highSetpointSchedule->name().get());
    }
  } else {
    LOG(Error, "SetpointManager:Scheduled:DualSetpoint '" << modelObject.name().get() << "' is missing required high setpoint schedule");
  }

  // Low Setpoint Schedule Name
  if( boost::optional<Schedule> lowSetpointSchedule = modelObject.lowSetpointSchedule() )
  {
    boost::optional<IdfObject> _lowSetpointSchedule = translateAndMapModelObject(lowSetpointSchedule.get());
    if( _lowSetpointSchedule && _lowSetpointSchedule->name() )
    {
      idfObject.setString(SetpointManager_Scheduled_DualSetpointFields::LowSetpointScheduleName,_lowSetpointSchedule->name().get());
    }
  } else {
    LOG(Error, "SetpointManager:Scheduled:DualSetpoint '" << modelObject.name().get() << "' is missing required low setpoint schedule");
  }

  // SetpointNodeorNodeListName
  if( boost::optional<Node> node = modelObject.setpointNode() )
  {
    idfObject.setString(SetpointManager_Scheduled_DualSetpointFields::SetpointNodeorNodeListName,node->name().get());
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translatePhotovoltaicPerformanceSimple(model::PhotovoltaicPerformanceSimple & modelObject)
{
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::PhotovoltaicPerformance_Simple, modelObject);

  if (modelObject.name()) {
    idfObject.setString(PhotovoltaicPerformance_SimpleFields::Name, modelObject.name().get());
  }

  idfObject.setString(PhotovoltaicPerformance_SimpleFields::ConversionEfficiencyInputMode, modelObject.conversionEfficiencyInputMode());

  idfObject.setDouble(PhotovoltaicPerformance_SimpleFields::FractionofSurfaceAreawithActiveSolarCells, modelObject.fractionOfSurfaceAreaWithActiveSolarCells());
  
  if (modelObject.fixedEfficiency()) {
    idfObject.setDouble(PhotovoltaicPerformance_SimpleFields::ValueforCellEfficiencyifFixed, modelObject.fixedEfficiency().get());
  }

  if (modelObject.efficiencySchedule() && modelObject.efficiencySchedule().get().name()) {
    idfObject.setString(PhotovoltaicPerformance_SimpleFields::EfficiencyScheduleName, modelObject.efficiencySchedule().get().name().get());
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateZoneHVACBaseboardConvectiveElectric(
    ZoneHVACBaseboardConvectiveElectric & modelObject )
{
  // Makes sure the modelObject gets put in the map, and that the new idfObject gets put in 
  // the final file. Also set's the idfObject's name.
  IdfObject idfObject = createRegisterAndNameIdfObject(IddObjectType::ZoneHVAC_Baseboard_Convective_Electric,modelObject);

  boost::optional<std::string> s;
  boost::optional<double> value;
  boost::optional<ModelObject> temp;
  
  // AvailabilityScheduleName
  Schedule availabilitySchedule = modelObject.availabilitySchedule();
  translateAndMapModelObject(availabilitySchedule);
  idfObject.setString(ZoneHVAC_Baseboard_Convective_ElectricFields::AvailabilityScheduleName,
                      availabilitySchedule.name().get() );

  // NominalCapacity

  if( modelObject.isNominalCapacityAutosized() )
  {
    idfObject.setString(ZoneHVAC_Baseboard_Convective_ElectricFields::NominalCapacity,"Autosize");
  }
  else if( value = modelObject.nominalCapacity() )
  {
    idfObject.setDouble(ZoneHVAC_Baseboard_Convective_ElectricFields::NominalCapacity,value.get());
  }

  // Efficiency

  if( value = modelObject.efficiency() )
  {
    idfObject.setDouble(ZoneHVAC_Baseboard_Convective_ElectricFields::Efficiency,value.get());
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateZoneHVACIdealLoadsAirSystem(ZoneHVACIdealLoadsAirSystem & modelObject)
{
  
  IdfObject zoneHVACIdealLoadsAirSystem = createRegisterAndNameIdfObject(openstudio::IddObjectType::ZoneHVAC_IdealLoadsAirSystem,modelObject);
  
  // availability schedule name
  boost::optional<Schedule> schedule = modelObject.availabilitySchedule();
  if(schedule){
    boost::optional<IdfObject> idfSchedule = translateAndMapModelObject(*schedule);
    if(idfSchedule){
      zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::AvailabilityScheduleName,idfSchedule->name().get());
    }
  }

  // zone supply air node name
  boost::optional<std::string> zoneSupplyAirNodeName;
  if(boost::optional<Node> node = modelObject.outletNode()){
    if(boost::optional<std::string> s = node->name()){
      zoneSupplyAirNodeName = s;
      zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::ZoneSupplyAirNodeName,s.get());
    }
  }

  // zone exhaust air node name
  boost::optional<std::string> zoneExhaustAirNodeName;
  if(boost::optional<Node> node = modelObject.inletNode()){
    if(boost::optional<std::string> s = node->name()){
      zoneExhaustAirNodeName = s;
      zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::ZoneExhaustAirNodeName,s.get());
    }
  }

  // maximum heating supply air temperature
  if(! modelObject.isMaximumHeatingSupplyAirTemperatureDefaulted()){
    zoneHVACIdealLoadsAirSystem.setDouble(ZoneHVAC_IdealLoadsAirSystemFields::MaximumHeatingSupplyAirTemperature,modelObject.maximumHeatingSupplyAirTemperature());
  }

  // minimum cooling supply air temperature
  if (! modelObject.isMinimumCoolingSupplyAirTemperatureDefaulted()){
    zoneHVACIdealLoadsAirSystem.setDouble(ZoneHVAC_IdealLoadsAirSystemFields::MinimumCoolingSupplyAirTemperature,modelObject.minimumCoolingSupplyAirTemperature());
  }

  // maximum heating supply air humidity ratio
  if (! modelObject.isMaximumHeatingSupplyAirHumidityRatioDefaulted()){
    zoneHVACIdealLoadsAirSystem.setDouble(ZoneHVAC_IdealLoadsAirSystemFields::MaximumHeatingSupplyAirHumidityRatio,modelObject.maximumHeatingSupplyAirHumidityRatio());
  }

  // minimum cooling supply air humidity ratio
  if (! modelObject.isMinimumCoolingSupplyAirHumidityRatioDefaulted()){
    zoneHVACIdealLoadsAirSystem.setDouble(ZoneHVAC_IdealLoadsAirSystemFields::MinimumCoolingSupplyAirHumidityRatio,modelObject.minimumCoolingSupplyAirHumidityRatio());
  }

  // heating limit
  if (! modelObject.isHeatingLimitDefaulted()){
    zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::HeatingLimit,modelObject.heatingLimit());
  }

  // maximum heating air flow rate
  if(modelObject.isMaximumHeatingAirFlowRateAutosized()){
    zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::MaximumHeatingAirFlowRate,"Autosize");
  }else if(boost::optional<double> d = modelObject.maximumHeatingAirFlowRate()){
    zoneHVACIdealLoadsAirSystem.setDouble(ZoneHVAC_IdealLoadsAirSystemFields::MaximumHeatingAirFlowRate,d.get());
  }

  // maximum sensible heating capacity
  if(modelObject.isMaximumSensibleHeatingCapacityAutosized()){
    zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::MaximumSensibleHeatingCapacity,"Autosize");
  }else if(boost::optional<double> d = modelObject.maximumSensibleHeatingCapacity()){
    zoneHVACIdealLoadsAirSystem.setDouble(ZoneHVAC_IdealLoadsAirSystemFields::MaximumSensibleHeatingCapacity,d.get());
  }

  // cooling limit
  if (! modelObject.isCoolingLimitDefaulted()){
    zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::CoolingLimit,modelObject.coolingLimit());
  }

  // maximum cooling air flow rate
  if(modelObject.isMaximumCoolingAirFlowRateAutosized()){
    zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::MaximumCoolingAirFlowRate,"Autosize");
  }else if(boost::optional<double> d = modelObject.maximumCoolingAirFlowRate()){
    zoneHVACIdealLoadsAirSystem.setDouble(ZoneHVAC_IdealLoadsAirSystemFields::MaximumCoolingAirFlowRate,d.get());
  }

  // maximum total cooling capacity
  if(modelObject.isMaximumTotalCoolingCapacityAutosized()){
    zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::MaximumTotalCoolingCapacity,"Autosize");
  }else if(boost::optional<double> d = modelObject.maximumTotalCoolingCapacity()){
    zoneHVACIdealLoadsAirSystem.setDouble(ZoneHVAC_IdealLoadsAirSystemFields::MaximumTotalCoolingCapacity,d.get());
  }

  // heating availability schedule name
  if(boost::optional<Schedule> schedule = modelObject.heatingAvailabilitySchedule()){
    if(boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get())){
      zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::HeatingAvailabilityScheduleName,_schedule->name().get());
    }
  }

 // cooling availability schedule name
  if(boost::optional<Schedule> schedule = modelObject.coolingAvailabilitySchedule()){
    if(boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get())){
      zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::CoolingAvailabilityScheduleName,_schedule->name().get());
    }
  }

  // dehumidification control type
  if (! modelObject.isDehumidificationControlTypeDefaulted()){
    zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::DehumidificationControlType,modelObject.dehumidificationControlType());
  }

  // cooling sensible heat ratio
  if (! modelObject.isCoolingSensibleHeatRatioDefaulted()){
    zoneHVACIdealLoadsAirSystem.setDouble(ZoneHVAC_IdealLoadsAirSystemFields::CoolingSensibleHeatRatio,modelObject.coolingSensibleHeatRatio());
  }

  // humidification control type
  if (! modelObject.isHumidificationControlTypeDefaulted()){
    zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::HumidificationControlType,modelObject.humidificationControlType());
  }

  // forward translate design specification outdoor air object name
  // get the zone that this piece of equipment is connected to
  boost::optional<ThermalZone> zone = modelObject.thermalZone();
  if (zone) {
    // get this zone's space
    std::vector<Space> spaces = zone->spaces();
    // get the space's design specification outdoor air, if one exists
    if ( ! spaces.empty() ){
      boost::optional<DesignSpecificationOutdoorAir> designSpecificationOutdoorAir;
      designSpecificationOutdoorAir = spaces[0].designSpecificationOutdoorAir();
      if (designSpecificationOutdoorAir){
        // translate the design specification outdoor air to idf      
        boost::optional<IdfObject> designSpecificationOutdoorAirIdf;
        designSpecificationOutdoorAirIdf = translateAndMapModelObject(*designSpecificationOutdoorAir);
        // the translation should complete successfully
        OS_ASSERT(designSpecificationOutdoorAirIdf);      
        // set the field to reference the design specification outdoor air
        zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::DesignSpecificationOutdoorAirObjectName,designSpecificationOutdoorAirIdf->name().get()); 
      }
    }
  }

  // demand controlled ventilation type
  if (! modelObject.isDemandControlledVentilationTypeDefaulted()){
    zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::DemandControlledVentilationType,modelObject.demandControlledVentilationType());
  }

  // outdoor air economizer type
  if (! modelObject.isOutdoorAirEconomizerTypeDefaulted()){
    zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::OutdoorAirEconomizerType,modelObject.outdoorAirEconomizerType());
  }

  // heat recovery type
  if (! modelObject.isHeatRecoveryTypeDefaulted()){
    zoneHVACIdealLoadsAirSystem.setString(ZoneHVAC_IdealLoadsAirSystemFields::HeatRecoveryType,modelObject.heatRecoveryType());
  }

  // sensible heat recovery effectiveness
  if (! modelObject.isSensibleHeatRecoveryEffectivenessDefaulted()){
    zoneHVACIdealLoadsAirSystem.setDouble(ZoneHVAC_IdealLoadsAirSystemFields::SensibleHeatRecoveryEffectiveness,modelObject.sensibleHeatRecoveryEffectiveness());
  }

  // latent heat recovery effectiveness
  if (! modelObject.isLatentHeatRecoveryEffectivenessDefaulted()){
    zoneHVACIdealLoadsAirSystem.setDouble(ZoneHVAC_IdealLoadsAirSystemFields::LatentHeatRecoveryEffectiveness,modelObject.latentHeatRecoveryEffectiveness());
  }

  return zoneHVACIdealLoadsAirSystem;
}
boost::optional<IdfObject> ForwardTranslator::translateCoilHeatingGasMultiStage( CoilHeatingGasMultiStage & modelObject )
{
  boost::optional<std::string> s;
  boost::optional<double> value;

  // Name
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::Coil_Heating_Gas_MultiStage, modelObject);

  // AvailabilityScheduleName
  if( auto schedule = modelObject.availabilitySchedule() ) {
    if( auto _schedule = translateAndMapModelObject(schedule.get()) ) {
      idfObject.setString(Coil_Heating_Gas_MultiStageFields::AvailabilityScheduleName,_schedule->name().get());
    }
  }

  // AirInletNodeName
  if( auto node = modelObject.inletModelObject() ) {
    idfObject.setString(Coil_Heating_Gas_MultiStageFields::AirInletNodeName,node->name().get());
  }  

  // AirOutletNodeName
  // TemperatureSetpointNodeName
  if( auto node = modelObject.outletModelObject() ) {
    idfObject.setString(Coil_Heating_Gas_MultiStageFields::AirOutletNodeName,node->name().get());
    idfObject.setString(Coil_Heating_Gas_MultiStageFields::TemperatureSetpointNodeName,node->name().get());
  }

  // PartLoadFractionCorrelationCurveName
  if( auto curve = modelObject.partLoadFractionCorrelationCurve() ) {
    if( auto _curve = translateAndMapModelObject(curve.get()) ) {
      idfObject.setString(Coil_Heating_Gas_MultiStageFields::PartLoadFractionCorrelationCurveName,_curve->name().get());
    }
  }

  // ParasiticGasLoad
  if( (value = modelObject.parasiticGasLoad()) ) {
    idfObject.setDouble(Coil_Heating_Gas_MultiStageFields::ParasiticGasLoad,value.get());
  }

  // NumberofStages
  {
    auto num = modelObject.stages().size();
    idfObject.setInt(Coil_Heating_Gas_MultiStageFields::NumberofStages,num);
  }

  for( auto stage: modelObject.stages() ) {
    auto eg = idfObject.pushExtensibleGroup();

    // Stage1GasBurnerEfficiency
    if( (value = stage.gasBurnerEfficiency()) ) {
      eg.setDouble(Coil_Heating_Gas_MultiStageExtensibleFields::StageGasBurnerEfficiency,value.get());
    }

    // Stage1NominalCapacity
    if( stage.isNominalCapacityAutosized() ) {
      eg.setString(Coil_Heating_Gas_MultiStageExtensibleFields::StageNominalCapacity,"AutoSize");
    } else if( (value = stage.nominalCapacity()) ) {
      eg.setDouble(Coil_Heating_Gas_MultiStageExtensibleFields::StageNominalCapacity,value.get());
    }

    // Stage1ParasiticElectricLoad
    if( (value = stage.parasiticElectricLoad()) ) {
      eg.setDouble(Coil_Heating_Gas_MultiStageExtensibleFields::StageParasiticElectricLoad,value.get());
    }
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateAirTerminalSingleDuctConstantVolumeFourPipeInduction( AirTerminalSingleDuctConstantVolumeFourPipeInduction & modelObject )
{
  OptionalString s;
  OptionalDouble d;
  OptionalModelObject temp;

  IdfObject _airDistributionUnit(openstudio::IddObjectType::ZoneHVAC_AirDistributionUnit);
  _airDistributionUnit.setName(modelObject.name().get() + " Air Distribution Unit");
  m_idfObjects.push_back(_airDistributionUnit);

  // Name
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::AirTerminal_SingleDuct_ConstantVolume_FourPipeInduction, modelObject);

  // Availability Schedule Name
  if( (temp = modelObject.availabilitySchedule()) )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(temp.get()) )
    {
      idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::AvailabilityScheduleName,_schedule->name().get());
    }
  }

  // Maximum Total Air Flow Rate
  if( (d = modelObject.maximumTotalAirFlowRate()) )
  {
    idfObject.setDouble(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::MaximumTotalAirFlowRate,d.get());
  }
  else if( modelObject.isMaximumTotalAirFlowRateAutosized() )
  {
    idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::MaximumTotalAirFlowRate,"Autosize");
  }

  // Induction Ratio
  if( (d = modelObject.inductionRatio()) )
  {
    idfObject.setDouble(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::InductionRatio,d.get());
  }

  // Supply Air Inlet Node Name
  if( auto node = modelObject.inletModelObject() ) {
    idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::SupplyAirInletNodeName,node->name().get());
  }

  // Induced Air Inlet Node Name
  if( auto node = modelObject.inducedAirInletNode() ) {
    idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::InducedAirInletNodeName,node->name().get());
  }

  // Air Outlet Node Name
  if( auto node = modelObject.outletModelObject() ) {
    idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::AirOutletNodeName,node->name().get());
  }

  // Hot Water Inlet Node Name
  // deprecated

  // Cold Water Inlet Node Name
  //deprecated

  // Heating Coil Object Type
  // Heating Coil Name
  boost::optional<IdfObject> _heatingCoil;
  {
    auto heatingCoil = modelObject.heatingCoil();
    if( (_heatingCoil = translateAndMapModelObject(heatingCoil)) ) {
      idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::HeatingCoilObjectType,_heatingCoil->iddObject().name());
      idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::HeatingCoilName,_heatingCoil->name().get());
    }
  }

  // Maximum Hot Water Flow Rate
  if( (d = modelObject.maximumHotWaterFlowRate()) )
  {
    idfObject.setDouble(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::MaximumHotWaterFlowRate,d.get());
  }
  else if( modelObject.isMaximumHotWaterFlowRateAutosized() )
  {
    idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::MaximumHotWaterFlowRate,"Autosize");
  }

  // Minimum Hot Water Flow Rate
  if( (d = modelObject.minimumHotWaterFlowRate()) )
  {
    idfObject.setDouble(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::MinimumHotWaterFlowRate,d.get());
  }

  // Heating Convergence Tolerance
  if( (d = modelObject.heatingConvergenceTolerance()) )
  {
    idfObject.setDouble(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::HeatingConvergenceTolerance,d.get());
  }

  // Cooling Coil Object Type
  // Cooling Coil Name
  boost::optional<IdfObject> _coolingCoil;
  if( auto coolingCoil = modelObject.coolingCoil() ) {
    if( (_coolingCoil = translateAndMapModelObject(coolingCoil.get())) ) {
      idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::CoolingCoilObjectType,_coolingCoil->iddObject().name());
      idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::CoolingCoilName,_coolingCoil->name().get());
    }
  }
  
  // Maximum Cold Water Flow Rate
  if( (d = modelObject.maximumColdWaterFlowRate()) )
  {
    idfObject.setDouble(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::MaximumColdWaterFlowRate,d.get());
  }
  else if( modelObject.isMaximumColdWaterFlowRateAutosized() )
  {
    idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::MaximumColdWaterFlowRate,"Autosize");
  }

  // Minimum Cold Water Flow Rate
  if( (d = modelObject.minimumColdWaterFlowRate()) )
  {
    idfObject.setDouble(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::MinimumColdWaterFlowRate,d.get());
  }

  // Cooling Convergence Tolerance
  if( (d = modelObject.coolingConvergenceTolerance()) )
  {
    idfObject.setDouble(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::CoolingConvergenceTolerance,d.get());
  }

  // Zone Mixer Name
  IdfObject _mixer(IddObjectType::AirLoopHVAC_ZoneMixer);
  _mixer.setName(modelObject.name().get() + " Mixer");
  m_idfObjects.push_back(_mixer);
  _mixer.clearExtensibleGroups();
  idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_FourPipeInductionFields::ZoneMixerName,_mixer.name().get());

  std::string baseName = modelObject.name().get();

  std::string heatingCoilInlet;
  std::string heatingCoilOutlet;
  std::string coolingCoilInlet;
  std::string coolingCoilOutlet;
  std::string mixerAirSystemInlet;
  std::string mixerInducedInlet;
  std::string mixerOutlet;

  if( auto inducedAirInletNode = modelObject.inducedAirInletNode() ) {
    heatingCoilInlet = inducedAirInletNode->name().get();
  }
  heatingCoilOutlet = baseName + " Heating Coil Outlet";

  if( _coolingCoil ) {
    coolingCoilInlet = heatingCoilOutlet;
    coolingCoilOutlet = baseName + " Cooling Coil Outlet";

    mixerInducedInlet = coolingCoilOutlet;
  } else {
    mixerInducedInlet = heatingCoilOutlet;
  }

  if( auto node = modelObject.inletModelObject() ) {
    mixerAirSystemInlet = node->name().get();
  }
  if( auto node = modelObject.outletModelObject() ) {
    mixerOutlet = node->name().get();
  }

  if( _heatingCoil && (_heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water) ) {
    _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName,heatingCoilInlet);
    _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName,heatingCoilOutlet);
  }

  if( _coolingCoil && (_coolingCoil->iddObject().type() == IddObjectType::Coil_Cooling_Water) ) {
    _coolingCoil->setString(Coil_Cooling_WaterFields::AirInletNodeName,coolingCoilInlet);
    _coolingCoil->setString(Coil_Cooling_WaterFields::AirOutletNodeName,coolingCoilOutlet);
  }

  _mixer.setString(AirLoopHVAC_ZoneMixerFields::OutletNodeName,mixerOutlet);
  IdfExtensibleGroup eg = _mixer.pushExtensibleGroup();
  eg.setString(AirLoopHVAC_ZoneMixerExtensibleFields::InletNodeName,mixerAirSystemInlet);
  eg = _mixer.pushExtensibleGroup();
  eg.setString(AirLoopHVAC_ZoneMixerExtensibleFields::InletNodeName,mixerInducedInlet);

  if( auto node = modelObject.outletModelObject() ) {
    _airDistributionUnit.setString(ZoneHVAC_AirDistributionUnitFields::AirDistributionUnitOutletNodeName,node->name().get());
  }
  _airDistributionUnit.setString(ZoneHVAC_AirDistributionUnitFields::AirTerminalObjectType,idfObject.iddObject().name());
  _airDistributionUnit.setString(ZoneHVAC_AirDistributionUnitFields::AirTerminalName,idfObject.name().get());

  return _airDistributionUnit;
}
boost::optional<IdfObject> ForwardTranslator::translateRefrigerationCondenserEvaporativeCooled(RefrigerationCondenserEvaporativeCooled & modelObject)
{
    OptionalModelObject temp;
    OptionalString optS;
    boost::optional<std::string> s;
    boost::optional<double> d;

// Name
    IdfObject object = createRegisterAndNameIdfObject(openstudio::IddObjectType::Refrigeration_Condenser_EvaporativeCooled, modelObject);

//Rated Effective Total Heat Rejection Rate
    d = modelObject.ratedEffectiveTotalHeatRejectionRate();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::RatedEffectiveTotalHeatRejectionRate,d.get());
    }

//Rated Subcooling Temperature Difference
    d = modelObject.ratedSubcoolingTemperatureDifference();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::RatedSubcoolingTemperatureDifference,d.get());
    }

//Fan Speed Control Type
    s = modelObject.fanSpeedControlType();
    if (s) {
        object.setString(Refrigeration_Condenser_EvaporativeCooledFields::FanSpeedControlType,s.get());
    }

//Rated Fan Power
    d = modelObject.ratedFanPower();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::RatedFanPower,d.get());
    }

//Minimum Fan Air Flow Ratio
    d = modelObject.minimumFanAirFlowRatio();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::MinimumFanAirFlowRatio,d.get());
    }

//Approach Temperature Constant Term
    d = modelObject.approachTemperatureConstantTerm();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::ApproachTemperatureConstantTerm,d.get());
    }

//Approach Temperature Coefficient 2
    d = modelObject.approachTemperatureCoefficient2();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::ApproachTemperatureCoefficient2,d.get());
    }

//Approach Temperature Coefficient 3
    d = modelObject.approachTemperatureCoefficient3();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::ApproachTemperatureCoefficient3,d.get());
    }

//Approach Temperature Coefficient 4
    d = modelObject.approachTemperatureCoefficient4();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::ApproachTemperatureCoefficient4,d.get());
    }

//Minimum Capacity Factor
    d = modelObject.minimumCapacityFactor();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::MinimumCapacityFactor,d.get());
    }

//Maximum Capacity Factor
    d = modelObject.maximumCapacityFactor();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::MaximumCapacityFactor,d.get());
    }

//Air Inlet Node Name
    object.setString(Refrigeration_Condenser_EvaporativeCooledFields::AirInletNodeName,"");

//Rated Air Flow Rate
    d = modelObject.ratedAirFlowRate();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::RatedAirFlowRate,d.get());
    }
    else if ( modelObject.isRatedAirFlowRateAutocalculated() )
    {
        object.setString(Refrigeration_Condenser_EvaporativeCooledFields::RatedAirFlowRate,"Autocalculate");
    }

//Basin Heater Capacity
    d = modelObject.basinHeaterCapacity();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::BasinHeaterCapacity,d.get());
    }

//Basin Heater Setpoint Temperature
    d = modelObject.basinHeaterSetpointTemperature();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::BasinHeaterSetpointTemperature,d.get());
    }

//Rated Water Pump Power
    d = modelObject.ratedWaterPumpPower();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::RatedWaterPumpPower,d.get());
    }
    else if ( modelObject.isRatedWaterPumpPowerAutocalculated() )
    {
        object.setString(Refrigeration_Condenser_EvaporativeCooledFields::RatedWaterPumpPower,"Autocalculate");
    }

//Evaporative Water Supply Tank Name
    object.setString(Refrigeration_Condenser_EvaporativeCooledFields::EvaporativeWaterSupplyTankName,"");

//Evaporative Condenser Availability Schedule Name
    boost::optional<Schedule> evaporativeCondenserAvailabilitySchedule = modelObject.evaporativeCondenserAvailabilitySchedule();

    if(evaporativeCondenserAvailabilitySchedule)
    {
        boost::optional<IdfObject> _evaporativeCondenserAvailabilitySchedule = translateAndMapModelObject(evaporativeCondenserAvailabilitySchedule.get());

        if( _evaporativeCondenserAvailabilitySchedule && _evaporativeCondenserAvailabilitySchedule->name() )
        {
            object.setString(Refrigeration_Condenser_EvaporativeCooledFields::EvaporativeCondenserAvailabilityScheduleName,_evaporativeCondenserAvailabilitySchedule->name().get());
        }
    }

//End-Use Subcategory
    s = modelObject.endUseSubcategory();
    if (s) {
        object.setString(Refrigeration_Condenser_EvaporativeCooledFields::EndUseSubcategory,s.get());
    }

//Condenser Refrigerant Operating Charge Inventory
    d = modelObject.condenserRefrigerantOperatingChargeInventory();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::CondenserRefrigerantOperatingChargeInventory,d.get());
    }

//Condensate Receiver Refrigerant Inventory
    d = modelObject.condensateReceiverRefrigerantInventory();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::CondensateReceiverRefrigerantInventory,d.get());
    }

//Condensate Piping Refrigerant Inventory
    d = modelObject.condensatePipingRefrigerantInventory();
    if (d) {
        object.setDouble(Refrigeration_Condenser_EvaporativeCooledFields::CondensatePipingRefrigerantInventory,d.get());
    }

    return object;

}
boost::optional<IdfObject> ForwardTranslator::translateCoilCoolingWaterToAirHeatPumpEquationFit( CoilCoolingWaterToAirHeatPumpEquationFit & modelObject )
{
  //setup boost optionals to use to store get method returns
  boost::optional<std::string> s;
  boost::optional<double> value;
  boost::optional<Node> node;
  
  // Make sure the modelObject gets ut into the map, and the new idfObject gets put into the final file.
  // Also sets the idfObjects name

  IdfObject idfObject = createRegisterAndNameIdfObject(IddObjectType::Coil_Cooling_WaterToAirHeatPump_EquationFit,modelObject);
  
  // Object Name
  //std::string baseName = idfObject.name().get();

  //  A3 ,Field Water Inlet Node Name
  
 if( boost::optional<ModelObject> mo = modelObject.waterInletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::WaterInletNodeName,node->name().get());
    }
  }
  
  // A4, Field Water Outlet Node Name
  
  if( boost::optional<ModelObject> mo = modelObject.waterOutletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::WaterOutletNodeName,node->name().get());
    }
  }
  
  // A5, Field Air Inlet Node Name
  
  if( boost::optional<ModelObject> mo = modelObject.airInletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::AirInletNodeName,node->name().get());
    }
  }

  // A6 , \field Air Outlet Node Name
  
  if( boost::optional<ModelObject> mo = modelObject.airOutletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::AirOutletNodeName,node->name().get());
    }
  }

  // N1 Field Rated Air Flow Rate
  
  value = modelObject.ratedAirFlowRate();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::RatedAirFlowRate,*value);
  }
  
  else
  {
    idfObject.setString(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::RatedAirFlowRate,"Autosize");
  }
  
  //  N2 Rated Water Flow Rate
  
  value = modelObject.ratedWaterFlowRate();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::RatedWaterFlowRate,*value);
  }
  
  else
  {
    idfObject.setString(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::RatedWaterFlowRate,"Autosize");
  }
  
  // N3,  Field Rated Total Cooling Capacity
  
  value = modelObject.ratedTotalCoolingCapacity();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::GrossRatedTotalCoolingCapacity,*value);
  }
  
  else
  {
    idfObject.setString(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::GrossRatedTotalCoolingCapacity,"Autosize");
  }
  
  // N4,  Field Rated Sensible Cooling Capacity
  
  value = modelObject.ratedSensibleCoolingCapacity();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::GrossRatedSensibleCoolingCapacity,*value);
  }
  
  else
  {
    idfObject.setString(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::GrossRatedSensibleCoolingCapacity,"Autosize");
  }
  
  //   N5, Field Rated Cooling Coefficient of Performance

  value = modelObject.ratedCoolingCoefficientofPerformance();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::GrossRatedCoolingCOP,*value);
  }
  
  // N6,  Field Total Cooling Capacity Coefficient 1

  value = modelObject.totalCoolingCapacityCoefficient1();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::TotalCoolingCapacityCoefficient1,*value);
  }
  
  // N7,  Field Total Cooling Capacity Coefficient 2

  value = modelObject.totalCoolingCapacityCoefficient2();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::TotalCoolingCapacityCoefficient2,*value);
  }
  
  // N8,  Field Total Cooling Capacity Coefficient 3

  value = modelObject.totalCoolingCapacityCoefficient3();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::TotalCoolingCapacityCoefficient3,*value);
  }
  
  // N9,  Field Total Cooling Capacity Coefficient 4

  value = modelObject.totalCoolingCapacityCoefficient4();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::TotalCoolingCapacityCoefficient4,*value);
  }
  
  // N10,  Field Total Cooling Capacity Coefficient 5

  value = modelObject.totalCoolingCapacityCoefficient5();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::TotalCoolingCapacityCoefficient5,*value);
  }
  
  // N11,  Sensible Cooling Capacity Coefficient 1

  value = modelObject.sensibleCoolingCapacityCoefficient1();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::SensibleCoolingCapacityCoefficient1,*value);
  }
  
  // N12,  Sensible Cooling Capacity Coefficient 2

  value = modelObject.sensibleCoolingCapacityCoefficient2();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::SensibleCoolingCapacityCoefficient2,*value);
  }
  
   // N13,  Sensible Cooling Capacity Coefficient 3

  value = modelObject.sensibleCoolingCapacityCoefficient3();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::SensibleCoolingCapacityCoefficient3,*value);
  }
  
   // N14,  Sensible Cooling Capacity Coefficient 4

  value = modelObject.sensibleCoolingCapacityCoefficient4();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::SensibleCoolingCapacityCoefficient4,*value);
  }
  
   // N15,  Sensible Cooling Capacity Coefficient 5

  value = modelObject.sensibleCoolingCapacityCoefficient5();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::SensibleCoolingCapacityCoefficient5,*value);
  }
  
   // N16,  Sensible Cooling Capacity Coefficient 6

  value = modelObject.sensibleCoolingCapacityCoefficient6();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::SensibleCoolingCapacityCoefficient6,*value);
  }
  
  // N17,  Sensible Power Consumption Coefficient 1

  value = modelObject.coolingPowerConsumptionCoefficient1();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::CoolingPowerConsumptionCoefficient1,*value);
  }
  
  // N18,  Sensible Power Consumption Coefficient 2

  value = modelObject.coolingPowerConsumptionCoefficient2();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::CoolingPowerConsumptionCoefficient2,*value);
  }
  
  // N19,  Sensible Power Consumption Coefficient 3

  value = modelObject.coolingPowerConsumptionCoefficient3();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::CoolingPowerConsumptionCoefficient3,*value);
  }
  
  // N20,  Sensible Power Consumption Coefficient 4

  value = modelObject.coolingPowerConsumptionCoefficient4();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::CoolingPowerConsumptionCoefficient4,*value);
  }
  
  // N21,  Sensible Power Consumption Coefficient 5

  value = modelObject.coolingPowerConsumptionCoefficient5();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::CoolingPowerConsumptionCoefficient5,*value);
  }
  
  // N22, Field Nominal Time for Condensate Removal to Begin
  
  value = modelObject.nominalTimeforCondensateRemovaltoBegin();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::NominalTimeforCondensateRemovaltoBegin,*value);
  }
  
  //  N23, Field Ratio of Initial Moisture Evaporation Rate and Steady State Latent
  
  value = modelObject.ratioofInitialMoistureEvaporationRateandSteadyStateLatentCapacity();
  
  if( value )
  {
    idfObject.setDouble(Coil_Cooling_WaterToAirHeatPump_EquationFitFields::RatioofInitialMoistureEvaporationRateandSteadyStateLatentCapacity,*value);
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateRefrigerationWalkIn( RefrigerationWalkIn & modelObject )
{
  OptionalModelObject temp;
  boost::optional<std::string> s;
  boost::optional<double> d;

// Name
  IdfObject refrigerationWalkIn = createRegisterAndNameIdfObject(openstudio::IddObjectType::Refrigeration_WalkIn,
                                                          modelObject);

//AvailabilityScheduleName
  boost::optional<Schedule> availabilitySchedule = modelObject.availabilitySchedule();

  if( availabilitySchedule )
  {
    boost::optional<IdfObject> _availabilitySchedule = translateAndMapModelObject(availabilitySchedule.get());

    if( _availabilitySchedule && _availabilitySchedule->name() )
    {
      refrigerationWalkIn.setString(Refrigeration_WalkInFields::AvailabilityScheduleName,_availabilitySchedule->name().get());
    }
  }

//RatedCoilCoolingCapacity
  d = modelObject.ratedCoilCoolingCapacity();
  if (d) {
    refrigerationWalkIn.setDouble(Refrigeration_WalkInFields::RatedCoilCoolingCapacity,d.get());
  }

//OperatingTemperature
  d = modelObject.operatingTemperature();
  if (d) {
    refrigerationWalkIn.setDouble(Refrigeration_WalkInFields::OperatingTemperature,d.get());
  }

//RatedCoolingSourceTemperature
  d = modelObject.ratedCoolingSourceTemperature();
  if (d) {
    refrigerationWalkIn.setDouble(Refrigeration_WalkInFields::RatedCoolingSourceTemperature,d.get());
  }

//RatedTotalHeatingPower
  d = modelObject.ratedTotalHeatingPower();
  if (d) {
    refrigerationWalkIn.setDouble(Refrigeration_WalkInFields::RatedTotalHeatingPower,d.get());
  }

//HeatingPowerScheduleName
  boost::optional<Schedule> heatingPowerSchedule = modelObject.heatingPowerSchedule();

  if( heatingPowerSchedule )
  {
    boost::optional<IdfObject> _heatingPowerSchedule = translateAndMapModelObject(heatingPowerSchedule.get());

    if( _heatingPowerSchedule && _heatingPowerSchedule->name() )
    {
      refrigerationWalkIn.setString(Refrigeration_WalkInFields::HeatingPowerScheduleName,_heatingPowerSchedule->name().get());
    }
  }

//RatedCoolingCoilFanPower
  d = modelObject.ratedCoolingCoilFanPower();
  if (d) {
    refrigerationWalkIn.setDouble(Refrigeration_WalkInFields::RatedCoolingCoilFanPower,d.get());
  }

//RatedCirculationFanPower
  d = modelObject.ratedCirculationFanPower();
  if (d) {
    refrigerationWalkIn.setDouble(Refrigeration_WalkInFields::RatedCirculationFanPower,d.get());
  }

//RatedTotalLightingPower
  d = modelObject.ratedTotalLightingPower();
  if (d) {
    refrigerationWalkIn.setDouble(Refrigeration_WalkInFields::RatedTotalLightingPower,d.get());
  }

//LightingScheduleName
  boost::optional<Schedule> lightingSchedule = modelObject.lightingSchedule();

  if( lightingSchedule )
  {
    boost::optional<IdfObject> _lightingSchedule = translateAndMapModelObject(lightingSchedule.get());

    if( _lightingSchedule && _lightingSchedule->name() )
    {
      refrigerationWalkIn.setString(Refrigeration_WalkInFields::LightingScheduleName,_lightingSchedule->name().get());
    }
  }

//DefrostType
  s = modelObject.defrostType();
  if (s) {
    refrigerationWalkIn.setString(Refrigeration_WalkInFields::DefrostType,s.get());
  }

//DefrostControlType
  s = modelObject.defrostControlType();
  if (s) {
    refrigerationWalkIn.setString(Refrigeration_WalkInFields::DefrostControlType,s.get());
  }

//DefrostCycleParameters
  boost::optional<int> durationofDefrostCycle = modelObject.durationofDefrostCycle();
  boost::optional<int> dripDownTime = modelObject.dripDownTime();
  std::vector<openstudio::Time> defrostStartTimes = modelObject.getImpl<model::detail::RefrigerationWalkIn_Impl>()->defrostStartTimes();

  if( durationofDefrostCycle && dripDownTime && !defrostStartTimes.empty() ) {
    int defrostTimeHour = *durationofDefrostCycle / 60;
    int defrostTimeMin = *durationofDefrostCycle % 60;
    int dripDownTimeHour = *dripDownTime / 60;
    int dripDownTimeMin = *dripDownTime % 60;

    std::vector< std::pair<openstudio::Time, double> > defrostDefaultDay;
    std::vector< std::pair<openstudio::Time, double> > dripDownDefaultDay;
    for( auto _defrostStartTime = defrostStartTimes.begin();
       _defrostStartTime != defrostStartTimes.end();
       ++_defrostStartTime )
    {
      defrostDefaultDay.push_back(std::make_pair(*_defrostStartTime, 0)); // defrost off
      openstudio::Time defrostEndTime(0, _defrostStartTime->hours() + defrostTimeHour, _defrostStartTime->minutes() + defrostTimeMin);
      defrostDefaultDay.push_back(std::make_pair(defrostEndTime, 1)); // defrost on

      dripDownDefaultDay.push_back(std::make_pair(*_defrostStartTime, 0)); // drip down off
      openstudio::Time dripDownEndTime(0, _defrostStartTime->hours() + defrostTimeHour + dripDownTimeHour, _defrostStartTime->minutes() + defrostTimeMin + dripDownTimeMin);
      dripDownDefaultDay.push_back(std::make_pair(dripDownEndTime, 1)); // drip down on
    }

    if( (defrostStartTimes.front().hours() != 0 && defrostStartTimes.front().minutes() != 0) || defrostStartTimes.back().hours() < 24) {
      openstudio::Time defrostDayEnd(0, 24, 0);
      defrostDefaultDay.push_back(std::make_pair(defrostDayEnd, 0)); // defrost off
      dripDownDefaultDay.push_back(std::make_pair(defrostDayEnd, 0)); // drip down off
    }

    //DefrostScheduleName
    std::string defrostName(modelObject.name().get() + " Defrost Schedule");
    boost::optional<IdfObject> defrostSchedule = this->createSimpleSchedule(defrostName, defrostDefaultDay);
    if( defrostSchedule ) {
      refrigerationWalkIn.setString(Refrigeration_WalkInFields::DefrostScheduleName, defrostName);
    }

    //DefrostDripDownScheduleName
    std::string dripDownName(modelObject.name().get() + " Defrost Drip Down Schedule");
    boost::optional<IdfObject> defrostDripDownSchedule = this->createSimpleSchedule(dripDownName, dripDownDefaultDay);
    if( defrostDripDownSchedule ) {
      refrigerationWalkIn.setString(Refrigeration_WalkInFields::DefrostDripDownScheduleName, dripDownName);
    }
  } else {
  //DefrostScheduleName
    boost::optional<Schedule> defrostSchedule = modelObject.defrostSchedule();

    if( defrostSchedule )
    {
      boost::optional<IdfObject> _defrostSchedule = translateAndMapModelObject(defrostSchedule.get());

      if( _defrostSchedule && _defrostSchedule->name() )
      {
        refrigerationWalkIn.setString(Refrigeration_WalkInFields::DefrostScheduleName,_defrostSchedule->name().get());
      }
    }

  //DefrostDripDownScheduleName
    boost::optional<Schedule> defrostDripDownSchedule = modelObject.defrostDripDownSchedule();

    if( defrostDripDownSchedule )
    {
      boost::optional<IdfObject> _defrostDripDownSchedule = translateAndMapModelObject(defrostDripDownSchedule.get());

      if( _defrostDripDownSchedule && _defrostDripDownSchedule->name() )
      {
        refrigerationWalkIn.setString(Refrigeration_WalkInFields::DefrostDripDownScheduleName,_defrostDripDownSchedule->name().get());
      }
    }
  }

//DefrostPower
  d = modelObject.defrostPower();
  if (d) {
    refrigerationWalkIn.setDouble(Refrigeration_WalkInFields::DefrostPower,d.get());
  }

//TemperatureTerminationDefrostFractiontoIce
  d = modelObject.temperatureTerminationDefrostFractiontoIce();
  if (d) {
    refrigerationWalkIn.setDouble(Refrigeration_WalkInFields::TemperatureTerminationDefrostFractiontoIce,d.get());
  }

//RestockingScheduleName
  boost::optional<Schedule> restockingSchedule = modelObject.restockingSchedule();

  if( restockingSchedule )
  {
    boost::optional<IdfObject> _restockingSchedule = translateAndMapModelObject(restockingSchedule.get());

    if( _restockingSchedule && _restockingSchedule->name() )
    {
      refrigerationWalkIn.setString(Refrigeration_WalkInFields::RestockingScheduleName,_restockingSchedule->name().get());
    }
  }

//AverageRefrigerantChargeInventory
  d = modelObject.averageRefrigerantChargeInventory();
  if (d) {
    refrigerationWalkIn.setDouble(Refrigeration_WalkInFields::AverageRefrigerantChargeInventory,d.get());
  }

//InsulatedFloorSurfaceArea
  d = modelObject.insulatedFloorSurfaceArea();
  if (d) {
    refrigerationWalkIn.setDouble(Refrigeration_WalkInFields::InsulatedFloorSurfaceArea,d.get());
  }

//InsulatedFloorUValue
  d = modelObject.insulatedFloorUValue();
  if (d) {
    refrigerationWalkIn.setDouble(Refrigeration_WalkInFields::InsulatedFloorUValue,d.get());
  }

//ZoneBoundaries
  std::vector<RefrigerationWalkInZoneBoundary> zoneBoundaries = modelObject.zoneBoundaries();

  if( !zoneBoundaries.empty() )
  {
    for( const auto & _zoneBoundary : zoneBoundaries )
    {
      IdfExtensibleGroup eg = refrigerationWalkIn.pushExtensibleGroup();

      //ZoneName
        boost::optional<ThermalZone> thermalZone = _zoneBoundary.thermalZone();

        if( thermalZone )
        {
          boost::optional<IdfObject> _thermalZone = translateAndMapModelObject(thermalZone.get());

          if( _thermalZone && _thermalZone->name() )
          {
            eg.setString(Refrigeration_WalkInExtensibleFields::ZoneName,_thermalZone->name().get());
          }
        }

      //TotalInsulatedSurfaceAreaFacingZone
        d = _zoneBoundary.totalInsulatedSurfaceAreaFacingZone();
        if (d) {
          eg.setDouble(Refrigeration_WalkInExtensibleFields::TotalInsulatedSurfaceAreaFacingZone,d.get());
        }

      //InsulatedSurfaceUValueFacingZone
        d = _zoneBoundary.insulatedSurfaceUValueFacingZone();
        if (d) {
          eg.setDouble(Refrigeration_WalkInExtensibleFields::InsulatedSurfaceUValueFacingZone,d.get());
        }

      //AreaofGlassReachInDoorsFacingZone
        d = _zoneBoundary.areaofGlassReachInDoorsFacingZone();
        if (d) {
          eg.setDouble(Refrigeration_WalkInExtensibleFields::AreaofGlassReachInDoorsFacingZone,d.get());
        }

      //HeightofGlassReachInDoorsFacingZone
        d = _zoneBoundary.heightofGlassReachInDoorsFacingZone();
        if (d) {
          eg.setDouble(Refrigeration_WalkInExtensibleFields::HeightofGlassReachInDoorsFacingZone,d.get());
        }

      //GlassReachInDoorUValueFacingZone
        d = _zoneBoundary.glassReachInDoorUValueFacingZone();
        if (d) {
          eg.setDouble(Refrigeration_WalkInExtensibleFields::GlassReachInDoorUValueFacingZone,d.get());
        }

      //GlassReachInDoorOpeningScheduleNameFacingZone
        boost::optional<Schedule> glassReachInDoorOpeningScheduleFacingZone = _zoneBoundary.glassReachInDoorOpeningScheduleFacingZone();

        if( glassReachInDoorOpeningScheduleFacingZone )
        {
          boost::optional<IdfObject> _glassReachInDoorOpeningScheduleFacingZone = translateAndMapModelObject(glassReachInDoorOpeningScheduleFacingZone.get());

          if( _glassReachInDoorOpeningScheduleFacingZone && _glassReachInDoorOpeningScheduleFacingZone->name() )
          {
            eg.setString(Refrigeration_WalkInExtensibleFields::GlassReachInDoorOpeningScheduleNameFacingZone,_glassReachInDoorOpeningScheduleFacingZone->name().get());
          }
        }

      //AreaofStockingDoorsFacingZone
        d = _zoneBoundary.areaofStockingDoorsFacingZone();
        if (d) {
          eg.setDouble(Refrigeration_WalkInExtensibleFields::AreaofStockingDoorsFacingZone,d.get());
        }

      //HeightofStockingDoorsFacingZone
        d = _zoneBoundary.heightofStockingDoorsFacingZone();
        if (d) {
          eg.setDouble(Refrigeration_WalkInExtensibleFields::HeightofStockingDoorsFacingZone,d.get());
        }

      //StockingDoorUValueFacingZone
        d = _zoneBoundary.stockingDoorUValueFacingZone();
        if (d) {
          eg.setDouble(Refrigeration_WalkInExtensibleFields::StockingDoorUValueFacingZone,d.get());
        }

      //StockingDoorOpeningScheduleNameFacingZone
        boost::optional<Schedule> stockingDoorOpeningScheduleFacingZone = _zoneBoundary.stockingDoorOpeningScheduleFacingZone();

        if( stockingDoorOpeningScheduleFacingZone )
        {
          boost::optional<IdfObject> _stockingDoorOpeningScheduleFacingZone = translateAndMapModelObject(stockingDoorOpeningScheduleFacingZone.get());

          if( _stockingDoorOpeningScheduleFacingZone && _stockingDoorOpeningScheduleFacingZone->name() )
          {
            eg.setString(Refrigeration_WalkInExtensibleFields::StockingDoorOpeningScheduleNameFacingZone,_stockingDoorOpeningScheduleFacingZone->name().get());
          }
        }

      //StockingDoorOpeningProtectionTypeFacingZone
        s = _zoneBoundary.stockingDoorOpeningProtectionTypeFacingZone();
        if (s) {
          eg.setString(Refrigeration_WalkInExtensibleFields::StockingDoorOpeningProtectionTypeFacingZone,s.get());
        }
    }
  }

  return refrigerationWalkIn;

}
boost::optional<IdfObject> ForwardTranslator::translateCoilHeatingWaterToAirHeatPumpEquationFit(CoilHeatingWaterToAirHeatPumpEquationFit & modelObject)
{
  //setup boost optionals to use to store get method returns
  boost::optional<std::string> s;
  boost::optional<double> value;
  boost::optional<Node> node;
  
  // Make sure the modelObject gets put into the map, and the new idfObject gets put into the final file.
  // Also sets the idfObjects name

  IdfObject idfObject = createRegisterAndNameIdfObject(IddObjectType::Coil_Heating_WaterToAirHeatPump_EquationFit,modelObject);
  
  // Object Name
  //std::string baseName = idfObject.name().get();

  // Water Inlet Node Name  
  if( boost::optional<ModelObject> mo = modelObject.waterInletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(Coil_Heating_WaterToAirHeatPump_EquationFitFields::WaterInletNodeName,node->name().get());
    }
  }
  
  // Water Outlet Node Name
  if( boost::optional<ModelObject> mo = modelObject.waterOutletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(Coil_Heating_WaterToAirHeatPump_EquationFitFields::WaterOutletNodeName,node->name().get());
    }
  }
  
  //Air Inlet Node Name
  if( boost::optional<ModelObject> mo = modelObject.airInletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(Coil_Heating_WaterToAirHeatPump_EquationFitFields::AirInletNodeName,node->name().get());
    }
  }

  //Air Outlet Node Name
  if( boost::optional<ModelObject> mo = modelObject.airOutletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(Coil_Heating_WaterToAirHeatPump_EquationFitFields::AirOutletNodeName,node->name().get());
    }
  }

  //Rated Air Flow Rate
  if( modelObject.isRatedAirFlowRateAutosized())
  {
    idfObject.setString(Coil_Heating_WaterToAirHeatPump_EquationFitFields::RatedAirFlowRate,"Autosize");
  }
  else if((value = modelObject.ratedAirFlowRate()))
  {
    idfObject.setDouble(Coil_Heating_WaterToAirHeatPump_EquationFitFields::RatedAirFlowRate,value.get());
  }
  
  //Rated Water Flow Rate
  if( modelObject.isRatedWaterFlowRateAutosized())
  {
    idfObject.setString(Coil_Heating_WaterToAirHeatPump_EquationFitFields::RatedWaterFlowRate,"Autosize");
  }
  else if((value = modelObject.ratedAirFlowRate()))
  {
    idfObject.setDouble(Coil_Heating_WaterToAirHeatPump_EquationFitFields::RatedWaterFlowRate,value.get());
  }  

  
  // Rated Heating Capacity
  if( modelObject.isRatedHeatingCapacityAutosized())
  {
    idfObject.setString(Coil_Heating_WaterToAirHeatPump_EquationFitFields::GrossRatedHeatingCapacity,"Autosize");
  }
  else if((value = modelObject.ratedHeatingCapacity()))
  {
    idfObject.setDouble(Coil_Heating_WaterToAirHeatPump_EquationFitFields::GrossRatedHeatingCapacity,value.get());
  }  

  // Heating Coefficient of Performance
  if((value = modelObject.ratedHeatingCoefficientofPerformance()))
  {
    idfObject.setDouble(Coil_Heating_WaterToAirHeatPump_EquationFitFields::GrossRatedHeatingCOP,value.get());
  }
  
  //Heating Capacity Coefficient 1
  if((value = modelObject.heatingCapacityCoefficient1()))
  {
    idfObject.setDouble(Coil_Heating_WaterToAirHeatPump_EquationFitFields::HeatingCapacityCoefficient1,value.get());
  }
  
  //Heating Capacity Coefficient 2
  if((value = modelObject.heatingCapacityCoefficient2()))
  {
    idfObject.setDouble(Coil_Heating_WaterToAirHeatPump_EquationFitFields::HeatingCapacityCoefficient2,value.get());
  }
  
  //Heating Capacity Coefficient 3
  if((value = modelObject.heatingCapacityCoefficient3()))
  {
    idfObject.setDouble(Coil_Heating_WaterToAirHeatPump_EquationFitFields::HeatingCapacityCoefficient3,value.get());
  }

  //Heating Capacity Coefficient 4
  if((value = modelObject.heatingCapacityCoefficient4()))
  {
    idfObject.setDouble(Coil_Heating_WaterToAirHeatPump_EquationFitFields::HeatingCapacityCoefficient4,value.get());
  }
  
  //Heating Capacity Coefficient 5
  if((value = modelObject.heatingCapacityCoefficient5()))
  {
    idfObject.setDouble(Coil_Heating_WaterToAirHeatPump_EquationFitFields::HeatingCapacityCoefficient5,value.get());
  }

  //Heating Power Consumption Coefficient 1
  if((value = modelObject.heatingPowerConsumptionCoefficient1()))
  {
    idfObject.setDouble(Coil_Heating_WaterToAirHeatPump_EquationFitFields::HeatingPowerConsumptionCoefficient1,value.get());
  }

  //Heating Power Consumption Coefficient 2
  if((value = modelObject.heatingPowerConsumptionCoefficient2()))
  {
    idfObject.setDouble(Coil_Heating_WaterToAirHeatPump_EquationFitFields::HeatingPowerConsumptionCoefficient2,value.get());
  }

  //Heating Power Consumption Coefficient 3
  if((value = modelObject.heatingPowerConsumptionCoefficient3()))
  {
    idfObject.setDouble(Coil_Heating_WaterToAirHeatPump_EquationFitFields::HeatingPowerConsumptionCoefficient3,value.get());
  }

  //Heating Power Consumption Coefficient 4
  if((value = modelObject.heatingPowerConsumptionCoefficient4()))
  {
    idfObject.setDouble(Coil_Heating_WaterToAirHeatPump_EquationFitFields::HeatingPowerConsumptionCoefficient4,value.get());
  }

  //Heating Power Consumption Coefficient 5
  if((value = modelObject.heatingPowerConsumptionCoefficient5()))
  {
    idfObject.setDouble(Coil_Heating_WaterToAirHeatPump_EquationFitFields::HeatingPowerConsumptionCoefficient5,value.get());
  }
 
  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateZoneHVACBaseboardConvectiveWater(
    ZoneHVACBaseboardConvectiveWater & modelObject )
{
  // Makes sure the modelObject gets put in the map, and that the new idfObject gets put in 
  // the final file. Also set's the idfObject's name.
  IdfObject idfObject = createRegisterAndNameIdfObject(IddObjectType::ZoneHVAC_Baseboard_Convective_Water,modelObject);

  boost::optional<std::string> s;
  boost::optional<double> value;
  boost::optional<ModelObject> temp;
  //get the heating coil as a straight component, cast it to optional HT coil, if cast is successful, 
  //get the object of class CoilHeatingWaterBaseboard
  StraightComponent coilStraight = modelObject.heatingCoil();
  boost::optional<CoilHeatingWaterBaseboard>  coilOptionalHeatBBConvWater = coilStraight.optionalCast<CoilHeatingWaterBaseboard>();
  
  // AvailabilityScheduleName
  Schedule availabilitySchedule = modelObject.availabilitySchedule();
  translateAndMapModelObject(availabilitySchedule);
  idfObject.setString(ZoneHVAC_Baseboard_Convective_WaterFields::AvailabilityScheduleName,
                      availabilitySchedule.name().get() );

  if (coilOptionalHeatBBConvWater){
    CoilHeatingWaterBaseboard coilHeatBBConvWater = *coilOptionalHeatBBConvWater;

    // Inlet Node Name 
    temp = coilHeatBBConvWater.inletModelObject();
    if(temp)
    {
      s = temp->name();
      if(s)
      {
        idfObject.setString(openstudio::ZoneHVAC_Baseboard_Convective_WaterFields::InletNodeName,*s);
      }
    }

    // Outlet Node Name 
    temp = coilHeatBBConvWater.outletModelObject();
    if(temp)
    {
      s = temp->name();
      if(s)
      {
        idfObject.setString(openstudio::ZoneHVAC_Baseboard_Convective_WaterFields::OutletNodeName,*s);
      }
    }

    // UFactorTimesAreaValue
    if(coilHeatBBConvWater.isUFactorTimesAreaValueAutosized())
    {
      idfObject.setString(ZoneHVAC_Baseboard_Convective_WaterFields::UFactorTimesAreaValue,"Autosize");
    }
    else if( value = coilHeatBBConvWater.uFactorTimesAreaValue() )
    {
      idfObject.setDouble(ZoneHVAC_Baseboard_Convective_WaterFields::UFactorTimesAreaValue,value.get());
    }

   // MaximumWaterFlowRate

    if(coilHeatBBConvWater.isMaximumWaterFlowRateAutosized() )
    {
      idfObject.setString(ZoneHVAC_Baseboard_Convective_WaterFields::MaximumWaterFlowRate,"Autosize");
    }
    else if( value = coilHeatBBConvWater.maximumWaterFlowRate() )
    {
      idfObject.setDouble(ZoneHVAC_Baseboard_Convective_WaterFields::MaximumWaterFlowRate,value.get());
    }

   // Convergence Tolerance

    if( coilHeatBBConvWater.isConvergenceToleranceDefaulted())
    {
      idfObject.setDouble(ZoneHVAC_Baseboard_Convective_WaterFields::ConvergenceTolerance,0.001);
    }
    else if( value = coilHeatBBConvWater.convergenceTolerance())
    {
      idfObject.setDouble(ZoneHVAC_Baseboard_Convective_WaterFields::ConvergenceTolerance,value.get());
    }
  }
 return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateZoneHVACBaseboardRadiantConvectiveElectric(ZoneHVACBaseboardRadiantConvectiveElectric& modelObject)
{
  boost::optional<std::string> s;
  boost::optional<double> value;
  boost::optional<ModelObject> temp;

  // Name
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::ZoneHVAC_Baseboard_RadiantConvective_Electric, modelObject);

  // AvailabilityScheduleName
  {
    auto schedule = modelObject.availabilitySchedule();
    if( auto _schedule = translateAndMapModelObject(schedule) ) {
      idfObject.setString(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::AvailabilityScheduleName,_schedule->name().get());
    }
  }

  // HeatingDesignCapacityMethod
  if( (s = modelObject.heatingDesignCapacityMethod()) ) {
    idfObject.setString(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::HeatingDesignCapacityMethod,s.get());
  }

  // HeatingDesignCapacity
  if( modelObject.isHeatingDesignCapacityAutosized() ) {
    idfObject.setString(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::HeatingDesignCapacity,"AutoSize");
  } else if( (value = modelObject.heatingDesignCapacity()) ) {
    idfObject.setDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::HeatingDesignCapacity,value.get());
  }

  // HeatingDesignCapacityPerFloorArea
  if( (value = modelObject.heatingDesignCapacityPerFloorArea()) ) {
    idfObject.setDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::HeatingDesignCapacityPerFloorArea,value.get());
  }

  // FractionofAutosizedHeatingDesignCapacity
  if( (value = modelObject.fractionofAutosizedHeatingDesignCapacity()) ) {
    idfObject.setDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::FractionofAutosizedHeatingDesignCapacity,value.get());
  }

  // Efficiency
  if( (value = modelObject.efficiency()) ) {
    idfObject.setDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::Efficiency,value.get());
  }

  // FractionRadiant
  if( (value = modelObject.fractionRadiant()) ) {
    idfObject.setDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::FractionRadiant,value.get());
  }

  // FractionofRadiantEnergyIncidentonPeople
  double fractionofRadiantEnergyIncidentonPeople = modelObject.fractionofRadiantEnergyIncidentonPeople();
  {
    idfObject.setDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::FractionofRadiantEnergyIncidentonPeople,fractionofRadiantEnergyIncidentonPeople);
  }

  //get rid of any existing surface (just to be safe)
  idfObject.clearExtensibleGroups();  
 
  //aggregator for total area; will be used to create weighted area
  double totalAreaOfWallSurfaces = 0;
  double totalAreaOfCeilingSurfaces = 0;
  double totalAreaOfFloorSurfaces = 0;

  //loop through all surfaces, adding up their area
  auto const& surfaces = modelObject.getImpl<model::detail::ZoneHVACBaseboardRadiantConvectiveElectric_Impl>()->surfaces();

  for ( auto const& surface : surfaces ) {
    if( istringEqual(surface.surfaceType(),"Floor") ) {
      totalAreaOfFloorSurfaces += surface.grossArea();
    } else if( istringEqual(surface.surfaceType(),"RoofCeiling") ) {
      totalAreaOfCeilingSurfaces += surface.grossArea();
    } else {
      totalAreaOfWallSurfaces += surface.grossArea();
    }
  }

  // Assume that 5% of what is not on people is on the floor
  double fractionOnFloor = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.05;
  // Assume that 55% of what is not on people is on the walls
  double fractionOnWall = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.55;
  // Assume that 40% of what is not on people is on the ceiling
  double fractionOnCeiling = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.40;
  //loop through all the surfaces, adding them and their flow fractions (weighted per-area)
  for ( auto const& surface : surfaces ) {
    IdfExtensibleGroup group = idfObject.pushExtensibleGroup();
    group.setString(ZoneHVAC_Baseboard_RadiantConvective_ElectricExtensibleFields::SurfaceName, surface.name().get());        
    if( istringEqual(surface.surfaceType(),"Floor") ) {
      group.setDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricExtensibleFields::FractionofRadiantEnergytoSurface, (surface.grossArea()/totalAreaOfFloorSurfaces * fractionOnFloor) );     
    } else if( istringEqual(surface.surfaceType(),"RoofCeiling") ) {
      group.setDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricExtensibleFields::FractionofRadiantEnergytoSurface, (surface.grossArea()/totalAreaOfCeilingSurfaces * fractionOnCeiling) );     
    } else {
      group.setDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricExtensibleFields::FractionofRadiantEnergytoSurface, (surface.grossArea()/totalAreaOfWallSurfaces * fractionOnWall) );     
    }
  }

  return idfObject;
}