boost::optional<IdfObject> ForwardTranslator::translateCurveDoubleExponentialDecay( 
    CurveDoubleExponentialDecay& modelObject)
{
  IdfObject idfObject(IddObjectType::Curve_DoubleExponentialDecay);

  m_idfObjects.push_back(idfObject);

  OptionalString s;
  OptionalDouble d;

  if ((s = modelObject.name())) {
    idfObject.setName(*s);
  }

  idfObject.setDouble(Curve_DoubleExponentialDecayFields::Coefficient1C1,modelObject.coefficient1C1());
  idfObject.setDouble(Curve_DoubleExponentialDecayFields::Coefficient2C2,modelObject.coefficient2C2());
  idfObject.setDouble(Curve_DoubleExponentialDecayFields::Coefficient3C3,modelObject.coefficient3C3());
  idfObject.setDouble(Curve_DoubleExponentialDecayFields::Coefficient3C4,modelObject.coefficient3C4());
  idfObject.setDouble(Curve_DoubleExponentialDecayFields::Coefficient3C5,modelObject.coefficient3C5());
  idfObject.setDouble(Curve_DoubleExponentialDecayFields::MinimumValueofx,modelObject.minimumValueofx());
  idfObject.setDouble(Curve_DoubleExponentialDecayFields::MaximumValueofx,modelObject.maximumValueofx());
  if ((d = modelObject.minimumCurveOutput())) {
    idfObject.setDouble(Curve_DoubleExponentialDecayFields::MinimumCurveOutput,*d);
  }
  if ((d = modelObject.maximumCurveOutput())) {
    idfObject.setDouble(Curve_DoubleExponentialDecayFields::MaximumCurveOutput,*d);
  }
  if (!modelObject.isInputUnitTypeforxDefaulted()) {
    idfObject.setString(Curve_DoubleExponentialDecayFields::InputUnitTypeforx,modelObject.inputUnitTypeforx());
  }
  if (!modelObject.isOutputUnitTypeDefaulted()) {
    idfObject.setString(Curve_DoubleExponentialDecayFields::OutputUnitType,modelObject.outputUnitType());
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateCurveQuartic( 
    CurveQuartic& modelObject)
{
  IdfObject idfObject(IddObjectType::Curve_Quartic);

  m_idfObjects.push_back(idfObject);

  OptionalString s;
  OptionalDouble d;

  if ((s = modelObject.name())) {
    idfObject.setName(*s);
  }

  idfObject.setDouble(Curve_QuarticFields::Coefficient1Constant,modelObject.coefficient1Constant());
  idfObject.setDouble(Curve_QuarticFields::Coefficient2x,modelObject.coefficient2x());
  idfObject.setDouble(Curve_QuarticFields::Coefficient3x_POW_2,modelObject.coefficient3xPOW2());
  idfObject.setDouble(Curve_QuarticFields::Coefficient4x_POW_3,modelObject.coefficient4xPOW3());
  idfObject.setDouble(Curve_QuarticFields::Coefficient5x_POW_4,modelObject.coefficient5xPOW4());
  idfObject.setDouble(Curve_QuarticFields::MinimumValueofx,modelObject.minimumValueofx());
  idfObject.setDouble(Curve_QuarticFields::MaximumValueofx,modelObject.maximumValueofx());
  if ((d = modelObject.minimumCurveOutput())) {
    idfObject.setDouble(Curve_QuarticFields::MinimumCurveOutput,*d);
  }
  if ((d = modelObject.maximumCurveOutput())) {
    idfObject.setDouble(Curve_QuarticFields::MaximumCurveOutput,*d);
  }
  if (!modelObject.isInputUnitTypeforXDefaulted()) {
    idfObject.setString(Curve_QuarticFields::InputUnitTypeforX,modelObject.inputUnitTypeforX());
  }
  if (!modelObject.isOutputUnitTypeDefaulted()) {
    idfObject.setString(Curve_QuarticFields::OutputUnitType,modelObject.outputUnitType());
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateShadowCalculation( ShadowCalculation & modelObject )
{
  IdfObject idfObject( openstudio::IddObjectType::ShadowCalculation);

  idfObject.setString(ShadowCalculationFields::CalculationMethod,"AverageOverDaysInFrequency");

  idfObject.setInt(ShadowCalculationFields::CalculationFrequency,modelObject.calculationFrequency());

  idfObject.setInt(ShadowCalculationFields::MaximumFiguresinShadowOverlapCalculations,modelObject.maximumFiguresInShadowOverlapCalculations());

  OptionalString s = modelObject.polygonClippingAlgorithm();
  if (s) {
    idfObject.setString(ShadowCalculationFields::PolygonClippingAlgorithm,*s);
  }

  s = modelObject.skyDiffuseModelingAlgorithm();
  if (s) {
    idfObject.setString(ShadowCalculationFields::SkyDiffuseModelingAlgorithm,*s);
  }

  m_idfObjects.push_back(idfObject);

  return boost::optional<IdfObject>(idfObject);
}
boost::optional<IdfObject> ForwardTranslator::translateZoneHVACPackagedTerminalAirConditioner( 
    ZoneHVACPackagedTerminalAirConditioner & modelObject )
{
  boost::optional<std::string> s;
  boost::optional<double> value;

  IdfObject idfObject(IddObjectType::ZoneHVAC_PackagedTerminalAirConditioner);

  m_idfObjects.push_back(idfObject);

  // Name

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

  idfObject.setName(baseName);

  std::string mixedAirNodeName = baseName + " Mixed Air Node";

  std::string coolingCoilOutletNodeName = baseName + " Cooling Coil Outlet Node";

  std::string heatingCoilOutletNodeName = baseName + " Heating Coil Outlet Node";

  std::string reliefAirNodeName = baseName + " Relief Air Node";

  std::string oaNodeName = baseName + " OA Node";

  // AvailabilityScheduleName

  if( boost::optional<Schedule> schedule = modelObject.availabilitySchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::AvailabilityScheduleName,_schedule->name().get());
    }
  }

  // AirInletNodeName

  boost::optional<std::string> airInletNodeName;

  if( boost::optional<Node> node = modelObject.inletNode() )
  {
    if( (s = node->name()) )
    {
      airInletNodeName = s;

      idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::AirInletNodeName,s.get());
    }
  }

  // AirOutletNodeName

  boost::optional<std::string> airOutletNodeName;

  if( boost::optional<Node> node = modelObject.outletNode() )
  {
    if( (s = node->name()) )
    {
      airOutletNodeName = s;

      idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::AirOutletNodeName,s.get());
    }
  }

  // OutdoorAirMixerObjectType
  idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirMixerObjectType,
                      modelObject.outdoorAirMixerObjectType());

  // OutdoorAirMixerName
  
  std::string oaMixerName = modelObject.name().get() + " OA Mixer";  

  idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirMixerName,oaMixerName);

  IdfObject _outdoorAirMixer(IddObjectType::OutdoorAir_Mixer);
  _outdoorAirMixer.setName(oaMixerName);
  m_idfObjects.push_back(_outdoorAirMixer);

  _outdoorAirMixer.setString(OutdoorAir_MixerFields::MixedAirNodeName,mixedAirNodeName);

  _outdoorAirMixer.setString(OutdoorAir_MixerFields::OutdoorAirStreamNodeName,oaNodeName);

  IdfObject _oaNodeList(openstudio::IddObjectType::OutdoorAir_NodeList);
  _oaNodeList.setString(0,oaNodeName);
  m_idfObjects.push_back(_oaNodeList);

  _outdoorAirMixer.setString(OutdoorAir_MixerFields::ReliefAirStreamNodeName,reliefAirNodeName);

  if(airInletNodeName)
  {
    _outdoorAirMixer.setString(OutdoorAir_MixerFields::ReturnAirStreamNodeName,airInletNodeName.get());
  }

  // SupplyAirFlowRateDuringCoolingOperation

  if( modelObject.isSupplyAirFlowRateDuringCoolingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFlowRateDuringCoolingOperation,"Autosize");
  }
  else if( (value = modelObject.supplyAirFlowRateDuringCoolingOperation()) )
  {
    idfObject.setDouble(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFlowRateDuringCoolingOperation,value.get());
  }

  // SupplyAirFlowRateDuringHeatingOperation

  if( modelObject.isSupplyAirFlowRateDuringHeatingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFlowRateDuringHeatingOperation,"Autosize");
  }
  else if( (value = modelObject.supplyAirFlowRateDuringHeatingOperation()) )
  {
    idfObject.setDouble(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFlowRateDuringHeatingOperation,value.get());
  }

  // SupplyAirFlowRateWhenNoCoolingorHeatingisNeeded

  if( modelObject.isSupplyAirFlowRateWhenNoCoolingorHeatingisNeededAutosized() )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFlowRateWhenNoCoolingorHeatingisNeeded,"Autosize");
  } 
  else if( (value = modelObject.supplyAirFlowRateWhenNoCoolingorHeatingisNeeded()) )
  {
    idfObject.setDouble(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFlowRateWhenNoCoolingorHeatingisNeeded,value.get());
  }

  // OutdoorAirFlowRateDuringCoolingOperation
  
  if( modelObject.isOutdoorAirFlowRateDuringCoolingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirFlowRateDuringCoolingOperation,"Autosize");
  }
  else if( (value = modelObject.outdoorAirFlowRateDuringCoolingOperation()) )
  {
    idfObject.setDouble(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirFlowRateDuringCoolingOperation,value.get());
  }

  // OutdoorAirFlowRateDuringHeatingOperation
  
  if( modelObject.isOutdoorAirFlowRateDuringHeatingOperationAutosized() )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirFlowRateDuringHeatingOperation,"Autosize");
  }
  else if( (value = modelObject.outdoorAirFlowRateDuringHeatingOperation()) )
  {
    idfObject.setDouble(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirFlowRateDuringHeatingOperation,value.get());
  }

  // OutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded
  
  if( modelObject.isOutdoorAirFlowRateWhenNoCoolingorHeatingisNeededAutosized() )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded,"Autosize");
  }
  else if( (value = modelObject.outdoorAirFlowRateWhenNoCoolingorHeatingisNeeded()) )
  {
    idfObject.setDouble(ZoneHVAC_PackagedTerminalAirConditionerFields::OutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded,value.get());
  }

  // SupplyAirFanObjectType

  HVACComponent supplyAirFan = modelObject.supplyAirFan();

  if( boost::optional<IdfObject> _supplyAirFan = translateAndMapModelObject(supplyAirFan) )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFanObjectType,_supplyAirFan->iddObject().name() );

    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFanName,_supplyAirFan->name().get());

    if( airOutletNodeName )
    {
      if( _supplyAirFan->iddObject().type() == IddObjectType::Fan_ConstantVolume )
      {
        _supplyAirFan->setString(Fan_ConstantVolumeFields::AirInletNodeName,heatingCoilOutletNodeName);

        _supplyAirFan->setString(Fan_ConstantVolumeFields::AirOutletNodeName,airOutletNodeName.get());
      }
    }
  }

  // HeatingCoilObjectType
  
  HVACComponent heatingCoil = modelObject.heatingCoil();

  if( boost::optional<IdfObject> _heatingCoil = translateAndMapModelObject(heatingCoil) )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::HeatingCoilObjectType,_heatingCoil->iddObject().name() );

    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::HeatingCoilName,_heatingCoil->name().get() ); 

    if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water )
    {
      _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName,coolingCoilOutletNodeName);

      _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName,heatingCoilOutletNodeName);
    }
    else if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Gas )
    {
      _heatingCoil->setString(Coil_Heating_GasFields::AirInletNodeName,coolingCoilOutletNodeName);

      _heatingCoil->setString(Coil_Heating_GasFields::AirOutletNodeName,heatingCoilOutletNodeName);
    }
    else if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Electric )
    {
      _heatingCoil->setString(Coil_Heating_ElectricFields::AirInletNodeName,coolingCoilOutletNodeName);

      _heatingCoil->setString(Coil_Heating_ElectricFields::AirOutletNodeName,heatingCoilOutletNodeName);
    }
  }

  // CoolingCoilObjectType

  HVACComponent coolingCoil = modelObject.coolingCoil();

  boost::optional<IdfObject> _coolingCoil;

  if( boost::optional<CoilCoolingDXSingleSpeed> dxCoil = coolingCoil.optionalCast<CoilCoolingDXSingleSpeed>() )
  {
    _coolingCoil = translateCoilCoolingDXSingleSpeedWithoutUnitary(dxCoil.get());

    m_map.insert(std::make_pair(coolingCoil.handle(),_coolingCoil.get()));
  }
  else
  {
    _coolingCoil = translateAndMapModelObject(coolingCoil);
  }

  if( _coolingCoil )
  {
    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::CoolingCoilObjectType,_coolingCoil->iddObject().name() );

    idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::CoolingCoilName,_coolingCoil->name().get() );

    if( _coolingCoil->iddObject().type() == IddObjectType::Coil_Cooling_DX_SingleSpeed )
    {
      _coolingCoil->setString(Coil_Cooling_DX_SingleSpeedFields::AirInletNodeName,mixedAirNodeName);

      _coolingCoil->setString(Coil_Cooling_DX_SingleSpeedFields::AirOutletNodeName,coolingCoilOutletNodeName);
    }
  }

  // FanPlacement

  idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::FanPlacement,modelObject.fanPlacement());

  // SupplyAirFanOperatingModeScheduleName
  
  if( boost::optional<Schedule> schedule = modelObject.supplyAirFanOperatingModeSchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(ZoneHVAC_PackagedTerminalAirConditionerFields::SupplyAirFanOperatingModeScheduleName,_schedule->name().get());
    }
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateAirTerminalSingleDuctVAVReheat( AirTerminalSingleDuctVAVReheat & modelObject )
{
  OptionalModelObject temp;
  OptionalString optS;
  boost::optional<std::string> s;

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

  IdfObject _airDistributionUnit(openstudio::IddObjectType::ZoneHVAC_AirDistributionUnit);
  _airDistributionUnit.setName("ADU " + baseName ); //ADU: Air Distribution Unit

  IdfObject idfObject(openstudio::IddObjectType::AirTerminal_SingleDuct_VAV_Reheat);

  idfObject.setName(baseName);

  HVACComponent coil = modelObject.reheatCoil();

  m_idfObjects.push_back(_airDistributionUnit);

  m_idfObjects.push_back(idfObject);

  boost::optional<IdfObject> _reheatCoil = translateAndMapModelObject(coil);

  if( _reheatCoil && _reheatCoil->name() )
  {
    std::string damperOutletNodeName = modelObject.name().get() + " Damper Outlet";

    boost::optional<std::string> inletNodeName;
    boost::optional<std::string> outletNodeName;

    if( boost::optional<ModelObject> inletModelObject = modelObject.inletModelObject() )
    {
      if( boost::optional<Node> inletNode = inletModelObject->optionalCast<Node>() )
      {
        inletNodeName = inletNode->name().get();
      }
    }

    if( boost::optional<ModelObject> outletModelObject = modelObject.outletModelObject() )
    {
      if( boost::optional<Node> outletNode = outletModelObject->optionalCast<Node>() )
      {
        outletNodeName = outletNode->name().get();
      }
    }

    // Reheat Coil Name
    idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::ReheatCoilName,_reheatCoil->name().get());

    // Reheat Coil Type
    idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::ReheatCoilObjectType,_reheatCoil->iddObject().name());

    idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::DamperAirOutletNodeName,damperOutletNodeName);

    if( outletNodeName && inletNodeName )
    {
      if( _reheatCoil->iddObject().type() == IddObjectType::Coil_Heating_Gas )
      {
        _reheatCoil->setString(Coil_Heating_GasFields::AirInletNodeName,damperOutletNodeName);
        _reheatCoil->setString(Coil_Heating_GasFields::AirOutletNodeName,outletNodeName.get());
      }
      else if( _reheatCoil->iddObject().type() == IddObjectType::Coil_Heating_Electric )
      {
        _reheatCoil->setString(Coil_Heating_ElectricFields::AirInletNodeName,damperOutletNodeName);
        _reheatCoil->setString(Coil_Heating_ElectricFields::AirOutletNodeName,outletNodeName.get());
      }
      else if( _reheatCoil->iddObject().type() == IddObjectType::Coil_Heating_Water )
      {
        _reheatCoil->setString(Coil_Heating_WaterFields::AirInletNodeName,damperOutletNodeName);
        _reheatCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName,outletNodeName.get());
      }

      idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::AirOutletNodeName,outletNodeName.get());
      idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::AirInletNodeName,inletNodeName.get());
    }
  }
  else
  {
    LOG(Error,modelObject.briefDescription() << ": Could not translate heating coil");

    return boost::none;
  }

  // AvailabilityScheduleName
  Schedule availabilitySchedule = modelObject.availabilitySchedule();

  boost::optional<IdfObject> _availabilitySchedule = translateAndMapModelObject(availabilitySchedule);

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

  // MaximumAirFlowRate
  boost::optional<double> value = modelObject.maximumAirFlowRate();
  if( value )
  {
    idfObject.setDouble(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumAirFlowRate,value.get());
  }
  else if( modelObject.isMaximumAirFlowRateAutosized() )
  {
    idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumAirFlowRate,"Autosize");
  }

  // ZoneMinimumAirFlowMethod
  s = modelObject.zoneMinimumAirFlowMethod();
  if( s )
  {
    idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::ZoneMinimumAirFlowInputMethod,s.get());
  }

  // ConstantMinimumAirFlowFraction
  value = modelObject.constantMinimumAirFlowFraction();
  idfObject.setDouble(AirTerminal_SingleDuct_VAV_ReheatFields::ConstantMinimumAirFlowFraction,value.get());

  // FixedMinimumAirFlowRate
  value = modelObject.fixedMinimumAirFlowRate();
  idfObject.setDouble(AirTerminal_SingleDuct_VAV_ReheatFields::FixedMinimumAirFlowRate,value.get());

  // MinimumAirFlowFractionScheduleName
  boost::optional<Schedule> minAirFlowFractionSchedule = modelObject.minimumAirFlowFractionSchedule();

  if( minAirFlowFractionSchedule )
  {
    boost::optional<IdfObject> _minAirFlowFractionSchedule = translateAndMapModelObject(minAirFlowFractionSchedule.get());

    if( _minAirFlowFractionSchedule && _minAirFlowFractionSchedule->name() )
    {
      idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::MinimumAirFlowFractionScheduleName,_minAirFlowFractionSchedule->name().get());
    }
  }

  // MaximumHotWaterOrSteamFlowRate
  value = modelObject.maximumHotWaterOrSteamFlowRate();
  
  if( value )
  {
    idfObject.setDouble(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumHotWaterorSteamFlowRate,value.get());
  }
  else if( modelObject.isMaximumHotWaterOrSteamFlowRateAutosized() )
  {
    idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumHotWaterorSteamFlowRate,"Autosize");
  }

  // MinimumHotWaterOrSteamFlowRate
  value = modelObject.minimumHotWaterOrSteamFlowRate();
  idfObject.setDouble(AirTerminal_SingleDuct_VAV_ReheatFields::MinimumHotWaterorSteamFlowRate,value.get());

  // ConvergenceTolerance
  value = modelObject.convergenceTolerance();
  idfObject.setDouble(AirTerminal_SingleDuct_VAV_ReheatFields::ConvergenceTolerance,value.get());

  // DamperHeatingAction
  s = modelObject.damperHeatingAction();
  idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::DamperHeatingAction,s.get());

  // MaximumFlowPerZoneFloorAreaDuringReheat
  value = modelObject.maximumFlowPerZoneFloorAreaDuringReheat();
  
  if( value )
  {
    idfObject.setDouble(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumFlowperZoneFloorAreaDuringReheat,value.get());
  }
  else if ( modelObject.isMaximumFlowPerZoneFloorAreaDuringReheatAutosized() )
  {
    idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumFlowperZoneFloorAreaDuringReheat,"Autocalculate");
  }

  // MaximumFlowFractionDuringReheat
  value = modelObject.maximumFlowFractionDuringReheat();

  if( value )
  {
    idfObject.setDouble(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumFlowFractionDuringReheat,value.get());
  }
  else if( modelObject.isMaximumFlowFractionDuringReheatAutosized() )
  {
    idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumFlowFractionDuringReheat,"Autocalculate");
  }

  // MaximumReheatAirTemperature
  value = modelObject.maximumReheatAirTemperature();
  idfObject.setDouble(AirTerminal_SingleDuct_VAV_ReheatFields::MaximumReheatAirTemperature,value.get());

  // Populate fields for AirDistributionUnit
  if( boost::optional<ModelObject> outletNode = modelObject.outletModelObject() )
  {
    _airDistributionUnit.setString(ZoneHVAC_AirDistributionUnitFields::AirDistributionUnitOutletNodeName,outletNode->name().get());
  }
  _airDistributionUnit.setString(ZoneHVAC_AirDistributionUnitFields::AirTerminalObjectType,idfObject.iddObject().name());
  _airDistributionUnit.setString(ZoneHVAC_AirDistributionUnitFields::AirTerminalName,idfObject.name().get());

  // ControlForOutdoorAir
  {
    if( modelObject.controlForOutdoorAir() ) {
      if( auto airLoopHVAC = modelObject.airLoopHVAC() ) {
        auto zones = airLoopHVAC->demandComponents(modelObject,airLoopHVAC->demandOutletNode(),model::ThermalZone::iddObjectType());
        if( ! zones.empty() ) {
          auto zone = zones.front();
          auto spaces = zone.cast<model::ThermalZone>().spaces();
          if( ! spaces.empty() ) {
            if( auto designSpecificationOutdoorAir = spaces.front().designSpecificationOutdoorAir() ) {
              idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::DesignSpecificationOutdoorAirObjectName,
                designSpecificationOutdoorAir->name().get()); 
            }
          }
        }
      }  
    }
  }

  return _airDistributionUnit;
}
boost::optional<IdfObject> ForwardTranslator::translateDesignDay( DesignDay & modelObject )
{

  IdfObject idfObject( openstudio::IddObjectType::SizingPeriod_DesignDay);

  // Name
  idfObject.setName(modelObject.name().get());

  // Month
  idfObject.setInt(SizingPeriod_DesignDayFields::Month, modelObject.month());

  // Day of Month
  idfObject.setInt(SizingPeriod_DesignDayFields::DayofMonth, modelObject.dayOfMonth());

  // Day Type
  idfObject.setString(SizingPeriod_DesignDayFields::DayType, modelObject.dayType());

  // Maximum Dry-Bulb Temperature
  idfObject.setDouble(SizingPeriod_DesignDayFields::MaximumDryBulbTemperature, modelObject.maximumDryBulbTemperature());

  // Dry-Bulb Temperature Range Modifier Type
  std::string dryBulbTemperatureRangeModifierType = modelObject.dryBulbTemperatureRangeModifierType();
  idfObject.setString(SizingPeriod_DesignDayFields::DryBulbTemperatureRangeModifierType, dryBulbTemperatureRangeModifierType);

  // Daily Dry-Bulb Temperature Range
  if (!istringEqual(dryBulbTemperatureRangeModifierType, "DifferenceSchedule")){
    idfObject.setDouble(SizingPeriod_DesignDayFields::DailyDryBulbTemperatureRange, modelObject.dailyDryBulbTemperatureRange());
  }

  // Dry-Bulb Temperature Range Modifier Day Schedule Name
  if (istringEqual(dryBulbTemperatureRangeModifierType, "MultiplierSchedule") || istringEqual(dryBulbTemperatureRangeModifierType, "DifferenceSchedule")){
    boost::optional<IdfObject> idfSchedule;
    if( boost::optional<ScheduleDay> schedule = modelObject.dryBulbTemperatureRangeModifierSchedule() ){
      idfSchedule = translateAndMapModelObject(*schedule);
    }
    if (idfSchedule){
      idfObject.setString(SizingPeriod_DesignDayFields::DryBulbTemperatureRangeModifierDayScheduleName, idfSchedule->name().get());
    }else{
      LOG(Error, "Dry Bulb Temperature Range Modifier Day Schedule Name field is required but not found");
    }
  }

  // Humidity Condition Type
  std::string humidityIndicatingType = modelObject.humidityIndicatingType();
  if (istringEqual(humidityIndicatingType, "Schedule")){
    humidityIndicatingType = "RelativeHumiditySchedule";
  }
  idfObject.setString(SizingPeriod_DesignDayFields::HumidityConditionType, humidityIndicatingType);

  // Wetbulb or DewPoint at Maximum Dry-Bulb
  if (istringEqual(humidityIndicatingType, "Wetbulb") ||
      istringEqual(humidityIndicatingType, "Dewpoint") ||
      istringEqual(humidityIndicatingType, "WetBulbProfileMultiplierSchedule") ||
      istringEqual(humidityIndicatingType, "WetBulbProfileDifferenceSchedule") ||
      istringEqual(humidityIndicatingType, "WetBulbProfileDefaultMultipliers")){
    // units for this field are C
    idfObject.setDouble(SizingPeriod_DesignDayFields::WetbulborDewPointatMaximumDryBulb, modelObject.humidityIndicatingConditionsAtMaximumDryBulb());
  }

  // Humidity Condition Day Schedule Name
  if (istringEqual(humidityIndicatingType, "RelativeHumiditySchedule") ||
      istringEqual(humidityIndicatingType, "WetBulbProfileMultiplierSchedule") ||
      istringEqual(humidityIndicatingType, "WetBulbProfileDifferenceSchedule") ||
      istringEqual(humidityIndicatingType, "RelativeHumiditySchedule")){
    if( boost::optional<ScheduleDay> schedule = modelObject.humidityIndicatingDaySchedule() ){
      idfObject.setString(SizingPeriod_DesignDayFields::HumidityConditionDayScheduleName, schedule->name().get());
    }else{
      LOG(Error, "Humidity Condition Day Schedule Name field is required but not found");
    }
  }

  // Humidity Ratio at Maximum Dry-Bulb
  if (istringEqual(humidityIndicatingType, "HumidityRatio")){
    // units for this field are kgWater/kgDryAir
    idfObject.setDouble(SizingPeriod_DesignDayFields::HumidityRatioatMaximumDryBulb, modelObject.humidityIndicatingConditionsAtMaximumDryBulb());
  }

  // Enthalpy at Maximum Dry-Bulb
  if (istringEqual(humidityIndicatingType, "Enthalpy")){
    // units for this field are J/kg
    idfObject.setDouble(SizingPeriod_DesignDayFields::EnthalpyatMaximumDryBulb, modelObject.humidityIndicatingConditionsAtMaximumDryBulb());
  }

  // Daily Wet-Bulb Temperature Range
  if (istringEqual(humidityIndicatingType, "WetbulbProfileMultiplierSchedule") ||
      istringEqual(humidityIndicatingType, "WetBulbProfileDefaultMultipliers")){
    if ( OptionalDouble d = modelObject.dailyWetBulbTemperatureRange()) {
      idfObject.setDouble(SizingPeriod_DesignDayFields::DailyWetBulbTemperatureRange, *d);
    }else{
      LOG(Error, "Daily Wet Bulb Temperature Range field is required but not found");
    }
  }

  // Barometric Pressure
  idfObject.setDouble(SizingPeriod_DesignDayFields::BarometricPressure, modelObject.barometricPressure());

  // Site Wind Speed
  idfObject.setDouble(SizingPeriod_DesignDayFields::WindSpeed, modelObject.windSpeed());

  // Site Wind Direction
  idfObject.setDouble(SizingPeriod_DesignDayFields::WindDirection,modelObject.windDirection());

  // Rain Indicator
  if( modelObject.rainIndicator() ){
    idfObject.setString(SizingPeriod_DesignDayFields::RainIndicator, "Yes");
  }else{
    idfObject.setString(SizingPeriod_DesignDayFields::RainIndicator, "No");
  }

  // Snow Indicator
  if( modelObject.snowIndicator() ){
    idfObject.setString(SizingPeriod_DesignDayFields::SnowIndicator, "Yes");
  }else{
    idfObject.setString(SizingPeriod_DesignDayFields::SnowIndicator, "No");
  }

  // Site Daylight Saving Time Status
  if( modelObject.daylightSavingTimeIndicator() ){
    idfObject.setString(SizingPeriod_DesignDayFields::DaylightSavingTimeIndicator, "Yes");
  }else{
    idfObject.setString(SizingPeriod_DesignDayFields::DaylightSavingTimeIndicator, "No");
  }

  // Solar Model Indicator
  std::string solarModelIndicator = modelObject.solarModelIndicator();
  idfObject.setString(SizingPeriod_DesignDayFields::SolarModelIndicator, solarModelIndicator);

  // Beam Solar Day Schedule Name and Site Diffuse Solar Radiation Rate per Area Day Schedule Name
  if (istringEqual(solarModelIndicator, "Schedule")){

    boost::optional<IdfObject> idfSchedule;

    // Beam Solar Day Schedule Name
    if( boost::optional<ScheduleDay> schedule = modelObject.beamSolarDaySchedule() ){
      idfSchedule = translateAndMapModelObject(*schedule);
    }
    if (idfSchedule){
      idfObject.setString(SizingPeriod_DesignDayFields::BeamSolarDayScheduleName, idfSchedule->name().get());
    }else{
      LOG(Error, "Beam Solar Day Schedule Name field is required but not found");
    }

    idfSchedule.reset();

    // Site Diffuse Solar Radiation Rate per Area Day Schedule Name
    if( boost::optional<ScheduleDay> schedule = modelObject.diffuseSolarDaySchedule() ){
      idfSchedule = translateAndMapModelObject(*schedule);
    }
    if (idfSchedule) {
      idfObject.setString(SizingPeriod_DesignDayFields::DiffuseSolarDayScheduleName, idfSchedule->name().get());
    }else{
      LOG(Error, "Site Diffuse Solar Radiation Rate per Area Day Schedule Name field is required but not found");
    }
  }

  if (istringEqual(solarModelIndicator, "ASHRAETau")){
    // ASHRAE Clear Sky Optical Depth for Beam Irradiance (taub)
    idfObject.setDouble(SizingPeriod_DesignDayFields::ASHRAEClearSkyOpticalDepthforBeamIrradiance_taub_ , modelObject.ashraeTaub());

    // ASHRAE Clear Sky Optical Depth for Diffuse Irradiance (taud)
    idfObject.setDouble(SizingPeriod_DesignDayFields::ASHRAEClearSkyOpticalDepthforDiffuseIrradiance_taud_, modelObject.ashraeTaud());
  }

  // Sky Clearness
  if (istringEqual(solarModelIndicator, "ASHRAEClearSky") || istringEqual(solarModelIndicator, "ZhangHuang")){
    idfObject.setDouble(SizingPeriod_DesignDayFields::SkyClearness, modelObject.skyClearness());
  }

  m_idfObjects.push_back(idfObject);

  return boost::optional<IdfObject>(idfObject);
}
boost::optional<IdfObject> ForwardTranslator::translateAirTerminalSingleDuctConstantVolumeReheat( AirTerminalSingleDuctConstantVolumeReheat& modelObject )
{
  OptionalModelObject temp;
  OptionalString optS;
  boost::optional<std::string> s;

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

  IdfObject _airDistributionUnit(openstudio::IddObjectType::ZoneHVAC_AirDistributionUnit);
  _airDistributionUnit.setName("ADU " + baseName ); //ADU: Air Distribution Unit

  IdfObject idfObject(openstudio::IddObjectType::AirTerminal_SingleDuct_ConstantVolume_Reheat);

  idfObject.setName(baseName);

  HVACComponent coil = modelObject.reheatCoil();

  m_idfObjects.push_back(_airDistributionUnit);

  m_idfObjects.push_back(idfObject);

  boost::optional<IdfObject> _reheatCoil = translateAndMapModelObject(coil);

  if( _reheatCoil && _reheatCoil->name() )
  {
    boost::optional<std::string> inletNodeName;
    boost::optional<std::string> outletNodeName;

    if( boost::optional<ModelObject> inletModelObject = modelObject.inletModelObject() )
    {
      if( boost::optional<Node> inletNode = inletModelObject->optionalCast<Node>() )
      {
        inletNodeName = inletNode->name().get();
      }
    }

    if( boost::optional<ModelObject> outletModelObject = modelObject.outletModelObject() )
    {
      if( boost::optional<Node> outletNode = outletModelObject->optionalCast<Node>() )
      {
        outletNodeName = outletNode->name().get();
      }
    }

    // Reheat Coil Name
    idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::ReheatCoilName,_reheatCoil->name().get());

    // Reheat Coil Type
    idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::ReheatCoilObjectType,_reheatCoil->iddObject().name());

    if( outletNodeName && inletNodeName )
    {
      if( _reheatCoil->iddObject().type() == IddObjectType::Coil_Heating_Gas )
      {
        _reheatCoil->setString(Coil_Heating_GasFields::AirInletNodeName,inletNodeName.get());
        _reheatCoil->setString(Coil_Heating_GasFields::AirOutletNodeName,outletNodeName.get());
      }
      else if( _reheatCoil->iddObject().type() == IddObjectType::Coil_Heating_Electric )
      {
        _reheatCoil->setString(Coil_Heating_ElectricFields::AirInletNodeName,inletNodeName.get());
        _reheatCoil->setString(Coil_Heating_ElectricFields::AirOutletNodeName,outletNodeName.get());
      }
      else if( _reheatCoil->iddObject().type() == IddObjectType::Coil_Heating_Water )
      {
        _reheatCoil->setString(Coil_Heating_WaterFields::AirInletNodeName,inletNodeName.get());
        _reheatCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName,outletNodeName.get());
      }

      idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::AirOutletNodeName,outletNodeName.get());
      idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::AirInletNodeName,inletNodeName.get());
    }
  }
  else
  {
    LOG(Error,modelObject.briefDescription() << ": Could not translate heating coil");

    return boost::none;
  }

  // AvailabilityScheduleName
  Schedule availabilitySchedule = modelObject.availabilitySchedule();

  boost::optional<IdfObject> _availabilitySchedule = translateAndMapModelObject(availabilitySchedule);

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

  // MaximumAirFlowRate
  boost::optional<double> value = modelObject.maximumAirFlowRate();
  if( value )
  {
    idfObject.setDouble(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::MaximumAirFlowRate,value.get());
  }
  else if( modelObject.isMaximumAirFlowRateAutosized() )
  {
    idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::MaximumAirFlowRate,"Autosize");
  }

  // HotWaterorSteamInletNodeName
  idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::HotWaterorSteamInletNodeName,"");

  // MaximumHotWaterOrSteamFlowRate
  value = modelObject.maximumHotWaterorSteamFlowRate();
  
  if( value )
  {
    idfObject.setDouble(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::MaximumHotWaterorSteamFlowRate,value.get());
  }
  else if( modelObject.isMaximumHotWaterorSteamFlowRateAutosized() )
  {
    idfObject.setString(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::MaximumHotWaterorSteamFlowRate,"Autosize");
  }

  // MinimumHotWaterOrSteamFlowRate
  value = modelObject.minimumHotWaterorSteamFlowRate();
  idfObject.setDouble(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::MinimumHotWaterorSteamFlowRate,value.get());

  // ConvergenceTolerance
  value = modelObject.convergenceTolerance();
  idfObject.setDouble(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::ConvergenceTolerance,value.get());

  // MaximumReheatAirTemperature
  value = modelObject.maximumReheatAirTemperature();
  idfObject.setDouble(AirTerminal_SingleDuct_ConstantVolume_ReheatFields::MaximumReheatAirTemperature,value.get());

  // Populate fields for AirDistributionUnit
  if( boost::optional<ModelObject> outletNode = modelObject.outletModelObject() )
  {
    _airDistributionUnit.setString(ZoneHVAC_AirDistributionUnitFields::AirDistributionUnitOutletNodeName,outletNode->name().get());
  }
  _airDistributionUnit.setString(ZoneHVAC_AirDistributionUnitFields::AirTerminalObjectType,idfObject.iddObject().name());
  _airDistributionUnit.setString(ZoneHVAC_AirDistributionUnitFields::AirTerminalName,idfObject.name().get());

  return _airDistributionUnit;
}
boost::optional<IdfObject> ForwardTranslator::translateCoilHeatingElectric( CoilHeatingElectric & modelObject )
{
  boost::optional<std::string> s;
  boost::optional<double> value;

  IdfObject idfObject(IddObjectType::Coil_Heating_Electric);

  m_idfObjects.push_back(idfObject);

  // Name

  s = modelObject.name();
  if( s )
  {
    idfObject.setName(*s);
  }

  // AvailabilityScheduleName

  if( boost::optional<Schedule> schedule = modelObject.availabilitySchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(Coil_Heating_ElectricFields::AvailabilityScheduleName,_schedule->name().get());
    }
  }

  // Efficiency

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

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

  // Air Inlet Node Name
 
  if( boost::optional<ModelObject> mo = modelObject.inletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(Coil_Heating_ElectricFields::AirInletNodeName,node->name().get());
    }
  }

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

  // Temperature Setpoint Node Name 
 
  if( boost::optional<Node> node = modelObject.temperatureSetpointNode() )
  {
    idfObject.setString(Coil_Heating_ElectricFields::TemperatureSetpointNodeName,node->name().get());
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateWaterHeaterHeatPump( 
    WaterHeaterHeatPump & modelObject)
{
  IdfObject idfObject(IddObjectType::WaterHeater_HeatPump_PumpedCondenser);
  m_idfObjects.push_back(idfObject);

  // Name
  if( auto s = modelObject.name() ) {
    idfObject.setName(*s);
  }

  if( auto mo = modelObject.availabilitySchedule() ) {
    idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::AvailabilityScheduleName,mo->name().get());
  }

  {
    auto mo = modelObject.compressorSetpointTemperatureSchedule();
    idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::CompressorSetpointTemperatureScheduleName,mo.name().get());
  }

  {
    auto value = modelObject.deadBandTemperatureDifference();
    idfObject.setDouble(WaterHeater_HeatPump_PumpedCondenserFields::DeadBandTemperatureDifference,value);
  }

  if( modelObject.isCondenserWaterFlowRateAutosized() ) {
    idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::CondenserWaterFlowRate,"Autosize");
  } else if( auto value = modelObject.condenserWaterFlowRate() ) {
    idfObject.setDouble(WaterHeater_HeatPump_PumpedCondenserFields::CondenserWaterFlowRate,value.get());
  }

  if( modelObject.isEvaporatorAirFlowRateAutosized() ) {
    idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::EvaporatorAirFlowRate,"Autosize");
  } else if( auto value = modelObject.evaporatorAirFlowRate() ) {
    idfObject.setDouble(WaterHeater_HeatPump_PumpedCondenserFields::EvaporatorAirFlowRate,value.get());
  }

  {
    auto value = modelObject.inletAirConfiguration();
    idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::InletAirConfiguration,value);
  }

  if( auto mo = modelObject.inletAirTemperatureSchedule() ) {
    idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::InletAirTemperatureScheduleName,mo->name().get());
  }

  if( auto mo = modelObject.inletAirHumiditySchedule() ) {
    idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::InletAirHumidityScheduleName,mo->name().get());
  }

  {
    auto value = modelObject.minimumInletAirTemperatureforCompressorOperation();
    idfObject.setDouble(WaterHeater_HeatPump_PumpedCondenserFields::MinimumInletAirTemperatureforCompressorOperation,value);
  }

  {
    auto value = modelObject.compressorLocation();
    idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::CompressorLocation,value);
  }

  if( auto mo = modelObject.compressorAmbientTemperatureSchedule() ) {
    idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::CompressorAmbientTemperatureScheduleName,mo->name().get());
  }

  {
    auto value = modelObject.fanPlacement();
    idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::FanPlacement,value);
  }

  {
    auto value = modelObject.onCycleParasiticElectricLoad();
    idfObject.setDouble(WaterHeater_HeatPump_PumpedCondenserFields::OnCycleParasiticElectricLoad,value);
  }

  {
    auto value = modelObject.offCycleParasiticElectricLoad();
    idfObject.setDouble(WaterHeater_HeatPump_PumpedCondenserFields::OffCycleParasiticElectricLoad,value);
  }

  {
    auto value = modelObject.parasiticHeatRejectionLocation();
    idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::ParasiticHeatRejectionLocation,value);
  }

  {
    auto mo = modelObject.inletAirMixerSchedule();
    idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::InletAirMixerScheduleName,mo.name().get());
  }

  {
    auto tank = modelObject.tank();
    if( auto stratifiedTank = tank.optionalCast<model::WaterHeaterStratified>() ) {
      auto value = modelObject.controlSensorLocationInStratifiedTank();
      if( istringEqual(value,"Heater1") ) {
        auto height = stratifiedTank->heater1Height();
        idfObject.setDouble(WaterHeater_HeatPump_PumpedCondenserFields::ControlSensor1HeightInStratifiedTank,height);
      } else if( istringEqual(value,"Heater2") ) {
        auto height = stratifiedTank->heater2Height();
        idfObject.setDouble(WaterHeater_HeatPump_PumpedCondenserFields::ControlSensor1HeightInStratifiedTank,height);
      } else if( istringEqual(value,"SourceInlet") ) {
        if( auto height = stratifiedTank->sourceSideInletHeight() ) {
          idfObject.setDouble(WaterHeater_HeatPump_PumpedCondenserFields::ControlSensor1HeightInStratifiedTank,height.get());
        }
      } else if( istringEqual(value,"SourceOutlet") ) {
        auto height = stratifiedTank->sourceSideOutletHeight();
        idfObject.setDouble(WaterHeater_HeatPump_PumpedCondenserFields::ControlSensor1HeightInStratifiedTank,height);
      } else if( istringEqual(value,"UseInlet") ) {
        auto height = stratifiedTank->useSideInletHeight();
        idfObject.setDouble(WaterHeater_HeatPump_PumpedCondenserFields::ControlSensor1HeightInStratifiedTank,height);
      } else if( istringEqual(value,"UseOutlet") ) {
        if( auto height = stratifiedTank->useSideOutletHeight() ) {
          idfObject.setDouble(WaterHeater_HeatPump_PumpedCondenserFields::ControlSensor1HeightInStratifiedTank,height.get());
        }
      }
    }
  }

  std::string condOutletTankInletNodeName =
    modelObject.name().get() + " Condenser Outlet - Tank Inlet";

  std::string tankOutletCondInletNodeName = 
    modelObject.name().get() + " Tank Outlet - Condenser Inlet";

  idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::CondenserWaterInletNodeName,tankOutletCondInletNodeName);
  idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::CondenserWaterOutletNodeName,condOutletTankInletNodeName);

  std::string airInletNodeName;
  std::string airOutletNodeName;
  std::string outdoorAirNodeName;
  std::string exhaustAirNodeName;
  std::string inletAirZoneName;
  std::string inletAirMixerNodeName;
  std::string outletAirSplitterNodeName;
  std::string fanInletNodeName;
  std::string fanOutletNodeName;
  std::string evapInletNodeName;
  std::string evapOutletNodeName;

  auto inletAirConfiguration = modelObject.inletAirConfiguration();
  if( istringEqual(modelObject.fanPlacement(),"DrawThrough") ) {

    if( istringEqual(inletAirConfiguration,"ZoneAirOnly") ) {
      if( auto thermalZone = modelObject.thermalZone() ) {
        auto inletNode = modelObject.inletNode();
        OS_ASSERT(inletNode);
        airInletNodeName = inletNode->name().get();

        auto outletNode = modelObject.outletNode();
        OS_ASSERT(outletNode);
        airOutletNodeName = outletNode->name().get();
        
        inletAirZoneName = thermalZone->name().get();
        fanInletNodeName = modelObject.name().get() + " Evap Outlet - Fan Inlet";
        fanOutletNodeName = airOutletNodeName;
        evapInletNodeName = airInletNodeName;
        evapOutletNodeName = fanInletNodeName;
      }
    } else if( istringEqual(inletAirConfiguration,"ZoneAndOutdoorAir") ) {
      if( auto thermalZone = modelObject.thermalZone() ) {
        auto inletNode = modelObject.inletNode();
        OS_ASSERT(inletNode);
        airInletNodeName = inletNode->name().get();

        auto outletNode = modelObject.outletNode();
        OS_ASSERT(outletNode);
        airOutletNodeName = outletNode->name().get();

        outdoorAirNodeName = modelObject.name().get() + " Outdoor Air";
        exhaustAirNodeName = modelObject.name().get() + " Exhaust Air";
        inletAirZoneName = thermalZone->name().get();
        inletAirMixerNodeName = modelObject.name().get() + " Mixer Outlet - Evap Inlet";
        outletAirSplitterNodeName = modelObject.name().get() + " Fan Outlet - Splitter Inlet";
        fanInletNodeName = modelObject.name().get() + " Evap Outlet - Fan Inlet";
        fanOutletNodeName = outletAirSplitterNodeName;
        evapInletNodeName = inletAirMixerNodeName;
        evapOutletNodeName = fanInletNodeName;
      }
    } else if( istringEqual(inletAirConfiguration,"OutdoorAirOnly") ) {
      outdoorAirNodeName = modelObject.name().get() + " Outdoor Air";
      exhaustAirNodeName = modelObject.name().get() + " Exhaust Air";
      fanInletNodeName = modelObject.name().get() + " Evap Outlet - Fan Inlet";
      fanOutletNodeName = exhaustAirNodeName;
      evapInletNodeName = outdoorAirNodeName;
      evapOutletNodeName = fanInletNodeName;
    } else if( istringEqual(inletAirConfiguration,"Schedule") ) {
      airInletNodeName = modelObject.name().get() + " Inlet";
      airOutletNodeName = modelObject.name().get() + " Outlet";
      fanInletNodeName = modelObject.name().get() + " Evap Outlet - Fan Inlet";
      fanOutletNodeName = airOutletNodeName;
      evapInletNodeName = airInletNodeName;
      evapOutletNodeName = fanInletNodeName;
    }

  } else { // BlowThrough

    if( istringEqual(inletAirConfiguration,"ZoneAirOnly") ) {
      if( auto thermalZone = modelObject.thermalZone() ) {
        auto inletNode = modelObject.inletNode();
        OS_ASSERT(inletNode);
        airInletNodeName = inletNode->name().get();

        auto outletNode = modelObject.outletNode();
        OS_ASSERT(outletNode);
        airOutletNodeName = outletNode->name().get();
        
        inletAirZoneName = thermalZone->name().get();
        fanInletNodeName = airInletNodeName;
        fanOutletNodeName = modelObject.name().get() + " Fan Outlet - Evap Inlet";
        evapInletNodeName = fanOutletNodeName;
        evapOutletNodeName = airOutletNodeName;
      }
    } else if( istringEqual(inletAirConfiguration,"ZoneAndOutdoorAir") ) {
      if( auto thermalZone = modelObject.thermalZone() ) {
        auto inletNode = modelObject.inletNode();
        OS_ASSERT(inletNode);
        airInletNodeName = inletNode->name().get();

        auto outletNode = modelObject.outletNode();
        OS_ASSERT(outletNode);
        airOutletNodeName = outletNode->name().get();

        outdoorAirNodeName = modelObject.name().get() + " Outdoor Air";
        exhaustAirNodeName = modelObject.name().get() + " Exhaust Air";
        inletAirZoneName = thermalZone->name().get();
        inletAirMixerNodeName = modelObject.name().get() + " Mixer Outlet - Fan Inlet";
        outletAirSplitterNodeName = modelObject.name().get() + " Evap Outlet - Splitter Inlet";
        fanInletNodeName = inletAirMixerNodeName;
        fanOutletNodeName = modelObject.name().get() + " Fan Outlet - Evap Inlet";
        evapInletNodeName = fanOutletNodeName;
        evapOutletNodeName = outletAirSplitterNodeName;
      }
    } else if( istringEqual(inletAirConfiguration,"OutdoorAirOnly") ) {
      outdoorAirNodeName = modelObject.name().get() + " Outdoor Air";
      exhaustAirNodeName = modelObject.name().get() + " Exhaust Air";
      fanInletNodeName = outdoorAirNodeName;
      fanOutletNodeName = modelObject.name().get() + " Fan Outlet - Evap Inlet";
      evapInletNodeName = fanOutletNodeName;
      evapOutletNodeName = exhaustAirNodeName;
    } else if( istringEqual(inletAirConfiguration,"Schedule") ) {
      airInletNodeName = modelObject.name().get() + " Inlet";
      airOutletNodeName = modelObject.name().get() + " Outlet";
      fanInletNodeName = airInletNodeName;
      fanOutletNodeName = modelObject.name().get() + " Fan Outlet - Evap Inlet";
      evapInletNodeName = fanOutletNodeName;
      evapOutletNodeName = airOutletNodeName;
    }

  }

  {
    auto mo = modelObject.tank();
    if( auto idf = translateAndMapModelObject(mo) ) {
      idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::TankName,idf->name().get());
      idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::TankObjectType,idf->iddObject().name());
      if( mo.iddObjectType() == model::WaterHeaterMixed::iddObjectType() ) {
        idf->setString(WaterHeater_MixedFields::SourceSideOutletNodeName,tankOutletCondInletNodeName);
        idf->setString(WaterHeater_MixedFields::SourceSideInletNodeName,condOutletTankInletNodeName);
        auto waterHeaterMixed = mo.cast<model::WaterHeaterMixed>();
        if( auto node = waterHeaterMixed.supplyInletModelObject() ) {
          idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::TankUseSideInletNodeName,node->name().get());
        }
        if( auto node = waterHeaterMixed.supplyOutletModelObject() ) {
          idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::TankUseSideOutletNodeName,node->name().get());
        }
      } else if( mo.iddObjectType() == model::WaterHeaterStratified::iddObjectType() ) {
        idf->setString(WaterHeater_StratifiedFields::SourceSideOutletNodeName,tankOutletCondInletNodeName);
        idf->setString(WaterHeater_StratifiedFields::SourceSideInletNodeName,condOutletTankInletNodeName);
        auto waterHeaterStratified = mo.cast<model::WaterHeaterStratified>();
        if( auto node = waterHeaterStratified.supplyInletModelObject() ) {
          idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::TankUseSideInletNodeName,node->name().get());
        }
        if( auto node = waterHeaterStratified.supplyOutletModelObject() ) {
          idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::TankUseSideOutletNodeName,node->name().get());
        }
      } else {
        LOG(Error, modelObject.briefDescription() << " is attached to an unsupported type of tank: " << mo.briefDescription() );
      }
    }
  }

  {
    auto mo = modelObject.dXCoil();
    if( auto idf = translateAndMapModelObject(mo) ) {
      idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::DXCoilName,idf->name().get());
      idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::DXCoilObjectType,idf->iddObject().name());
      if( mo.iddObjectType() == model::CoilWaterHeatingAirToWaterHeatPump::iddObjectType() ) {
        idf->setString(Coil_WaterHeating_AirToWaterHeatPump_PumpedFields::CondenserWaterInletNodeName,tankOutletCondInletNodeName);
        idf->setString(Coil_WaterHeating_AirToWaterHeatPump_PumpedFields::CondenserWaterOutletNodeName,condOutletTankInletNodeName);
        idf->setString(Coil_WaterHeating_AirToWaterHeatPump_PumpedFields::EvaporatorAirInletNodeName,evapInletNodeName);
        idf->setString(Coil_WaterHeating_AirToWaterHeatPump_PumpedFields::EvaporatorAirOutletNodeName,evapOutletNodeName);
      } else {
        LOG(Error, modelObject.briefDescription() << " is attached to an unsupported type of coil: " << mo.briefDescription() );
      }
    }
  }

  {
    auto mo = modelObject.fan();
    if( auto idf = translateAndMapModelObject(mo) ) {
      idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::FanName,idf->name().get());
      idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::FanObjectType,idf->iddObject().name());
      if( mo.iddObjectType() == model::FanOnOff::iddObjectType() ) {
        idf->setString(Fan_OnOffFields::AirInletNodeName,fanInletNodeName);
        idf->setString(Fan_OnOffFields::AirOutletNodeName,fanOutletNodeName);
      } else {
        LOG(Error, modelObject.briefDescription() << " is attached to an unsupported type of fan: " << mo.briefDescription() );
      }
    }
  }

  idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::AirInletNodeName,airInletNodeName);
  idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::AirOutletNodeName,airOutletNodeName);
  idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::OutdoorAirNodeName,outdoorAirNodeName);
  idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::ExhaustAirNodeName,exhaustAirNodeName);
  idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::InletAirZoneName,inletAirZoneName);
  idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::InletAirMixerNodeName,inletAirMixerNodeName);
  idfObject.setString(WaterHeater_HeatPump_PumpedCondenserFields::OutletAirSplitterNodeName,outletAirSplitterNodeName);

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateCoilCoolingDXTwoSpeedWithoutUnitary( model::CoilCoolingDXTwoSpeed & modelObject )
{
  //setup two boost optionals to use to store get method returns
  boost::optional<std::string> s;
  boost::optional<double> d;

  //create the IdfObject that will be the coil
  IdfObject idfObject(IddObjectType::Coil_Cooling_DX_TwoSpeed);

  //Name
  m_idfObjects.push_back(idfObject);
  s = modelObject.name();
  if( s )
  {
    idfObject.setName(*s);
  }

  //  A2 , \field Availability Schedule Name
  Schedule sched = modelObject.getAvailabilitySchedule();
  translateAndMapModelObject(sched);
  idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::AvailabilityScheduleName,
                      sched.name().get() );

  //  N1 , \field Rated High Speed Total Cooling Capacity
  d = modelObject.getRatedHighSpeedTotalCoolingCapacity();
  if( d )
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::RatedHighSpeedTotalCoolingCapacity,*d);
  }
  else
  {
    idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::RatedHighSpeedTotalCoolingCapacity,"Autosize");
  }

  //  N2 , \field Rated High Speed Sensible Heat Ratio
  d = modelObject.getRatedHighSpeedSensibleHeatRatio();
  if( d )
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::RatedHighSpeedSensibleHeatRatio,*d);
  }
  else
  {
    idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::RatedHighSpeedSensibleHeatRatio,"Autosize");
  }

  //  N3 , \field Rated High Speed COP
  d = modelObject.getRatedHighSpeedCOP();
  if( d )
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::RatedHighSpeedCOP,*d);
  }

  //  N4 , \field Rated High Speed Air Flow Rate
  d = modelObject.getRatedHighSpeedAirFlowRate();
  if( d )
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::RatedHighSpeedAirFlowRate,*d);
  }
  else
  {
    idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::RatedHighSpeedAirFlowRate,"Autosize");
  }

  //A3 , \field Air Inlet Node Name
  OptionalModelObject omo = modelObject.inletModelObject();
  if( omo )
  {
    translateAndMapModelObject(*omo);
    s = omo->name();
    if(s)
    {
      idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::AirInletNodeName,*s );
    }
  }

  //A4 , \field Air Outlet Node Name
  omo= modelObject.outletModelObject();
  if( omo )
  {
    translateAndMapModelObject(*omo);
    s = omo->name();
    if(s)
    {
      idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::AirOutletNodeName,*s);
    }
  }

  //  A5 , \field Total Cooling Capacity Function of Temperature Curve Name
  Curve cb =  modelObject.getTotalCoolingCapacityFunctionOfTemperatureCurve();
  translateAndMapModelObject(cb);
  idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::TotalCoolingCapacityFunctionofTemperatureCurveName,
                     cb.name().get());

  //  A6 , \field Total Cooling Capacity Function of Flow Fraction Curve Name
  cb =  modelObject.getTotalCoolingCapacityFunctionOfFlowFractionCurve();
  translateAndMapModelObject(cb);
  idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::TotalCoolingCapacityFunctionofFlowFractionCurveName,
                     cb.name().get());

  //  A7 , \field Energy Input Ratio Function of Temperature Curve Name
  cb =modelObject.getEnergyInputRatioFunctionOfTemperatureCurve();
  translateAndMapModelObject(cb);
  idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::EnergyInputRatioFunctionofTemperatureCurveName,
                      cb.name().get());

  //  A8 , \field Energy Input Ratio Function of Flow Fraction Curve Name
  Curve cq = modelObject.getEnergyInputRatioFunctionOfFlowFractionCurve();
  translateAndMapModelObject(cq);
  idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::EnergyInputRatioFunctionofFlowFractionCurveName,
                      cq.name().get());

  //  A9 , \field Part Load Fraction Correlation Curve Name
  cq = modelObject.getPartLoadFractionCorrelationCurve();
  translateAndMapModelObject(cq);
  idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::PartLoadFractionCorrelationCurveName,
                      cq.name().get());

  //  N5 , \field Rated Low Speed Total Cooling Capacity
  d = modelObject.getRatedLowSpeedTotalCoolingCapacity();
  if( d )
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::RatedLowSpeedTotalCoolingCapacity,*d);
  }
  else
  {
    idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::RatedLowSpeedTotalCoolingCapacity,"Autosize");
  }

  //  N6 , \field Rated Low Speed Sensible Heat Ratio
  d = modelObject.getRatedLowSpeedSensibleHeatRatio();
  if( d )
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::RatedLowSpeedSensibleHeatRatio,*d);
  }
  else
  {
    idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::RatedLowSpeedSensibleHeatRatio,"Autosize");
  }

  //  N7 , \field Rated Low Speed COP
  d = modelObject.getRatedLowSpeedCOP();
  if( d )
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::RatedLowSpeedCOP,*d);
  }

  //  N8 , \field Rated Low Speed Air Flow Rate
  d = modelObject.getRatedLowSpeedAirFlowRate();
  if( d )
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::RatedLowSpeedAirFlowRate,*d);
  }
  else
  {
    idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::RatedLowSpeedAirFlowRate,"Autosize");
  }

  //  A10, \field Low Speed Total Cooling Capacity Function of Temperature Curve Name
  cq = modelObject.getLowSpeedTotalCoolingCapacityFunctionOfTemperatureCurve();
  translateAndMapModelObject(cq);
  idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::LowSpeedTotalCoolingCapacityFunctionofTemperatureCurveName,
                      cq.name().get());

  //  A11, \field Low Speed Energy Input Ratio Function of Temperature Curve Name
  cq = modelObject.getLowSpeedEnergyInputRatioFunctionOfTemperatureCurve();
  translateAndMapModelObject(cq);
  idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::LowSpeedEnergyInputRatioFunctionofTemperatureCurveName,
                      cq.name().get());

  //  A12, \field Condenser Air Inlet Node Name
  s=modelObject.getCondenserAirInletNodeName();
  if(s)
  {
    idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::CondenserAirInletNodeName,*s);
  }

  //  A13, \field Condenser Type
  idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::CondenserType,modelObject.getCondenserType());

  //   N9, \field High Speed Evaporative Condenser Effectiveness
  d=modelObject.getHighSpeedEvaporativeCondenserEffectiveness();
  if(d)
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::HighSpeedEvaporativeCondenserEffectiveness,*d);
  }

  //  N10, \field High Speed Evaporative Condenser Air Flow Rate
  d=modelObject.getHighSpeedEvaporativeCondenserAirFlowRate();
  if(d)
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::HighSpeedEvaporativeCondenserAirFlowRate,*d);
  }

  //  N11, \field High Speed Evaporative Condenser Pump Rated Power Consumption
  d=modelObject.getHighSpeedEvaporativeCondenserPumpRatedPowerConsumption();
  if(d)
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::HighSpeedEvaporativeCondenserPumpRatedPowerConsumption,*d);
  }

  //  N12, \field Low Speed Evaporative Condenser Effectiveness
  d=modelObject.getLowSpeedEvaporativeCondenserEffectiveness();
  if(d)
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::LowSpeedEvaporativeCondenserEffectiveness,*d);
  }

  //  N13, \field Low Speed Evaporative Condenser Air Flow Rate
  d=modelObject.getLowSpeedEvaporativeCondenserAirFlowRate();
  if(d)
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::LowSpeedEvaporativeCondenserAirFlowRate,*d);
  }

  //  N14, \field Low Speed Evaporative Condenser Pump Rated Power Consumption
  d=modelObject.getLowSpeedEvaporativeCondenserPumpRatedPowerConsumption();
  if(d)
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::LowSpeedEvaporativeCondenserPumpRatedPowerConsumption,*d);
  }

  //TODO
  //  A14, \field Supply Water Storage Tank Name
  //getSupplyWaterStorageTankName

  //TODO
  //  A15, \field Condensate Collection Water Storage Tank Name
  //getCondensateCollectionWaterStorageTankName

  //  N15, \field Basin Heater Capacity
  d=modelObject.getBasinHeaterCapacity();
  if(d)
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::BasinHeaterCapacity,*d);
  }

  //  N16, \field Basin Heater Setpoint Temperature
  d=modelObject.getBasinHeaterSetpointTemperature();
  if(d)
  {
    idfObject.setDouble(Coil_Cooling_DX_TwoSpeedFields::BasinHeaterSetpointTemperature,*d);
  }

  //  A16; \field Basin Heater Operating Schedule Name
  OptionalSchedule os = modelObject.getBasinHeaterOperatingSchedule();
  if( os )
  {
    translateAndMapModelObject(*os);
    idfObject.setString(Coil_Cooling_DX_TwoSpeedFields::BasinHeaterOperatingScheduleName,
                        os->name().get() );
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translatePumpConstantSpeed( 
    PumpConstantSpeed& modelObject)
{
  boost::optional<std::string> s;
  boost::optional<double> value;
  OptionalSchedule schedule;

  IdfObject idfObject(IddObjectType::Pump_ConstantSpeed);

  m_idfObjects.push_back(idfObject);

  // Name

  s = modelObject.name();
  if( s )
  {
    idfObject.setName(*s);
  }

  // InletNodeName

  if( boost::optional<ModelObject> mo = modelObject.inletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(Pump_ConstantSpeedFields::InletNodeName,node->name().get());
    }
  }

  // OutletNodeName

  if( boost::optional<ModelObject> mo = modelObject.outletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(Pump_ConstantSpeedFields::OutletNodeName,node->name().get());
    }
  }

  // RatedFlowRate

  if( modelObject.isRatedFlowRateAutosized() )
  {
    idfObject.setString(Pump_ConstantSpeedFields::RatedFlowRate,"Autosize");
  }
  else if( (value = modelObject.ratedFlowRate()) )
  {
    idfObject.setDouble(Pump_ConstantSpeedFields::RatedFlowRate,value.get());
  }

  // RatedPumpHead

  if( (value = modelObject.ratedPumpHead()) )
  {
    idfObject.setDouble(Pump_ConstantSpeedFields::RatedPumpHead,value.get());
  }

  // RatedPowerConsumption

  if( modelObject.isRatedPowerConsumptionAutosized() )
  {
    idfObject.setString(Pump_ConstantSpeedFields::RatedPowerConsumption,"Autosize");
  }
  else if( (value = modelObject.ratedPowerConsumption()) )
  {
    idfObject.setDouble(Pump_ConstantSpeedFields::RatedPowerConsumption,value.get());
  }

  // MotorEfficiency

  if( (value = modelObject.motorEfficiency()) )
  {
    idfObject.setDouble(Pump_ConstantSpeedFields::MotorEfficiency,value.get());
  }

  // FractionofMotorInefficienciestoFluidStream  

  if( (value = modelObject.fractionofMotorInefficienciestoFluidStream()) )
  {
    idfObject.setDouble(Pump_ConstantSpeedFields::FractionofMotorInefficienciestoFluidStream,value.get());
  } 

  // PumpControlType

  if( (s = modelObject.pumpControlType()) )
  {
    idfObject.setString(Pump_ConstantSpeedFields::PumpControlType,s.get());
  }

  // PumpFlowRateSchedule

  if ((schedule = modelObject.pumpFlowRateSchedule())) {
    idfObject.setString(Pump_ConstantSpeedFields::PumpFlowRateScheduleName,schedule->name().get());
  }

  // PumpCurve

  if (OptionalCurve curve = modelObject.pumpCurve()) {
    idfObject.setString(Pump_ConstantSpeedFields::PumpCurveName,curve->name().get());
  }

  // ImpellerDiameter

  if ((value = modelObject.impellerDiameter())) {
    idfObject.setDouble(Pump_ConstantSpeedFields::ImpellerDiameter,value.get());
  }

  // SkinLossRadiativeFraction

  if ((value = modelObject.skinLossRadiativeFraction())) {
    idfObject.setDouble(Pump_ConstantSpeedFields::SkinLossRadiativeFraction,value.get());
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateTableMultiVariableLookup( TableMultiVariableLookup& modelObject )
{
  OptionalString s;
  OptionalDouble d;
  OptionalModelObject temp;
  OptionalInt n;  

  // Create a new IddObjectType::Table_MultiVariableLookup
  IdfObject idfObject(IddObjectType::Table_MultiVariableLookup);

  m_idfObjects.push_back(idfObject);

  // Name
  s = modelObject.name();
  if(s)
  {
    idfObject.setName(*s);
  }

  // InterpolationMethod
  if( (s = modelObject.interpolationMethod()) )
  {
    idfObject.setString(Table_MultiVariableLookupFields::InterpolationMethod,s.get());
  }

  // NumberofInterpolationPoints
  if( (n = modelObject.numberofInterpolationPoints()) )
  {
    idfObject.setInt(Table_MultiVariableLookupFields::NumberofInterpolationPoints,n.get());
  }

  // CurveType
  if( (s = modelObject.curveType()) )
  {
    idfObject.setString(Table_MultiVariableLookupFields::CurveType,s.get());
  }
  
  // TableDataFormat
  if( (s = modelObject.tableDataFormat()) )
  {
    idfObject.setString(Table_MultiVariableLookupFields::TableDataFormat,s.get());
  }

  // ExternalFileName
  // Not supported
  
  // X1SortOrder
  idfObject.setString(Table_MultiVariableLookupFields::X1SortOrder,"Ascending");
  
  // X2SortOrder
  idfObject.setString(Table_MultiVariableLookupFields::X2SortOrder,"Ascending");
  
  // NormalizationReference
  if( (d = modelObject.normalizationReference()) )
  {
    idfObject.setDouble(Table_MultiVariableLookupFields::NormalizationReference,d.get());
  }
  
  // MinimumValueofX1
  if( (d = modelObject.minimumValueofX1()) )
  {
    idfObject.setDouble(Table_MultiVariableLookupFields::MinimumValueofX1,d.get());
  }
  
  // MaximumValueofX1
  if( (d = modelObject.maximumValueofX1()) )
  {
    idfObject.setDouble(Table_MultiVariableLookupFields::MaximumValueofX1,d.get());
  }
  
  // MinimumValueofX2
  if( (d = modelObject.minimumValueofX2()) )
  {
    idfObject.setDouble(Table_MultiVariableLookupFields::MinimumValueofX2,d.get());
  }
  
  // MaximumValueofX2
  if( (d = modelObject.maximumValueofX2()) )
  {
    idfObject.setDouble(Table_MultiVariableLookupFields::MaximumValueofX2,d.get());
  }
  
  // MinimumValueofX3
  if( (d = modelObject.minimumValueofX3()) )
  {
    idfObject.setDouble(Table_MultiVariableLookupFields::MinimumValueofX3,d.get());
  }
  
  // MaximumValueofX3
  if( (d = modelObject.maximumValueofX3()) )
  {
    idfObject.setDouble(Table_MultiVariableLookupFields::MaximumValueofX3,d.get());
  }
  
  // MinimumValueofX4
  if( (d = modelObject.minimumValueofX4()) )
  {
    idfObject.setDouble(Table_MultiVariableLookupFields::MinimumValueofX4,d.get());
  }
  
  // MaximumValueofX4
  if( (d = modelObject.maximumValueofX4()) )
  {
    idfObject.setDouble(Table_MultiVariableLookupFields::MaximumValueofX4,d.get());
  }
  
  // MinimumValueofX5
  if( (d = modelObject.minimumValueofX5()) )
  {
    idfObject.setDouble(Table_MultiVariableLookupFields::MinimumValueofX5,d.get());
  }
  
  // MaximumValueofX5
  if( (d = modelObject.maximumValueofX5()) )
  {
    idfObject.setDouble(Table_MultiVariableLookupFields::MaximumValueofX5,d.get());
  }
  
  // MinimumTableOutput
  if( (d = modelObject.minimumTableOutput()) )
  {
    idfObject.setDouble(Table_MultiVariableLookupFields::MinimumTableOutput,d.get());
  }
  
  // MaximumTableOutput
  if( (d = modelObject.maximumTableOutput()) )
  {
    idfObject.setDouble(Table_MultiVariableLookupFields::MaximumTableOutput,d.get());
  }
  
  // InputUnitTypeforX1
  if( (s = modelObject.inputUnitTypeforX1()) )
  {
    idfObject.setString(Table_MultiVariableLookupFields::InputUnitTypeforX1,s.get());
  }
  
  // InputUnitTypeforX2
  if( (s = modelObject.inputUnitTypeforX2()) )
  {
    idfObject.setString(Table_MultiVariableLookupFields::InputUnitTypeforX2,s.get());
  }
  
  // InputUnitTypeforX3
  if( (s = modelObject.inputUnitTypeforX3()) )
  {
    idfObject.setString(Table_MultiVariableLookupFields::InputUnitTypeforX3,s.get());
  }
  
  // InputUnitTypeforX4
  if( (s = modelObject.inputUnitTypeforX4()) )
  {
    idfObject.setString(Table_MultiVariableLookupFields::InputUnitTypeforX4,s.get());
  }
  
  // InputUnitTypeforX5
  if( (s = modelObject.inputUnitTypeforX5()) )
  {
    idfObject.setString(Table_MultiVariableLookupFields::InputUnitTypeforX5,s.get());
  }
  
  // OutputUnitType
  if( (s = modelObject.outputUnitType()) )
  {
    idfObject.setString(Table_MultiVariableLookupFields::OutputUnitType,s.get());
  }
  
  // NumberofIndependentVariables
  if( (n = modelObject.numberofIndependentVariables()) )
  {
    idfObject.setInt(Table_MultiVariableLookupFields::NumberofIndependentVariables,n.get());
  }
  
  unsigned t_numNonextensibleFields = idfObject.numNonextensibleFields();
  unsigned t_currentFieldIndex = t_numNonextensibleFields;
  unsigned t_numberofIndependentVariables = modelObject.numberofIndependentVariables();

  // Set the number of xValues for each independent variable
  for(unsigned i = 0; i != t_numberofIndependentVariables; ++i)
  {
    unsigned xValueCount = modelObject.getImpl<model::detail::TableMultiVariableLookup_Impl>()->xValues(i).size();
    idfObject.setUnsigned(t_currentFieldIndex,xValueCount);
    ++t_currentFieldIndex;
  }

  // Set the xValues for each independent variable
  for(unsigned i = 0; i != t_numberofIndependentVariables; ++i)
  {
    std::vector<double> xValues = modelObject.getImpl<model::detail::TableMultiVariableLookup_Impl>()->xValues(i);
    for(auto it = xValues.begin();
        it != xValues.end();
        ++it)
    {
      idfObject.setDouble(t_currentFieldIndex,*it);
      ++t_currentFieldIndex;
    }
  }

  // Set the table data
  if(t_numberofIndependentVariables == 1u)
  {
    // If there is just one variable then we just make a list of the y values.
    std::vector<double> xValues = modelObject.getImpl<model::detail::TableMultiVariableLookup_Impl>()->xValues(0);

    for(auto it = xValues.begin();
        it != xValues.end();
        ++it)
    {
      std::vector<double> coord(1);
      coord[0] = *it;

      boost::optional<double> yValue = modelObject.getImpl<model::detail::TableMultiVariableLookup_Impl>()->yValue(coord);
      if(yValue)
      {
        idfObject.setDouble(t_currentFieldIndex,yValue.get());
      }
      else
      {
        idfObject.setString(t_currentFieldIndex,"");
      }
      ++t_currentFieldIndex;
    }
  }
  else if(t_numberofIndependentVariables == 2u)
  {
    // If there are two variables we make a list of the y values corresponding to x1 and x2,
    // iterating over x2 in the outer layer
    std::vector<double> x1Values = modelObject.getImpl<model::detail::TableMultiVariableLookup_Impl>()->xValues(0);
    std::vector<double> x2Values = modelObject.getImpl<model::detail::TableMultiVariableLookup_Impl>()->xValues(1);

    for(auto it2 = x2Values.begin();
        it2 != x2Values.end();
        ++it2)
    {
      for(auto it1 = x1Values.begin();
          it1 != x1Values.end();
          ++it1)
      {
        std::vector<double> coord(2);
        coord[0] = *it1;
        coord[1] = *it2;

        boost::optional<double> yValue = modelObject.yValue(coord);
        if(yValue)
        {
          idfObject.setDouble(t_currentFieldIndex,yValue.get());
        }
        else
        {
          idfObject.setString(t_currentFieldIndex,"");
        }
        ++t_currentFieldIndex;
      }
    }
  }
  else
  {
    std::vector<std::pair<std::vector<double>,double> > points = modelObject.points();

    // Slice the first and second x values off the coordinates
    std::vector<std::vector<double> > slices;
    for(std::vector<std::pair<std::vector<double>,double> >::const_iterator it = points.begin();
        it != points.end();
        ++it)
    {
      OS_ASSERT(it->first.size() == t_numberofIndependentVariables);
      std::vector<double> slice(it->first.begin() + 2,it->first.begin() + t_numberofIndependentVariables);
      slices.push_back(slice);
    }

    // Remove duplicate slices
    std::sort(slices.begin(),slices.end());
    slices.erase(std::unique(slices.begin(),slices.end()),slices.end());

    // Iterate over each slice that is left, creating a 2D table for each one 
    for(std::vector<std::vector<double> >::const_iterator it = slices.begin();
        it != slices.end();
        ++it)
    {
      for(auto it2 = it->begin();
          it2 != it->end();
          ++it2)
      {
        idfObject.setDouble(t_currentFieldIndex,*it2);
        ++t_currentFieldIndex; 
      }

      std::vector<double> x1Values = modelObject.getImpl<model::detail::TableMultiVariableLookup_Impl>()->xValues(0);
      std::vector<double> x2Values = modelObject.getImpl<model::detail::TableMultiVariableLookup_Impl>()->xValues(1);

      for(auto x2It = x2Values.begin();
          x2It != x2Values.end();
          ++x2It)
      {
        for(auto x1It = x1Values.begin();
            x1It != x1Values.end();
            ++x1It)
        {
          std::vector<double> coord(2);
          coord[0] = *x1It;
          coord[1] = *x2It;
          coord.insert(coord.end(),it->begin(),it->end());

          boost::optional<double> yValue = modelObject.yValue(coord);
          if(yValue)
          {
            idfObject.setDouble(t_currentFieldIndex,yValue.get());
          }
          else
          {
            idfObject.setString(t_currentFieldIndex,"");
          }
          ++t_currentFieldIndex;
        }
      }
    }
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateAirLoopHVACOutdoorAirSystem( AirLoopHVACOutdoorAirSystem & modelObject )
{
  OptionalString s;
  IdfObject idfObject(IddObjectType::AirLoopHVAC_OutdoorAirSystem);

  m_idfObjects.push_back(idfObject);

  // Name
  std::string name = modelObject.name().get();
  idfObject.setString(openstudio::AirLoopHVAC_OutdoorAirSystemFields::Name,name);
 

  // Controller List
  IdfObject _controllerList(IddObjectType::AirLoopHVAC_ControllerList);
  _controllerList.setName(name + " Controller List");
  _controllerList.clearExtensibleGroups();
  m_idfObjects.push_back(_controllerList);

  ControllerOutdoorAir controllerOutdoorAir = modelObject.getControllerOutdoorAir();
  boost::optional<IdfObject> _controllerOutdoorAir = translateAndMapModelObject(controllerOutdoorAir);
  OS_ASSERT(_controllerOutdoorAir);

  idfObject.setString(openstudio::AirLoopHVAC_OutdoorAirSystemFields::ControllerListName,_controllerList.name().get());

  IdfExtensibleGroup eg = _controllerList.pushExtensibleGroup();
  eg.setString(AirLoopHVAC_ControllerListExtensibleFields::ControllerObjectType,_controllerOutdoorAir->iddObject().name());
  eg.setString(AirLoopHVAC_ControllerListExtensibleFields::ControllerName,_controllerOutdoorAir->name().get());

  std::vector<ModelObject> controllers;
  auto components = modelObject.components();
  for( const auto & component : components ) {
    boost::optional<ControllerWaterCoil> controller;

    if( auto coil = component.optionalCast<CoilCoolingWater>() ) {
      controller = coil->controllerWaterCoil();
    } else if ( auto coil = component.optionalCast<CoilHeatingWater>() ) {
      controller = coil->controllerWaterCoil();
    }

    if( controller ) {
      controllers.push_back(controller.get());
    }
  } 
  
  for( auto & controller: controllers ) {
    auto _controller = translateAndMapModelObject(controller);
    if( _controller ) {
      IdfExtensibleGroup eg = _controllerList.pushExtensibleGroup();
      eg.setString(AirLoopHVAC_ControllerListExtensibleFields::ControllerObjectType,_controller->iddObject().name());
      eg.setString(AirLoopHVAC_ControllerListExtensibleFields::ControllerName,_controller->name().get());
    }
  }

  // Field: Availability Manager List Name //////////////////////////////////
  IdfObject availabilityManagerListIdf(IddObjectType::AvailabilityManagerAssignmentList);
  availabilityManagerListIdf.setName(name + " Availability Manager List");
  m_idfObjects.push_back(availabilityManagerListIdf);

  IdfObject availabilityManagerScheduledIdf = IdfObject(openstudio::IddObjectType::AvailabilityManager_Scheduled);
  availabilityManagerScheduledIdf.setName(name + " Availability Manager");
  m_idfObjects.push_back(availabilityManagerScheduledIdf);

  Schedule alwaysOn = modelObject.model().alwaysOnDiscreteSchedule();
  IdfObject alwaysOnIdf = translateAndMapModelObject(alwaysOn).get();

  s = availabilityManagerListIdf.getString(openstudio::AvailabilityManagerAssignmentListFields::Name);
  if(s)
  {
    idfObject.setString(openstudio::AirLoopHVAC_OutdoorAirSystemFields::AvailabilityManagerListName,*s);
  }

  availabilityManagerListIdf.setString(1 + openstudio::AvailabilityManagerAssignmentListExtensibleFields::AvailabilityManagerObjectType,
                                       availabilityManagerScheduledIdf.iddObject().name());
  availabilityManagerListIdf.setString(1 + openstudio::AvailabilityManagerAssignmentListExtensibleFields::AvailabilityManagerName,
                                       availabilityManagerScheduledIdf.name().get());
  availabilityManagerScheduledIdf.setString(openstudio::AvailabilityManager_ScheduledFields::ScheduleName,alwaysOnIdf.name().get());

  // OA Node List
  s = modelObject.outboardOANode()->name();
  IdfObject oaNodeListIdf(openstudio::IddObjectType::OutdoorAir_NodeList);
  if(s)
  {
    oaNodeListIdf.setString(0,*s);
  }
  m_idfObjects.push_back(oaNodeListIdf);

  ///////////////////////////////////////////////////////////////////////////
  // Field: Outdoor Air Equipment List Name /////////////////////////////////
  IdfObject equipmentListIdf(IddObjectType::AirLoopHVAC_OutdoorAirSystem_EquipmentList);
  equipmentListIdf.setName(name + " Equipment List");

  m_idfObjects.push_back(equipmentListIdf);

  IdfObject outdoorAirMixerIdf(IddObjectType::OutdoorAir_Mixer);
  outdoorAirMixerIdf.setName(name + " Outdoor Air Mixer");
  m_idfObjects.push_back(outdoorAirMixerIdf);

  s = modelObject.mixedAirModelObject()->name();
  if(s)
  {
    outdoorAirMixerIdf.setString(OutdoorAir_MixerFields::MixedAirNodeName,*s);
  }
  s = modelObject.outdoorAirModelObject()->name();
  if(s)
  {
    outdoorAirMixerIdf.setString(OutdoorAir_MixerFields::OutdoorAirStreamNodeName,*s);
  }

  s = modelObject.reliefAirModelObject()->name();
  if(s)
  {
    outdoorAirMixerIdf.setString(OutdoorAir_MixerFields::ReliefAirStreamNodeName,*s);
  }

  s = modelObject.returnAirModelObject()->name();
  if(s)
  {
    outdoorAirMixerIdf.setString(OutdoorAir_MixerFields::ReturnAirStreamNodeName,*s);
  }

  s = outdoorAirMixerIdf.iddObject().name();
  equipmentListIdf.setString(1,*s);
  s = outdoorAirMixerIdf.name();
  equipmentListIdf.setString(2,*s);

  unsigned i = 3;
  ModelObjectVector oaModelObjects = modelObject.oaComponents();
  for( ModelObjectVector::iterator oaIt = oaModelObjects.begin();
       oaIt != oaModelObjects.end();
       ++oaIt )
  {
    if( ! oaIt->optionalCast<Node>() )
    {
      if( boost::optional<IdfObject> idfObject = translateAndMapModelObject(*oaIt) )
      {
        equipmentListIdf.setString(i,idfObject->iddObject().name());
        i++;
        equipmentListIdf.setString(i,idfObject->name().get());
        i++;
      }
    }
  }

  ModelObjectVector reliefModelObjects = modelObject.reliefComponents();
  for( ModelObjectVector::iterator reliefIt = reliefModelObjects.begin();
       reliefIt != reliefModelObjects.end();
       ++reliefIt )
  {
    if( (! reliefIt->optionalCast<Node>()) && (! reliefIt->optionalCast<AirToAirComponent>()) )
    {
      if( boost::optional<IdfObject> idfObject = translateAndMapModelObject(*reliefIt) )
      {
        equipmentListIdf.setString(i,idfObject->iddObject().name());
        i++;
        equipmentListIdf.setString(i,idfObject->name().get());
        i++;
      }
    }
  }

  s = equipmentListIdf.name();
  if(s)
  {
    idfObject.setString(openstudio::AirLoopHVAC_OutdoorAirSystemFields::OutdoorAirEquipmentListName,*s);
  }

  return boost::optional<IdfObject>(idfObject);
}
boost::optional<IdfObject> ForwardTranslator::translateAirConditionerVariableRefrigerantFlow( AirConditionerVariableRefrigerantFlow & modelObject )
{
  boost::optional<std::string> s;
  boost::optional<double> value;

  IdfObject idfObject(IddObjectType::AirConditioner_VariableRefrigerantFlow);

  m_idfObjects.push_back(idfObject);

  // Name

  s = modelObject.name();
  if( s )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatPumpName,*s);
  }

  // AvailabilityScheduleName

  if( boost::optional<model::Schedule> schedule = modelObject.availabilitySchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::AvailabilityScheduleName,_schedule->name().get());
    }
  }

  // RatedTotalCoolingCapacity

  if( modelObject.isRatedTotalCoolingCapacityAutosized() )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::GrossRatedTotalCoolingCapacity,"Autosize");
  }
  else if( (value = modelObject.ratedTotalCoolingCapacity()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::GrossRatedTotalCoolingCapacity,value.get());
  }

  // RatedCoolingCOP

  if( (value = modelObject.ratedCoolingCOP()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::GrossRatedCoolingCOP,value.get());
  }

  // MinimumOutdoorTemperatureinCoolingMode

  if( (value = modelObject.minimumOutdoorTemperatureinCoolingMode()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::MinimumOutdoorTemperatureinCoolingMode,value.get());
  }

  // MaximumOutdoorTemperatureinCoolingMode

  if( (value = modelObject.maximumOutdoorTemperatureinCoolingMode()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::MaximumOutdoorTemperatureinCoolingMode,value.get());
  }


  // CoolingCapacityRatioModifierFunctionofLowTemperatureCurveName

  if( boost::optional<model::CurveBiquadratic> curve = modelObject.coolingCapacityRatioModifierFunctionofLowTemperatureCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CoolingCapacityRatioModifierFunctionofLowTemperatureCurveName,_curve->name().get());
    } 
  }
  
  // CoolingCapacityRatioBoundaryCurveName

  if( boost::optional<model::CurveCubic> curve = modelObject.coolingCapacityRatioBoundaryCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CoolingCapacityRatioBoundaryCurveName,_curve->name().get());
    }
  }

  // CoolingCapacityRatioModifierFunctionofHighTemperatureCurveName
  
  if( boost::optional<model::CurveBiquadratic> curve = modelObject.coolingCapacityRatioModifierFunctionofHighTemperatureCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CoolingCapacityRatioModifierFunctionofHighTemperatureCurveName,_curve->name().get());
    }
  }
  
  // CoolingEnergyInputRatioModifierFunctionofLowTemperatureCurveName

  if( boost::optional<model::CurveBiquadratic> curve = modelObject.coolingEnergyInputRatioModifierFunctionofLowTemperatureCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CoolingEnergyInputRatioModifierFunctionofLowTemperatureCurveName,_curve->name().get());
    }
  }

  // CoolingEnergyInputRatioBoundaryCurveName

  if( boost::optional<model::CurveCubic> curve = modelObject.coolingEnergyInputRatioBoundaryCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CoolingEnergyInputRatioBoundaryCurveName,_curve->name().get());
    }
  }

  // CoolingEnergyInputRatioModifierFunctionofHighTemperatureCurveName

  if( boost::optional<model::CurveBiquadratic> curve = modelObject.coolingEnergyInputRatioModifierFunctionofHighTemperatureCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CoolingEnergyInputRatioModifierFunctionofHighTemperatureCurveName,_curve->name().get());
    }
  }

  // CoolingEnergyInputRatioModifierFunctionofLowPartLoadRatioCurveName

  if( boost::optional<model::CurveCubic> curve = modelObject.coolingEnergyInputRatioModifierFunctionofLowPartLoadRatioCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CoolingEnergyInputRatioModifierFunctionofLowPartLoadRatioCurveName,_curve->name().get());
    }
  }

  // CoolingEnergyInputRatioModifierFunctionofHighPartLoadRatioCurveName
  
  if( boost::optional<model::CurveCubic> curve = modelObject.coolingEnergyInputRatioModifierFunctionofHighPartLoadRatioCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CoolingEnergyInputRatioModifierFunctionofHighPartLoadRatioCurveName,_curve->name().get());
    }
  }
  
  // CoolingCombinationRatioCorrectionFactorCurveName
  
  if( boost::optional<model::CurveCubic> curve = modelObject.coolingCombinationRatioCorrectionFactorCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CoolingCombinationRatioCorrectionFactorCurveName,_curve->name().get());
    }
  }

  // CoolingPartLoadFractionCorrelationCurveName
  
  if( boost::optional<model::CurveCubic> curve = modelObject.coolingPartLoadFractionCorrelationCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CoolingPartLoadFractionCorrelationCurveName,_curve->name().get());
    }
  }  

  // RatedTotalHeatingCapacity
  
  if( modelObject.isRatedTotalHeatingCapacityAutosized() )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::GrossRatedHeatingCapacity,"Autosize");
  }
  else if( (value = modelObject.ratedTotalHeatingCapacity()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::GrossRatedHeatingCapacity,value.get());
  }

  // RatedTotalHeatingCapacitySizingRatio

  if( (value = modelObject.ratedTotalHeatingCapacitySizingRatio()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::RatedHeatingCapacitySizingRatio,value.get());
  }
  
  // RatedHeatingCOP

  if( (value = modelObject.ratedHeatingCOP()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::GrossRatedHeatingCOP,value.get());
  }
  
  // MinimumOutdoorTemperatureinHeatingMode
  
  if( (value = modelObject.minimumOutdoorTemperatureinHeatingMode()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::MinimumOutdoorTemperatureinHeatingMode,value.get());
  }
  
  // MaximumOutdoorTemperatureinHeatingMode
  
  if( (value = modelObject.maximumOutdoorTemperatureinHeatingMode()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::MaximumOutdoorTemperatureinHeatingMode,value.get());
  }

  // HeatingCapacityRatioModifierFunctionofLowTemperatureCurveName

  if( boost::optional<model::CurveBiquadratic> curve = modelObject.heatingCapacityRatioModifierFunctionofLowTemperatureCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatingCapacityRatioModifierFunctionofLowTemperatureCurveName,_curve->name().get());
    }
  }
  
  // HeatingCapacityRatioBoundaryCurveName

  if( boost::optional<model::CurveCubic> curve = modelObject.heatingCapacityRatioBoundaryCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatingCapacityRatioBoundaryCurveName,_curve->name().get());
    }
  }
  
  // HeatingCapacityRatioModifierFunctionofHighTemperatureCurveName
  
  if( boost::optional<model::CurveBiquadratic> curve = modelObject.heatingCapacityRatioModifierFunctionofHighTemperatureCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatingCapacityRatioModifierFunctionofHighTemperatureCurveName,_curve->name().get());
    }
  }

  // HeatingEnergyInputRatioModifierFunctionofLowTemperatureCurveName
  
  if( boost::optional<model::CurveBiquadratic> curve = modelObject.heatingEnergyInputRatioModifierFunctionofLowTemperatureCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatingEnergyInputRatioModifierFunctionofLowTemperatureCurveName,_curve->name().get());
    }
  }

  // HeatingEnergyInputRatioBoundaryCurveName

  if( boost::optional<model::CurveCubic> curve = modelObject.heatingEnergyInputRatioBoundaryCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatingEnergyInputRatioBoundaryCurveName,_curve->name().get());
    }
  }  

  // HeatingEnergyInputRatioModifierFunctionofHighTemperatureCurveName
  
  if( boost::optional<model::CurveBiquadratic> curve = modelObject.heatingEnergyInputRatioModifierFunctionofHighTemperatureCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatingEnergyInputRatioModifierFunctionofHighTemperatureCurveName,_curve->name().get());
    }
  }

  // HeatingPerformanceCurveOutdoorTemperatureType

  if( (s = modelObject.heatingPerformanceCurveOutdoorTemperatureType()) )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatingPerformanceCurveOutdoorTemperatureType,s.get());
  }

  // HeatingEnergyInputRatioModifierFunctionofLowPartLoadRatioCurveName

  if( boost::optional<model::CurveCubic> curve = modelObject.heatingEnergyInputRatioModifierFunctionofLowPartLoadRatioCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatingEnergyInputRatioModifierFunctionofLowPartLoadRatioCurveName,_curve->name().get());
    }
  }

  // HeatingEnergyInputRatioModifierFunctionofHighPartLoadRatioCurveName
  
  if( boost::optional<model::CurveCubic> curve = modelObject.heatingEnergyInputRatioModifierFunctionofHighPartLoadRatioCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatingEnergyInputRatioModifierFunctionofHighPartLoadRatioCurveName,_curve->name().get());
    }
  }

  // HeatingCombinationRatioCorrectionFactorCurveName
  
  if( boost::optional<model::CurveCubic> curve = modelObject.heatingCombinationRatioCorrectionFactorCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatingCombinationRatioCorrectionFactorCurveName,_curve->name().get());
    }
  }

  // HeatingPartLoadFractionCorrelationCurveName

  if( boost::optional<model::CurveCubic> curve = modelObject.heatingPartLoadFractionCorrelationCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatingPartLoadFractionCorrelationCurveName,_curve->name().get());
    }
  }

  // MinimumHeatPumpPartLoadRatio

  if( (value = modelObject.minimumHeatPumpPartLoadRatio()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::MinimumHeatPumpPartLoadRatio,value.get());
  }

  // ZoneNameforMasterThermostatLocation

  if( boost::optional<model::ThermalZone> zone = modelObject.zoneforMasterThermostatLocation() )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::ZoneNameforMasterThermostatLocation,zone->name().get());
  }

  // MasterThermostatPriorityControlType

  if( (s = modelObject.masterThermostatPriorityControlType()) )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::MasterThermostatPriorityControlType,s.get());
  }

  // ThermostatPriorityScheduleName
  
  if( boost::optional<model::Schedule> schedule = modelObject.thermostatPrioritySchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::ThermostatPriorityScheduleName,_schedule->name().get());
    }
  }

  // HeatPumpWasteHeatRecovery
  
  if( modelObject.heatPumpWasteHeatRecovery() )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatPumpWasteHeatRecovery,"Yes");
  }
  else
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatPumpWasteHeatRecovery,"No");
  }
  
  // EquivalentPipingLengthusedforPipingCorrectionFactorinCoolingMode
  
  if( (value = modelObject.equivalentPipingLengthusedforPipingCorrectionFactorinCoolingMode()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::EquivalentPipingLengthusedforPipingCorrectionFactorinCoolingMode,value.get());
  }

  // VerticalHeightusedforPipingCorrectionFactor

  if( (value = modelObject.verticalHeightusedforPipingCorrectionFactor()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::VerticalHeightusedforPipingCorrectionFactor,value.get());
  }
  
  // PipingCorrectionFactorforLengthinCoolingModeCurveName
  
  if( boost::optional<model::CurveBiquadratic> curve = modelObject.pipingCorrectionFactorforLengthinCoolingModeCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::PipingCorrectionFactorforLengthinCoolingModeCurveName,_curve->name().get());
    }
  }

  // PipingCorrectionFactorforHeightinCoolingModeCoefficient
  
  if( (value = modelObject.pipingCorrectionFactorforHeightinCoolingModeCoefficient()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::PipingCorrectionFactorforHeightinCoolingModeCoefficient,value.get()); 
  }

  // EquivalentPipingLengthusedforPipingCorrectionFactorinHeatingMode
  
  if( (value = modelObject.equivalentPipingLengthusedforPipingCorrectionFactorinHeatingMode()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::EquivalentPipingLengthusedforPipingCorrectionFactorinHeatingMode,value.get());
  }
  
  // PipingCorrectionFactorforLengthinHeatingModeCurveName
  
  if( boost::optional<model::CurveBiquadratic> curve = modelObject.pipingCorrectionFactorforLengthinHeatingModeCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::PipingCorrectionFactorforLengthinHeatingModeCurveName,_curve->name().get());
    }
  }

  // PipingCorrectionFactorforHeightinHeatingModeCoefficient
  
  if( (value = modelObject.pipingCorrectionFactorforHeightinHeatingModeCoefficient()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::PipingCorrectionFactorforHeightinHeatingModeCoefficient,value.get());
  }

  // CrankcaseHeaterPowerperCompressor

  if( (value = modelObject.crankcaseHeaterPowerperCompressor()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::CrankcaseHeaterPowerperCompressor,value.get());
  }
  
  // NumberofCompressors
  
  {
    int number = modelObject.numberofCompressors();

    idfObject.setUnsigned(AirConditioner_VariableRefrigerantFlowFields::NumberofCompressors,(unsigned)number);
  }
  
  // RatioofCompressorSizetoTotalCompressorCapacity
  
  if( (value = modelObject.ratioofCompressorSizetoTotalCompressorCapacity()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::RatioofCompressorSizetoTotalCompressorCapacity,value.get());
  }
  
  // MaximumOutdoorDrybulbTemperatureforCrankcaseHeater
  
  if( (value = modelObject.maximumOutdoorDrybulbTemperatureforCrankcaseHeater()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::MaximumOutdoorDryBulbTemperatureforCrankcaseHeater,value.get());
  }

  // DefrostStrategy

  if( (s = modelObject.defrostStrategy()) )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::DefrostStrategy,s.get());
  }
  
  // DefrostControl
  
  if( (s = modelObject.defrostControl()) )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::DefrostControl,s.get());
  }
  
  // DefrostEnergyInputRatioModifierFunctionofTemperatureCurveName
  
  if( boost::optional<model::CurveBiquadratic> curve = modelObject.defrostEnergyInputRatioModifierFunctionofTemperatureCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::DefrostEnergyInputRatioModifierFunctionofTemperatureCurveName,_curve->name().get());
    }
  }

  // DefrostTimePeriodFraction

  if( (value = modelObject.defrostTimePeriodFraction()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::DefrostTimePeriodFraction,value.get());
  }

  // ResistiveDefrostHeaterCapacity

  if( modelObject.isResistiveDefrostHeaterCapacityAutosized() )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::ResistiveDefrostHeaterCapacity,"Autosize");
  }
  else if( (value = modelObject.resistiveDefrostHeaterCapacity()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::ResistiveDefrostHeaterCapacity,value.get());
  }

  // MaximumOutdoorDrybulbTemperatureforDefrostOperation
  
  if( (value = modelObject.maximumOutdoorDrybulbTemperatureforDefrostOperation()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::MaximumOutdoorDrybulbTemperatureforDefrostOperation,value.get());
  }
  
  // CondenserInletNodeName

  if( boost::optional<model::ModelObject> mo = modelObject.inletModelObject() )
  {
    if( boost::optional<IdfObject> _mo = translateAndMapModelObject(mo.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CondenserInletNodeName,_mo->name().get());
    }
  }
  
  // CondenserOutletNodeName

  if( boost::optional<model::ModelObject> mo = modelObject.outletModelObject() )
  {
    if( boost::optional<IdfObject> _mo = translateAndMapModelObject(mo.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CondenserOutletNodeName,_mo->name().get());
    }
  }
  
  // WaterCondenserVolumeFlowRate
  
  if( modelObject.isWaterCondenserVolumeFlowRateAutosized() )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::WaterCondenserVolumeFlowRate,"Autosize");
  }
  else if( (value = modelObject.waterCondenserVolumeFlowRate()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::WaterCondenserVolumeFlowRate,value.get());
  }

  // EvaporativeCondenserEffectiveness

  if( (value = modelObject.evaporativeCondenserEffectiveness()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::EvaporativeCondenserEffectiveness,value.get());
  }

  // EvaporativeCondenserAirFlowRate

  if( modelObject.isEvaporativeCondenserAirFlowRateAutosized() )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::EvaporativeCondenserAirFlowRate,"Autosize");
  }
  else if( (value = modelObject.evaporativeCondenserAirFlowRate()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::EvaporativeCondenserAirFlowRate,value.get());
  }

  // EvaporativeCondenserPumpRatedPowerConsumption
  
  if( modelObject.isEvaporativeCondenserPumpRatedPowerConsumptionAutosized() )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::EvaporativeCondenserPumpRatedPowerConsumption,"Autosize");
  }
  else if( ( value = modelObject.evaporativeCondenserPumpRatedPowerConsumption()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::EvaporativeCondenserPumpRatedPowerConsumption,value.get());
  }

  // BasinHeaterCapacity
  
  if( (value = modelObject.basinHeaterCapacity()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::BasinHeaterCapacity,value.get());
  }
  
  // BasinHeaterSetpointTemperature

  if( (value = modelObject.basinHeaterSetpointTemperature()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::BasinHeaterSetpointTemperature,value.get());
  }

  // BasinHeaterOperatingScheduleName

  if( boost::optional<model::Schedule> schedule = modelObject.basinHeaterOperatingSchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::BasinHeaterOperatingScheduleName,_schedule->name().get());
    }
  }

  // FuelType

  if( (s = modelObject.fuelType()) )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::FuelType,s.get());
  }

  // MinimumOutdoorTemperatureinHeatRecoveryMode
  
  if( (value = modelObject.minimumOutdoorTemperatureinHeatRecoveryMode()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::MinimumOutdoorTemperatureinHeatRecoveryMode,value.get());
  }

  // MaximumOutdoorTemperatureinHeatRecoveryMode
  
  if( (value = modelObject.maximumOutdoorTemperatureinHeatingMode()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::MaximumOutdoorTemperatureinHeatRecoveryMode,value.get());
  }

  // HeatRecoveryCoolingCapacityModifierCurveName
  
  if( boost::optional<model::CurveBiquadratic> curve = modelObject.heatRecoveryCoolingCapacityModifierCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryCoolingCapacityModifierCurveName,_curve->name().get());
    }
  }

  // InitialHeatRecoveryCoolingCapacityFraction
  
  if( (value = modelObject.initialHeatRecoveryCoolingEnergyFraction()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::InitialHeatRecoveryCoolingCapacityFraction,value.get());
  }

  // HeatRecoveryCoolingCapacityTimeConstant
  
  if( (value = modelObject.heatRecoveryCoolingCapacityTimeConstant()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryCoolingCapacityTimeConstant,value.get());
  }

  // HeatRecoveryCoolingEnergyModifierCurveName
  
  if( boost::optional<model::CurveBiquadratic> curve = modelObject.heatRecoveryCoolingEnergyModifierCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryCoolingEnergyModifierCurveName,_curve->name().get());
    }
  }

  // InitialHeatRecoveryCoolingEnergyFraction

  if( (value = modelObject.initialHeatRecoveryCoolingEnergyFraction()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::InitialHeatRecoveryCoolingEnergyFraction,value.get());
  }

  // HeatRecoveryCoolingEnergyTimeConstant

  if( (value = modelObject.heatRecoveryCoolingEnergyTimeConstant()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryCoolingEnergyTimeConstant,value.get());
  }  

  // HeatRecoveryHeatingCapacityModifierCurveName
  
  if( boost::optional<model::CurveBiquadratic> curve = modelObject.heatRecoveryHeatingCapacityModifierCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryHeatingCapacityModifierCurveName,_curve->name().get());
    }
  }

  // InitialHeatRecoveryHeatingCapacityFraction
  
  if( (value = modelObject.initialHeatRecoveryHeatingCapacityFraction()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::InitialHeatRecoveryHeatingCapacityFraction,value.get());
  }

  // HeatRecoveryHeatingCapacityTimeConstant

  if( (value = modelObject.heatRecoveryHeatingCapacityTimeConstant()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryHeatingCapacityTimeConstant,value.get());
  }

  // HeatRecoveryHeatingEnergyModifierCurveName
  
  if( boost::optional<model::CurveBiquadratic> curve = modelObject.heatRecoveryHeatingEnergyModifierCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryHeatingEnergyModifierCurveName,_curve->name().get());
    }
  }

  // InitialHeatRecoveryHeatingEnergyFraction

  if( (value = modelObject.initialHeatRecoveryHeatingEnergyFraction()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::InitialHeatRecoveryHeatingEnergyFraction,value.get());
  }

  // HeatRecoveryHeatingEnergyTimeConstant

  if( (value = modelObject.heatRecoveryHeatingEnergyTimeConstant()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryHeatingEnergyTimeConstant,value.get());
  }

  // Terminal Unit List
  
  IdfObject _zoneTerminalUnitList(IddObjectType::ZoneTerminalUnitList);

  std::string terminalUnitListName = modelObject.name().get() + " Terminal List";

  _zoneTerminalUnitList.setString(ZoneTerminalUnitListFields::ZoneTerminalUnitListName,terminalUnitListName);

  idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::ZoneTerminalUnitListName,terminalUnitListName);

  m_idfObjects.push_back(_zoneTerminalUnitList);

  std::vector<ZoneHVACTerminalUnitVariableRefrigerantFlow> terminals = modelObject.terminals();

  for( auto & terminal : terminals )
  {
    boost::optional<IdfObject> _terminal = translateAndMapModelObject(terminal);

    OS_ASSERT(_terminal);
     
    IdfExtensibleGroup eg = _zoneTerminalUnitList.pushExtensibleGroup();

    eg.setString(ZoneTerminalUnitListExtensibleFields::ZoneTerminalUnitName,_terminal->name().get());
  }

  // CondenserType

  if( modelObject.plantLoop() )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CondenserType,"WaterCooled");
  }
  else
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CondenserType,"AirCooled");
  }  

  // CondenserInletNodeName

  OptionalModelObject omo = modelObject.inletModelObject();
  if( omo )
  {
    translateAndMapModelObject(*omo);
    s = omo->name();
    if(s)
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CondenserInletNodeName,*s );
    }
  }

  // CondenserOutletNodeName

  omo = modelObject.outletModelObject();
  if( omo )
  {
    translateAndMapModelObject(*omo);
    s = omo->name();
    if(s)
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::CondenserOutletNodeName,*s );
    }
  }

  // WaterCondenserVolumeFlowRate

  if( modelObject.isWaterCondenserVolumeFlowRateAutosized() )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::WaterCondenserVolumeFlowRate,"Autosize");
  }
  else if( (value = modelObject.waterCondenserVolumeFlowRate()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::WaterCondenserVolumeFlowRate,value.get()); 
  }

  // EvaporativeCondenserEffectiveness

  if( (value = modelObject.evaporativeCondenserEffectiveness()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::EvaporativeCondenserEffectiveness,value.get());
  }

  // EvaporativeCondenserAirFlowRate

  if( modelObject.isEvaporativeCondenserAirFlowRateAutosized() )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::EvaporativeCondenserAirFlowRate,"Autosize");
  }
  else if( (value = modelObject.evaporativeCondenserAirFlowRate()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::EvaporativeCondenserAirFlowRate,value.get());
  }

  // EvaporativeCondenserPumpRatedPowerConsumption

  if( modelObject.isEvaporativeCondenserPumpRatedPowerConsumptionAutosized() )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::EvaporativeCondenserPumpRatedPowerConsumption,"Autosize");
  }
  else if( (value = modelObject.evaporativeCondenserPumpRatedPowerConsumption()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::EvaporativeCondenserPumpRatedPowerConsumption,value.get());
  }

  // BasinHeaterCapacity

  if( (value = modelObject.basinHeaterCapacity()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::BasinHeaterCapacity,value.get());
  }

  // BasinHeaterSetpointTemperature

  if( (value = modelObject.basinHeaterSetpointTemperature()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::BasinHeaterSetpointTemperature,value.get());
  } 

  // BasinHeaterOperatingScheduleName

  if( boost::optional<model::Schedule> schedule = modelObject.basinHeaterOperatingSchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::BasinHeaterOperatingScheduleName,_schedule->name().get());
    }
  }

  // FuelType
  
  if( (s = modelObject.fuelType()) )
  {
    idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::FuelType,s.get());
  }

  // MinimumOutdoorTemperatureinHeatRecoveryMode

  if( (value = modelObject.minimumOutdoorTemperatureinHeatRecoveryMode()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::MinimumOutdoorTemperatureinHeatRecoveryMode,value.get());
  }

  // MaximumOutdoorTemperatureinHeatRecoveryMode

  if( (value = modelObject.maximumOutdoorTemperatureinHeatRecoveryMode()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::MaximumOutdoorTemperatureinHeatRecoveryMode,value.get());
  }

  // HeatRecoveryCoolingCapacityModifierCurveName

  if( boost::optional<model::CurveBiquadratic> curve = modelObject.heatRecoveryCoolingCapacityModifierCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryCoolingCapacityModifierCurveName,_curve->name().get());
    } 
  }

  // InitialHeatRecoveryCoolingCapacityFraction

  if( (value = modelObject.initialHeatRecoveryCoolingCapacityFraction()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::InitialHeatRecoveryCoolingCapacityFraction,value.get());
  }

  // HeatRecoveryCoolingCapacityTimeConstant

  if( (value = modelObject.heatRecoveryCoolingEnergyTimeConstant()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryCoolingCapacityTimeConstant,value.get());
  }

  // HeatRecoveryCoolingEnergyModifierCurveName

  if( boost::optional<model::CurveBiquadratic> curve = modelObject.heatRecoveryCoolingEnergyModifierCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryCoolingEnergyModifierCurveName,_curve->name().get());
    } 
  }

  // InitialHeatRecoveryCoolingEnergyFraction
  
  if( (value = modelObject.initialHeatRecoveryCoolingEnergyFraction()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::InitialHeatRecoveryCoolingEnergyFraction,value.get());
  }

  // HeatRecoveryCoolingEnergyTimeConstant
  
  if( (value = modelObject.heatRecoveryCoolingEnergyTimeConstant()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryCoolingEnergyTimeConstant,value.get());
  }

  // HeatRecoveryHeatingCapacityModifierCurveName

  if( boost::optional<model::CurveBiquadratic> curve = modelObject.heatRecoveryHeatingCapacityModifierCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryHeatingCapacityModifierCurveName,_curve->name().get());
    } 
  }
  
  // InitialHeatRecoveryHeatingCapacityFraction

  if( (value = modelObject.initialHeatRecoveryHeatingCapacityFraction()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::InitialHeatRecoveryHeatingCapacityFraction,value.get());
  }
  
  // HeatRecoveryHeatingCapacityTimeConstant

  if( (value = modelObject.heatRecoveryHeatingCapacityTimeConstant()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryHeatingCapacityTimeConstant,value.get());
  }
  
  // HeatRecoveryHeatingEnergyModifierCurveName
  
  if( boost::optional<model::CurveBiquadratic> curve = modelObject.heatRecoveryHeatingEnergyModifierCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryHeatingEnergyModifierCurveName,_curve->name().get());
    } 
  }

  // InitialHeatRecoveryHeatingEnergyFraction
  
  if( (value = modelObject.initialHeatRecoveryHeatingEnergyFraction()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::InitialHeatRecoveryHeatingEnergyFraction,value.get());
  } 

  // HeatRecoveryHeatingEnergyTimeConstant

  if( (value = modelObject.heatRecoveryHeatingEnergyTimeConstant()) )
  {
    idfObject.setDouble(AirConditioner_VariableRefrigerantFlowFields::HeatRecoveryHeatingEnergyTimeConstant,value.get());
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateZoneHVACLowTempRadiantConstFlow(ZoneHVACLowTempRadiantConstFlow& modelObject)
{
  boost::optional<std::string> s;
  boost::optional<double> value;
  boost::optional<ModelObject> temp;

  IdfObject idfObject(IddObjectType::ZoneHVAC_LowTemperatureRadiant_ConstantFlow);
  m_idfObjects.push_back(idfObject);

  //Name
  std::string baseName = modelObject.name().get();
  idfObject.setName(baseName);

  // AvailabilityScheduleName
  if( boost::optional<Schedule> schedule = modelObject.availabilitySchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::AvailabilityScheduleName,_schedule->name().get());
    }
  }
  
  //field Zone Name
  boost::optional<std::string> thermalZoneName;
  if( boost::optional<ThermalZone> zone = modelObject.thermalZone() )
  {
    if( (s = zone->name()) )
    {
      thermalZoneName = s;

      idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::ZoneName,thermalZoneName.get());
    }
  }
 
  //field Surface Name or Radiant Surface Type

  //create a new surface group object
  IdfObject _surfaceGroup(IddObjectType::ZoneHVAC_LowTemperatureRadiant_SurfaceGroup);

  //create a name for the surface group
  std::string sname = baseName + "" + modelObject.radiantSurfaceType().get();
  _surfaceGroup.setName(sname);
  
  //attach the surface group to the zone low temp radiant object
  idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::SurfaceNameorRadiantSurfaceGroupName,sname);

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

  //loop through all surfaces, adding up their area
  for (const Surface& surface : modelObject.surfaces()){
    totalAreaOfSurfaces = totalAreaOfSurfaces + surface.grossArea();
  }

  //loop through all the surfaces, adding them and their flow fractions (weighted per-area)
  for (const Surface& surface : modelObject.surfaces()){
    IdfExtensibleGroup group = _surfaceGroup.pushExtensibleGroup();
    OS_ASSERT(group.numFields() == 2);
    group.setString(0, surface.name().get());        
    group.setDouble(1, (surface.grossArea()/totalAreaOfSurfaces) );     
  }
 
  //add the surface group to the list of idf objects
  m_idfObjects.push_back(_surfaceGroup);

 //field Hydronic Tubing Inside Diameter
 if( (value = modelObject.hydronicTubingInsideDiameter()) )
  {
    idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::HydronicTubingInsideDiameter,value.get());
  }

  //field Hydronic Tubing Length
 if( (value = modelObject.hydronicTubingLength()) )
  {
    idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::HydronicTubingLength,value.get());
  }

  //field Temperature Control Type
 if(boost::optional<std::string> tempCtrlType= modelObject.temperatureControlType() )
  {
    idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::TemperatureControlType,tempCtrlType.get());
  }

  //field Rated Flow Rate
  if( (value = modelObject.ratedFlowRate()) )
  {
    idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::RatedFlowRate,value.get());
  }

  //field Pump Flow Rate Schedule Name
  if( boost::optional<Schedule> schedule = modelObject.pumpFlowRateSchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::PumpFlowRateScheduleName,_schedule->name().get());
    }
  }

  //field Rated Pump Head
  if( (value = modelObject.ratedPumpHead()) )
  {
    idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::RatedPumpHead,value.get());
  }

  //field Rated Power Consumption
  if( (value = modelObject.ratedPowerConsumption()) )
  {
    idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::RatedPowerConsumption,value.get());
  }

  //field Motor Efficiency
  if( (value = modelObject.motorEfficiency()) )
  {
    idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::MotorEfficiency,value.get());
  }

  //field Fraction of Motor Inefficiencies to Fluid Stream
  if( (value = modelObject.fractionofMotorInefficienciestoFluidStream()) )
  {
    idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::FractionofMotorInefficienciestoFluidStream,value.get());
  }

  HVACComponent heatingCoil = modelObject.heatingCoil();
  boost::optional<CoilHeatingLowTempRadiantConstFlow>  coilOptionalHeating = heatingCoil.optionalCast<CoilHeatingLowTempRadiantConstFlow>();

  // field Heating Water Inlet Node Name 
  if (coilOptionalHeating){
    CoilHeatingLowTempRadiantConstFlow coilHeat = *coilOptionalHeating;

    temp = coilHeat.inletModelObject();
    if(temp)
    {
      s = temp->name();
      if(s)
      {
        idfObject.setString(openstudio::ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::HeatingWaterInletNodeName,*s);
      }
    }

    //field Heating Water Outlet Node Name 
    temp = coilHeat.outletModelObject();
    if(temp)
    {
      s = temp->name();
      if(s)
      {
        idfObject.setString(openstudio::ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::HeatingWaterOutletNodeName,*s);
      }
    }
  
    //field Heating High Water Temperature Schedule Name
    if( boost::optional<Schedule> schedule = coilHeat.heatingHighWaterTemperatureSchedule() )
    {
      if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
      {
        idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::HeatingHighWaterTemperatureScheduleName,_schedule->name().get());
      }
    }

    //field Heating Low Water Temperature Schedule Name
    if( boost::optional<Schedule> schedule = coilHeat.heatingLowWaterTemperatureSchedule() )
    {
      if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
      {
        idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::HeatingLowWaterTemperatureScheduleName,_schedule->name().get());
      }
    }

    //field Heating High Control Temperature Schedule Name
    if( boost::optional<Schedule> schedule = coilHeat.heatingHighControlTemperatureSchedule() )
    {
      if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
      {
        idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::HeatingHighControlTemperatureScheduleName,_schedule->name().get());
      }
    }

    //field Heating Low Control Temperature Schedule Name    
    if( boost::optional<Schedule> schedule = coilHeat.heatingLowControlTemperatureSchedule() )
    {
      if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
      {
        idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::HeatingLowControlTemperatureScheduleName,_schedule->name().get());
      }
    }
  }

  HVACComponent coolingCoil = modelObject.coolingCoil();
  boost::optional<CoilCoolingLowTempRadiantConstFlow>  coilOptionalCooling = coolingCoil.optionalCast<CoilCoolingLowTempRadiantConstFlow>();

  // field Cooling Water Inlet Node Name 
  if (coilOptionalCooling){
    CoilCoolingLowTempRadiantConstFlow coilCool = *coilOptionalCooling;

    temp = coilCool.inletModelObject();
    if(temp)
    {
      s = temp->name();
      if(s)
      {
        idfObject.setString(openstudio::ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::CoolingWaterInletNodeName,*s);
      }
    }

    //field Cooling Water Outlet Node Name 
    temp = coilCool.outletModelObject();
    if(temp)
    {
      s = temp->name();
      if(s)
      {
        idfObject.setString(openstudio::ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::CoolingWaterOutletNodeName,*s);
      }
    }

    //field Cooling High Water Temperature Schedule Name
    if( boost::optional<Schedule> schedule = coilCool.coolingHighWaterTemperatureSchedule() )
    {
      if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
      {
        idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::CoolingHighWaterTemperatureScheduleName,_schedule->name().get());
      }
    }

    //field Cooling Low Water Temperature Schedule Name
    if( boost::optional<Schedule> schedule = coilCool.coolingLowWaterTemperatureSchedule() )
    {
      if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
      {
        idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::CoolingLowWaterTemperatureScheduleName,_schedule->name().get());
      }
    }

    //field Cooling High Control Temperature Schedule Name
    if( boost::optional<Schedule> schedule = coilCool.coolingHighControlTemperatureSchedule() )
    {
      if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
      {
        idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::CoolingHighControlTemperatureScheduleName,_schedule->name().get());
      }
    }

    //field Cooling Low Control Temperature Schedule Name
    if( boost::optional<Schedule> schedule = coilCool.coolingLowControlTemperatureSchedule() )
    {
      if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
      {
        idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::CoolingLowControlTemperatureScheduleName,_schedule->name().get());
      }
    }
 
    //field Condensation Control Type
    idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::CondensationControlType,coilCool.condensationControlType());

    //field Condensation Control Dewpoint Offset
    if( (value = coilCool.condensationControlDewpointOffset()) )
    {
      idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::CondensationControlDewpointOffset,value.get());
    }
    
  }
  
  //field Number of Circuits
  idfObject.setString(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::NumberofCircuits,modelObject.numberofCircuits());

  //field Circuit Length
  idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_ConstantFlowFields::CircuitLength,modelObject.circuitLength());

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateControllerWaterCoil( ControllerWaterCoil & modelObject )
{
  boost::optional<std::string> s;
  boost::optional<double> value;

  IdfObject idfObject(IddObjectType::Controller_WaterCoil);

  m_idfObjects.push_back(idfObject);

  // Name

  s = modelObject.name();
  if( s )
  {
    idfObject.setName(*s);
  }

  // ControlVariable

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

  // Action

  if( s = modelObject.action() )
  {
    idfObject.setString(Controller_WaterCoilFields::Action,s.get());
  }

  // ActuatorVariable

  if( s = modelObject.actuatorVariable() )
  {
    idfObject.setString(Controller_WaterCoilFields::ActuatorVariable,s.get());
  }

  // SensorNodeName

  if( boost::optional<Node> node = modelObject.sensorNode() )
  {
    idfObject.setString(Controller_WaterCoilFields::SensorNodeName,node->name().get());
  }

  // ActuatorNodeName

  if( boost::optional<Node> node = modelObject.actuatorNode() )
  {
    idfObject.setString(Controller_WaterCoilFields::ActuatorNodeName,node->name().get());
  }

  // ControllerConvergenceTolerance

  if( modelObject.isControllerConvergenceToleranceAutosized() )
  {
    idfObject.setString(Controller_WaterCoilFields::ControllerConvergenceTolerance,"Autosize");
  }
  else if( value = modelObject.controllerConvergenceTolerance() )
  {
    idfObject.setDouble(Controller_WaterCoilFields::ControllerConvergenceTolerance,value.get());
  }

  // MaximumActuatedFlow

  if( modelObject.isMaximumActuatedFlowAutosized() )
  {
    idfObject.setString(Controller_WaterCoilFields::MaximumActuatedFlow,"Autosize");
  }
  else if( value = modelObject.maximumActuatedFlow() )
  {
    idfObject.setDouble(Controller_WaterCoilFields::MaximumActuatedFlow,value.get());
  }

  // MinimumActuatedFlow

  if( value = modelObject.minimumActuatedFlow() )
  {
    idfObject.setDouble(Controller_WaterCoilFields::MinimumActuatedFlow,value.get());
  }

  return boost::optional<IdfObject>(idfObject);
}
boost::optional<IdfObject> ForwardTranslator::translateCurveTriquadratic(CurveTriquadratic& modelObject)
{
  IdfObject idfObject(IddObjectType::Curve_Triquadratic);

  m_idfObjects.push_back(idfObject);

  OptionalString s;
  OptionalDouble d;

  if((s = modelObject.name())) {
    idfObject.setName(*s);
  }

  if ((d = modelObject.coefficient1Constant())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient1Constant,*d);
  }
  if ((d = modelObject.coefficient2xPOW2())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient2x_POW_2,*d);
  }
  if ((d = modelObject.coefficient3x())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient3x,*d);
  }
  if ((d = modelObject.coefficient4yPOW2())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient4y_POW_2,*d);
  }
  if ((d = modelObject.coefficient5y())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient5y,*d);
  }
  if ((d = modelObject.coefficient6zPOW2())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient6z_POW_2,*d);
  }
  if ((d = modelObject.coefficient7z())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient7z,*d);
  }
  if ((d = modelObject.coefficient8xPOW2TIMESYPOW2())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient8x_POW_2_TIMES_y_POW_2,*d);
  }
  if ((d = modelObject.coefficient9xTIMESY())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient9x_TIMES_y,*d);
  }
  if ((d = modelObject.coefficient10xTIMESYPOW2())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient10x_TIMES_y_POW_2,*d);
  }
  if ((d = modelObject.coefficient11xPOW2TIMESY())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient11x_POW_2_TIMES_y,*d);
  }
  if ((d = modelObject.coefficient12xPOW2TIMESZPOW2())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient12x_POW_2_TIMES_z_POW_2,*d);
  }
  if ((d = modelObject.coefficient13xTIMESZ())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient13x_TIMES_z,*d);
  }
  if ((d = modelObject.coefficient14xTIMESZPOW2())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient14x_TIMES_z_POW_2,*d);
  }
  if ((d = modelObject.coefficient15xPOW2TIMESZ())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient15x_POW_2_TIMES_z,*d);
  }
  if ((d = modelObject.coefficient16yPOW2TIMESZPOW2())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient16y_POW_2_TIMES_z_POW_2,*d);
  }
  if ((d = modelObject.coefficient17yTIMESZ())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient17y_TIMES_z,*d);
  }
  if ((d = modelObject.coefficient18yTIMESZPOW2())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient18y_TIMES_z_POW_2,*d);
  }
  if ((d = modelObject.coefficient19yPOW2TIMESZ())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient19y_POW_2_TIMES_z,*d);
  }
  if ((d = modelObject.coefficient20xPOW2TIMESYPOW2TIMESZPOW2())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient20x_POW_2_TIMES_y_POW_2_TIMES_z_POW_2,*d);
  }
  if ((d = modelObject.coefficient21xPOW2TIMESYPOW2TIMESZ())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient21x_POW_2_TIMES_y_POW_2_TIMES_z,*d);
  }
  if ((d = modelObject.coefficient22xPOW2TIMESYTIMESZPOW2())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient22x_POW_2_TIMES_y_TIMES_z_POW_2,*d);
  }
  if ((d = modelObject.coefficient23xTIMESYPOW2TIMESZPOW2())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient23x_TIMES_y_POW_2_TIMES_z_POW_2,*d);
  }
  if ((d = modelObject.coefficient24xPOW2TIMESYTIMESZ())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient24x_POW_2_TIMES_y_TIMES_z,*d);
  }
  if ((d = modelObject.coefficient25xTIMESYPOW2TIMESZ())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient25x_TIMES_y_POW_2_TIMES_z,*d);
  }
  if ((d = modelObject.coefficient26xTIMESYTIMESZPOW2())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient26x_TIMES_y_TIMES_z_POW_2,*d);
  }
  if ((d = modelObject.coefficient27xTIMESYTIMESZ())) {
    idfObject.setDouble(Curve_TriquadraticFields::Coefficient27x_TIMES_y_TIMES_z,*d);
  }
  if ((d = modelObject.minimumValueofx())) {
    idfObject.setDouble(Curve_TriquadraticFields::MinimumValueofx,*d);
  }
  if ((d = modelObject.maximumValueofx())) {
    idfObject.setDouble(Curve_TriquadraticFields::MaximumValueofx,*d); 
  }
  if ((d = modelObject.minimumValueofy())) {
    idfObject.setDouble(Curve_TriquadraticFields::MinimumValueofy,*d);
  }
  if ((d = modelObject.maximumValueofy())) {
    idfObject.setDouble(Curve_TriquadraticFields::MaximumValueofy,*d);
  }
  if ((d = modelObject.minimumValueofz())) {
    idfObject.setDouble(Curve_TriquadraticFields::MinimumValueofz,*d);
  }
  if ((d = modelObject.maximumValueofz())) {
    idfObject.setDouble(Curve_TriquadraticFields::MaximumValueofz,*d);
  }
  if ((d = modelObject.minimumCurveOutput())) {
    idfObject.setDouble(Curve_TriquadraticFields::MinimumCurveOutput,*d);
  }
  if ((d = modelObject.maximumCurveOutput())) {
    idfObject.setDouble(Curve_TriquadraticFields::MaximumCurveOutput,*d);
  }
  if (!modelObject.isInputUnitTypeforXDefaulted()) {
    idfObject.setString(Curve_TriquadraticFields::InputUnitTypeforX,modelObject.inputUnitTypeforX());
  }
  if (!modelObject.isInputUnitTypeforYDefaulted()) {
    idfObject.setString(Curve_TriquadraticFields::InputUnitTypeforY,modelObject.inputUnitTypeforY());
  }
  if (!modelObject.isInputUnitTypeforZDefaulted()) {
    idfObject.setString(Curve_TriquadraticFields::InputUnitTypeforZ,modelObject.inputUnitTypeforZ());
  }
  if (!modelObject.isOutputUnitTypeDefaulted()) {
    idfObject.setString(Curve_TriquadraticFields::OutputUnitType,modelObject.outputUnitType());
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateStandardGlazing( StandardGlazing & modelObject )
{
  IdfObject idfObject( openstudio::IddObjectType::WindowMaterial_Glazing);

  m_idfObjects.push_back(idfObject);

  idfObject.setString(WindowMaterial_GlazingFields::Name, modelObject.name().get());

  std::string opticalDataType;
  OptionalString s = modelObject.getString(OS_WindowMaterial_GlazingFields::OpticalDataType, false, true);
  if (s){
    opticalDataType = *s;
    idfObject.setString(WindowMaterial_GlazingFields::OpticalDataType, *s);
  }else{
    LOG(Error, "Missing required input 'Optical Data Type' for WindowMaterial:Glazing named '" << modelObject.name().get() << "'");
  }

  if (istringEqual("Spectral", opticalDataType)){
    s = modelObject.getString(OS_WindowMaterial_GlazingFields::WindowGlassSpectralDataSetName, false, true);
    if (s){
      idfObject.setString(WindowMaterial_GlazingFields::WindowGlassSpectralDataSetName, *s);
    }
  }

  OptionalDouble d = modelObject.getDouble(OS_WindowMaterial_GlazingFields::Thickness, false);
  if (d){
    idfObject.setDouble(WindowMaterial_GlazingFields::Thickness, *d);
  }else{
    LOG(Error, "Missing required input 'Thickness' for WindowMaterial:Glazing named '" << modelObject.name().get() << "'");
  }

  if (istringEqual("SpectralAverage", opticalDataType)){
    d = modelObject.getDouble(OS_WindowMaterial_GlazingFields::SolarTransmittanceatNormalIncidence, false);
    if (d){
      idfObject.setDouble(WindowMaterial_GlazingFields::SolarTransmittanceatNormalIncidence, *d);
    }

    d = modelObject.getDouble(OS_WindowMaterial_GlazingFields::FrontSideSolarReflectanceatNormalIncidence, false);
    if (d){
      idfObject.setDouble(WindowMaterial_GlazingFields::FrontSideSolarReflectanceatNormalIncidence, *d);
    }

    d = modelObject.getDouble(OS_WindowMaterial_GlazingFields::BackSideSolarReflectanceatNormalIncidence, false);
    if (d){
      idfObject.setDouble(WindowMaterial_GlazingFields::BackSideSolarReflectanceatNormalIncidence, *d);
    }

    d = modelObject.getDouble(OS_WindowMaterial_GlazingFields::VisibleTransmittanceatNormalIncidence, false);
    if (d){
      idfObject.setDouble(WindowMaterial_GlazingFields::VisibleTransmittanceatNormalIncidence, *d);
    }

    d = modelObject.getDouble(OS_WindowMaterial_GlazingFields::FrontSideVisibleReflectanceatNormalIncidence, false);
    if (d){
      idfObject.setDouble(WindowMaterial_GlazingFields::FrontSideVisibleReflectanceatNormalIncidence, *d);
    }

    d = modelObject.getDouble(OS_WindowMaterial_GlazingFields::BackSideVisibleReflectanceatNormalIncidence, false);
    if (d){
      idfObject.setDouble(WindowMaterial_GlazingFields::BackSideVisibleReflectanceatNormalIncidence, *d);
    }

  }

  d = modelObject.getDouble(OS_WindowMaterial_GlazingFields::InfraredTransmittanceatNormalIncidence, false);
  if (d){
    idfObject.setDouble(WindowMaterial_GlazingFields::InfraredTransmittanceatNormalIncidence, *d);
  }

  d = modelObject.getDouble(OS_WindowMaterial_GlazingFields::FrontSideInfraredHemisphericalEmissivity, false);
  if (d){
    idfObject.setDouble(WindowMaterial_GlazingFields::FrontSideInfraredHemisphericalEmissivity, *d);
  }

  d = modelObject.getDouble(OS_WindowMaterial_GlazingFields::BackSideInfraredHemisphericalEmissivity, false);
  if (d){
    idfObject.setDouble(WindowMaterial_GlazingFields::BackSideInfraredHemisphericalEmissivity, *d);
  }

  d = modelObject.getDouble(OS_WindowMaterial_GlazingFields::Conductivity, false);
  if (d){
    idfObject.setDouble(WindowMaterial_GlazingFields::Conductivity, *d);
  }

  d = modelObject.getDouble(OS_WindowMaterial_GlazingFields::DirtCorrectionFactorforSolarandVisibleTransmittance, false);
  if (d){
    idfObject.setDouble(WindowMaterial_GlazingFields::DirtCorrectionFactorforSolarandVisibleTransmittance, *d);
  }

  s = modelObject.getString(OS_WindowMaterial_GlazingFields::SolarDiffusing, false, true);
  if (s){
    idfObject.setString(WindowMaterial_GlazingFields::SolarDiffusing, *s);
  }

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

  // Create a new IddObjectType::Fan_ConstantVolume
  IdfObject idfObject(IddObjectType::CoolingTower_SingleSpeed);

  m_idfObjects.push_back(idfObject);

  // Name

  s = modelObject.name();
  if(s)
  {
    idfObject.setName(*s);
  }

  // WaterInletNodeName

  temp = modelObject.inletModelObject();
  if(temp)
  {
    idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::WaterInletNodeName,temp->name().get());
  }

  // WaterOutletNodeName

  temp = modelObject.outletModelObject();
  if(temp)
  {
    idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::WaterOutletNodeName,temp->name().get());
  }

  // DesignWaterFlowRate 

  if( istringEqual(modelObject.performanceInputMethod(),"NominalCapacity") )
  {
    idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::DesignWaterFlowRate,"");
  }
  else
  {
    if( (d = modelObject.designWaterFlowRate()) )
    {
      idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::DesignWaterFlowRate,d.get());
    }
    else if( modelObject.isDesignAirFlowRateAutosized() )
    {
      idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::DesignWaterFlowRate,"Autosize");
    }
  }

  // DesignAirFlowRate 

  if( (d = modelObject.designAirFlowRate()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::DesignAirFlowRate,d.get());
  }
  else if( modelObject.isDesignAirFlowRateAutosized() )
  {
    idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::DesignAirFlowRate,"Autosize");
  }

  // FanPoweratDesignAirFlowRate
  
  if( (d = modelObject.fanPoweratDesignAirFlowRate()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::FanPoweratDesignAirFlowRate,d.get());
  }
  else if( modelObject.isFanPoweratDesignAirFlowRateAutosized() )
  {
    idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::FanPoweratDesignAirFlowRate,"Autosize");
  }

  // UFactorTimesAreaValueatDesignAirFlowRate

  if( (d = modelObject.uFactorTimesAreaValueatDesignAirFlowRate()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::UFactorTimesAreaValueatDesignAirFlowRate,d.get());
  }
  else if( modelObject.isUFactorTimesAreaValueatFreeConvectionAirFlowRateAutosized() )
  {
    idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::UFactorTimesAreaValueatDesignAirFlowRate,"Autosize");
  }

  // AirFlowRateinFreeConvectionRegime

  if( (d = modelObject.airFlowRateinFreeConvectionRegime()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::AirFlowRateinFreeConvectionRegime,d.get());
  }
  else if( modelObject.isAirFlowRateinFreeConvectionRegimeAutosized() )
  {
    idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::AirFlowRateinFreeConvectionRegime,"Autosize");
  }

  // UFactorTimesAreaValueatFreeConvectionAirFlowRate

  if( (d = modelObject.uFactorTimesAreaValueatFreeConvectionAirFlowRate()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::UFactorTimesAreaValueatFreeConvectionAirFlowRate,d.get());
  }
  else if( modelObject.isUFactorTimesAreaValueatFreeConvectionAirFlowRateAutosized() )
  {
    idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::UFactorTimesAreaValueatFreeConvectionAirFlowRate,"Autosize");
  }

  // PerformanceInputMethod

  if( (s = modelObject.performanceInputMethod()) )
  {
    idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::PerformanceInputMethod,s.get());
  }

  // NominalCapacity

  if( (d = modelObject.nominalCapacity()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::NominalCapacity,d.get());
  }

  // FreeConvectionCapacity
  
  if( (d = modelObject.freeConvectionCapacity()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::FreeConvectionCapacity,d.get());
  }

  // BasinHeaterCapacity

  if( (d = modelObject.basinHeaterCapacity()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::BasinHeaterCapacity,d.get());
  }

  // BasinHeaterSetpointTemperature

  if( (d = modelObject.basinHeaterSetpointTemperature()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::BasinHeaterSetpointTemperature,d.get());
  }

  // BasinHeaterOperatingSchedule

  if( (temp = modelObject.basinHeaterOperatingSchedule()) )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(temp.get()) )
    {
      idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::BasinHeaterOperatingScheduleName,_schedule->name().get());
    }
  }

  // EvaporationLossMode

  if( (s = modelObject.evaporationLossMode()) )
  {
    idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::EvaporationLossMode,s.get());
  }

  // EvaporationLossFactor

  if( (d = modelObject.evaporationLossFactor()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::EvaporationLossFactor,d.get());
  }

  // DriftLossPercent

  if( (d = modelObject.driftLossPercent()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::DriftLossPercent,d.get());
  }

  // BlowdownCalculationMode

  if( (s = modelObject.blowdownCalculationMode()) )
  {
    idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::BlowdownCalculationMode,s.get());
  }
  
  // BlowdownConcentrationRatio
  
  if( (d = modelObject.blowdownConcentrationRatio()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::BlowdownConcentrationRatio,d.get());
  }

  // BlowdownMakeupWaterUsageScheduleName

  if( (temp = modelObject.blowdownMakeupWaterUsageSchedule()) )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(temp.get()) )
    {
      idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::BlowdownMakeupWaterUsageScheduleName,_schedule->name().get());
    }
  }

  // CapacityControl

  if( (s = modelObject.capacityControl()) )
  {
    idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::CapacityControl,s.get());
  }

  // NumberofCells

  if( int n = modelObject.numberofCells() )
  {
    idfObject.setUnsigned(openstudio::CoolingTower_SingleSpeedFields::NumberofCells,n);
  }

  // CellControl

  if( (s = modelObject.cellControl()) )
  {
    idfObject.setString(openstudio::CoolingTower_SingleSpeedFields::CellControl,s.get());
  }

  // CellMinimumWaterFlowRateFraction

  if( (d = modelObject.cellMinimumWaterFlowRateFraction()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::CellMinimumWaterFlowRateFraction,d.get());
  }

  // CellMaximumWaterFlowRateFraction

  if( (d = modelObject.cellMaximumWaterFlowRateFraction()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::CellMaximumWaterFlowRateFraction,d.get());
  }
  
  // SizingFactor

  if( (d = modelObject.sizingFactor()) )
  {
    idfObject.setDouble(openstudio::CoolingTower_SingleSpeedFields::SizingFactor,d.get());
  } 

  return boost::optional<IdfObject>(idfObject);
}
boost::optional<IdfObject> ForwardTranslator::translateAirLoopHVACUnitaryHeatPumpAirToAir( AirLoopHVACUnitaryHeatPumpAirToAir & modelObject )
{
  boost::optional<std::string> s;
  boost::optional<double> value;

  IdfObject idfObject(IddObjectType::AirLoopHVAC_UnitaryHeatPump_AirToAir);

  m_idfObjects.push_back(idfObject);

  // Name

  s = modelObject.name();
  if( s )
  {
    idfObject.setName(*s);
  }

  // AvailabilityScheduleName

  if( boost::optional<Schedule> schedule = modelObject.availabilitySchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::AvailabilityScheduleName,_schedule->name().get());
    }
  }

  // AirInletNodeName

  boost::optional<std::string> airInletNodeName;

  if( boost::optional<ModelObject> mo = modelObject.inletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      if( s = node->name() )
      {
        airInletNodeName = s;

        idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::AirInletNodeName,s.get());
      }
    }
  }

  // AirOutletNodeName

  boost::optional<std::string> airOutletNodeName;

  if( boost::optional<ModelObject> mo = modelObject.outletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      if( s = node->name() )
      {
        airOutletNodeName = s;

        idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::AirOutletNodeName,s.get());
      }
    }
  }

  // SupplyAirFlowRateDuringCoolingOperation

  if( modelObject.isSupplyAirFlowRateDuringCoolingOperationAutosized() )
  {
    idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::SupplyAirFlowRateDuringCoolingOperation,"Autosize");
  }
  else if( value = modelObject.supplyAirFlowRateDuringCoolingOperation() )
  {
    idfObject.setDouble(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::SupplyAirFlowRateDuringCoolingOperation,value.get());
  }

  // SupplyAirFlowRateDuringHeatingOperation

  if( modelObject.isSupplyAirFlowRateDuringHeatingOperationAutosized() )
  {
    idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::SupplyAirFlowRateDuringHeatingOperation,"Autosize");
  }
  else if( value = modelObject.supplyAirFlowRateDuringHeatingOperation() )
  {
    idfObject.setDouble(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::SupplyAirFlowRateDuringHeatingOperation,value.get());
  }

  // SupplyAirFlowRateWhenNoCoolingorHeatingisNeeded

  if( modelObject.isSupplyAirFlowRateWhenNoCoolingorHeatingisNeededAutosized() )
  {
    idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::SupplyAirFlowRateWhenNoCoolingorHeatingisNeeded,"Autosize");
  }
  else if( value = modelObject.supplyAirFlowRateWhenNoCoolingorHeatingisNeeded() )
  {
    idfObject.setDouble(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::SupplyAirFlowRateWhenNoCoolingorHeatingisNeeded,value.get());
  }

  // ControllingZoneorThermostatLocation

  if( boost::optional<ThermalZone> tz = modelObject.controllingZone() )
  {
    idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::ControllingZoneorThermostatLocation,tz->name().get() );
  }

  // SupplyAirFanName
  
  HVACComponent fan = modelObject.supplyAirFan();

  boost::optional<IdfObject> _fan = translateAndMapModelObject(fan);

  if( _fan )
  {
    idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::SupplyAirFanObjectType,_fan->iddObject().name() );

    idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::SupplyAirFanName,_fan->name().get());
  }

  // HeatingCoilName
  
  boost::optional<IdfObject> _heatingCoil;

  HVACComponent heatingCoil = modelObject.heatingCoil();

  if( boost::optional<CoilHeatingDXSingleSpeed> coilHeatingDXSingleSpeed = heatingCoil.optionalCast<CoilHeatingDXSingleSpeed>() )
  {
    _heatingCoil = translateCoilHeatingDXSingleSpeedWithoutUnitary(coilHeatingDXSingleSpeed.get());

    if( _heatingCoil )
    {
      idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::HeatingCoilObjectType,_heatingCoil->iddObject().name());

      idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::HeatingCoilName,_heatingCoil->name().get());
    }
  }

  // CoolingCoilName

  boost::optional<IdfObject> _coolingCoil;

  boost::optional<CoilCoolingDXSingleSpeed> coolingCoil = modelObject.coolingCoil().optionalCast<CoilCoolingDXSingleSpeed>();

  if( coolingCoil )
  {
    _coolingCoil = translateCoilCoolingDXSingleSpeedWithoutUnitary(coolingCoil.get());
  }

  if( _coolingCoil )
  {
    m_map.insert(std::make_pair(coolingCoil->handle(),_coolingCoil.get()));

    idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::CoolingCoilObjectType,_coolingCoil->iddObject().name());

    idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::CoolingCoilName,_coolingCoil->name().get());
  }

  // SupplementalHeatingCoilName

  boost::optional<IdfObject> _supplementalHeatingCoil;

  boost::optional<HVACComponent> supplementalHeatingCoil = modelObject.supplementalHeatingCoil();

  if( supplementalHeatingCoil )
  {
    _supplementalHeatingCoil = translateAndMapModelObject(supplementalHeatingCoil.get());
  }

  if( _supplementalHeatingCoil )
  {
    idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::SupplementalHeatingCoilObjectType,
      _supplementalHeatingCoil->iddObject().name());

    idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::SupplementalHeatingCoilName,_supplementalHeatingCoil->name().get()); 
  }

  // MaximumSupplyAirTemperaturefromSupplementalHeater

  if( modelObject.isMaximumSupplyAirTemperaturefromSupplementalHeaterAutosized() )
  {
    idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::MaximumSupplyAirTemperaturefromSupplementalHeater,"Autosize");
  }
  else if( value = modelObject.maximumSupplyAirTemperaturefromSupplementalHeater() )
  {
    idfObject.setDouble(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::MaximumSupplyAirTemperaturefromSupplementalHeater,value.get());
  }

  // MaximumOutdoorDryBulbTemperatureforSupplementalHeaterOperation

  if( value = modelObject.maximumOutdoorDryBulbTemperatureforSupplementalHeaterOperation() )
  {
    idfObject.setDouble(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::MaximumOutdoorDryBulbTemperatureforSupplementalHeaterOperation,value.get());
  }

  // FanPlacement

  if( s = modelObject.fanPlacement() )
  {
    idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::FanPlacement,s.get());
  }

  // SupplyAirFanOperatingModeScheduleName

  if( boost::optional<Schedule> schedule = modelObject.supplyAirFanOperatingModeSchedule() )
  {
    boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get());

    if( _schedule )
    {
      idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::SupplyAirFanOperatingModeScheduleName,_schedule->name().get());
    }
  }

  // Dehumidification Control Type
  if (!modelObject.isDehumidificationControlTypeDefaulted()) {
    idfObject.setString(AirLoopHVAC_UnitaryHeatPump_AirToAirFields::DehumidificationControlType,
                        modelObject.dehumidificationControlType());
  }

  // Fill in node names for inner components

  if( airInletNodeName && _fan )
  {
    _fan->setString(Fan_ConstantVolumeFields::AirInletNodeName,airInletNodeName.get());
  }

  //if( airOutletNodeName && _heatingCoil )
  //{
  //  //_heatingCoil->setString(Coil_Heating_DX_SingleSpeedFields::AirOutletNodeName,airOutletNodeName.get());
  //}

  if( _fan && _coolingCoil )
  {
    std::string nodeName = modelObject.name().get() + " Fan - Cooling Coil Node";

    _fan->setString(Fan_ConstantVolumeFields::AirOutletNodeName,nodeName);

    _coolingCoil->setString(Coil_Cooling_DX_SingleSpeedFields::AirInletNodeName,nodeName);
  }

  if( _coolingCoil && _heatingCoil )
  {
    std::string nodeName = modelObject.name().get() + " Cooling Coil - Heating Coil Node";

    _coolingCoil->setString(Coil_Cooling_DX_SingleSpeedFields::AirOutletNodeName,nodeName);

    _heatingCoil->setString(Coil_Heating_DX_SingleSpeedFields::AirInletNodeName,nodeName);
  }

  if( _supplementalHeatingCoil )
  {
    std::string nodeName = modelObject.name().get() + " Heating Coil - Supplemental Coil Node";

    if( _heatingCoil )
    {
      _heatingCoil->setString(Coil_Heating_DX_SingleSpeedFields::AirOutletNodeName,nodeName);
    }

    if( _supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Gas )
    {
      if( airOutletNodeName )
      {
        _supplementalHeatingCoil->setString(Coil_Heating_GasFields::AirOutletNodeName,airOutletNodeName.get()); 

        _supplementalHeatingCoil->setString(Coil_Heating_GasFields::AirInletNodeName,nodeName); 
      }
    }
    else if( _supplementalHeatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Electric )
    {
      if( airOutletNodeName )
      {
        _supplementalHeatingCoil->setString(Coil_Heating_ElectricFields::AirOutletNodeName,airOutletNodeName.get()); 

        _supplementalHeatingCoil->setString(Coil_Heating_ElectricFields::AirInletNodeName,nodeName); 
      }
    }
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateCoilWaterHeatingAirToWaterHeatPump( 
    CoilWaterHeatingAirToWaterHeatPump & modelObject)
{
  IdfObject idfObject(IddObjectType::Coil_WaterHeating_AirToWaterHeatPump);
  m_idfObjects.push_back(idfObject);

  // Name
  if( auto s = modelObject.name() ) {
    idfObject.setName(*s);
  }

  {
    auto value = modelObject.ratedHeatingCapacity();
    idfObject.setDouble(Coil_WaterHeating_AirToWaterHeatPumpFields::RatedHeatingCapacity,value);
  }

  {
    auto value = modelObject.ratedCOP();
    idfObject.setDouble(Coil_WaterHeating_AirToWaterHeatPumpFields::RatedCOP,value);
  }

  {
    auto value = modelObject.ratedSensibleHeatRatio();
    idfObject.setDouble(Coil_WaterHeating_AirToWaterHeatPumpFields::RatedSensibleHeatRatio,value);
  }

  {
    auto value = modelObject.ratedEvaporatorInletAirDryBulbTemperature();
    idfObject.setDouble(Coil_WaterHeating_AirToWaterHeatPumpFields::RatedEvaporatorInletAirDryBulbTemperature,value);
  }

  {
    auto value = modelObject.ratedEvaporatorInletAirWetBulbTemperature();
    idfObject.setDouble(Coil_WaterHeating_AirToWaterHeatPumpFields::RatedEvaporatorInletAirWetBulbTemperature,value);
  }

  {
    auto value = modelObject.ratedCondenserInletWaterTemperature();
    idfObject.setDouble(Coil_WaterHeating_AirToWaterHeatPumpFields::RatedCondenserInletWaterTemperature,value);
  }

  if( modelObject.isRatedEvaporatorAirFlowRateAutosized() ) {
    idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::RatedEvaporatorAirFlowRate,"Autosize");
  } else if( auto value = modelObject.ratedEvaporatorAirFlowRate() ) {
    idfObject.setDouble(Coil_WaterHeating_AirToWaterHeatPumpFields::RatedEvaporatorAirFlowRate,value.get());
  }

  if( modelObject.isRatedCondenserWaterFlowRateAutosized() ) {
    idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::RatedCondenserWaterFlowRate,"Autosize");
  } else if( auto value = modelObject.ratedCondenserWaterFlowRate() ) {
    idfObject.setDouble(Coil_WaterHeating_AirToWaterHeatPumpFields::RatedCondenserWaterFlowRate,value.get());
  }

  if( modelObject.evaporatorFanPowerIncludedinRatedCOP() ) {
    idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::EvaporatorFanPowerIncludedinRatedCOP,"Yes"); 
  } else {
    idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::EvaporatorFanPowerIncludedinRatedCOP,"No");
  }

  if( modelObject.condenserPumpPowerIncludedinRatedCOP() ) {
    idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::CondenserPumpPowerIncludedinRatedCOP,"Yes");
  } else {
    idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::CondenserPumpPowerIncludedinRatedCOP,"No");
  }

  if( modelObject.condenserPumpHeatIncludedinRatedHeatingCapacityandRatedCOP() ) {
    idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::CondenserPumpHeatIncludedinRatedHeatingCapacityandRatedCOP,"Yes");
  } else {
    idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::CondenserPumpHeatIncludedinRatedHeatingCapacityandRatedCOP,"No");
  }

  {
    auto value = modelObject.condenserWaterPumpPower();
    idfObject.setDouble(Coil_WaterHeating_AirToWaterHeatPumpFields::CondenserWaterPumpPower,value);
  }

  {
    auto value = modelObject.fractionofCondenserPumpHeattoWater();
    idfObject.setDouble(Coil_WaterHeating_AirToWaterHeatPumpFields::FractionofCondenserPumpHeattoWater,value);
  }

  {
    auto value = modelObject.crankcaseHeaterCapacity();
    idfObject.setDouble(Coil_WaterHeating_AirToWaterHeatPumpFields::CrankcaseHeaterCapacity,value);
  }

  {
    auto value = modelObject.maximumAmbientTemperatureforCrankcaseHeaterOperation();
    idfObject.setDouble(Coil_WaterHeating_AirToWaterHeatPumpFields::MaximumAmbientTemperatureforCrankcaseHeaterOperation,value);
  }

  {
    auto value = modelObject.evaporatorAirTemperatureTypeforCurveObjects();
    idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::EvaporatorAirTemperatureTypeforCurveObjects,value);
  }

  {
    auto curve = modelObject.heatingCapacityFunctionofTemperatureCurve();
    if( auto idf = translateAndMapModelObject(curve) ) {
      idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::HeatingCapacityFunctionofTemperatureCurveName,idf->name().get());
    }
  }

  {
    auto curve = modelObject.heatingCapacityFunctionofAirFlowFractionCurve();
    if( auto idf = translateAndMapModelObject(curve) ) {
      idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::HeatingCapacityFunctionofAirFlowFractionCurveName,idf->name().get());
    }
  }

  {
    auto curve = modelObject.heatingCapacityFunctionofWaterFlowFractionCurve();
    if( auto idf = translateAndMapModelObject(curve) ) {
      idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::HeatingCapacityFunctionofWaterFlowFractionCurveName,idf->name().get());
    }
  }

  {
    auto curve = modelObject.heatingCOPFunctionofTemperatureCurve();
    if( auto idf = translateAndMapModelObject(curve) ) {
      idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::HeatingCOPFunctionofTemperatureCurveName,idf->name().get());
    }
  }

  {
    auto curve = modelObject.heatingCOPFunctionofAirFlowFractionCurve();
    if( auto idf = translateAndMapModelObject(curve) ) {
      idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::HeatingCOPFunctionofAirFlowFractionCurveName,idf->name().get());
    }
  }

  {
    auto curve = modelObject.heatingCOPFunctionofWaterFlowFractionCurve();
    if( auto idf = translateAndMapModelObject(curve) ) {
      idfObject.setString(Coil_WaterHeating_AirToWaterHeatPumpFields::HeatingCOPFunctionofWaterFlowFractionCurveName,idf->name().get());
    }
  }

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

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateZoneHVACFourPipeFanCoil(
    ZoneHVACFourPipeFanCoil & modelObject )
{
  boost::optional<std::string> s;
  boost::optional<double> value;

  IdfObject idfObject(IddObjectType::ZoneHVAC_FourPipeFanCoil);

  // Get model object name and define node names for future use
  // Model Name
  std::string baseName = modelObject.name().get();
  // Node Names
  std::string mixedAirNodeName = baseName + " Mixed Air Node";
  std::string fanOutletNodeName = baseName + " Fan Outlet Node";
  std::string coolingCoilOutletNodeName = baseName + " Cooling Coil Outlet Node";
  std::string reliefAirNodeName = baseName + " Relief Air Node";
  std::string oaNodeName = baseName + " OA Node";

  boost::optional<AirLoopHVAC> t_airLoopHVAC = modelObject.airLoopHVAC();

  // AirInletNodeName
  boost::optional<std::string> airInletNodeName;
  if( boost::optional<Node> node = modelObject.inletNode() )
  {
    if( (s = node->name()) )
    {
      airInletNodeName = s;
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::AirInletNodeName,s.get() );
    }
  }
  // AirOutletNodeName
  boost::optional<std::string> airOutletNodeName;
  if( boost::optional<Node> node = modelObject.outletNode() )
  {
    if( (s = node->name()) )
    {
      airOutletNodeName = s;
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::AirOutletNodeName,s.get() );
    }
  }

  // hook up required objects
  try {
    // AvailabilityScheduleName
    Schedule availabilitySchedule = modelObject.availabilitySchedule();
    translateAndMapModelObject(availabilitySchedule);
    idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::AvailabilityScheduleName,
                        availabilitySchedule.name().get() );

    // Supply Air Fan
    HVACComponent supplyAirFan = modelObject.supplyAirFan();
    if( boost::optional<IdfObject> _supplyAirFan = translateAndMapModelObject(supplyAirFan) )
    {
      // SupplyAirFanObjectType
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::SupplyAirFanObjectType,_supplyAirFan->iddObject().name() );

      // SupplyAirFanName
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::SupplyAirFanName,_supplyAirFan->name().get() );
      // Supply Air Fan Inlet and Outlet Nodes
      if( airOutletNodeName && airInletNodeName )
      {
        // If there is an AirLoopHVAC then we provide no mixer
        std::string fanInletNodeName;
        if( t_airLoopHVAC ) {
          fanInletNodeName = airInletNodeName.get();
        } else {
          fanInletNodeName = mixedAirNodeName;
        }

        if( _supplyAirFan->iddObject().type() == IddObjectType::Fan_ConstantVolume )
        {
          _supplyAirFan->setString(Fan_ConstantVolumeFields::AirInletNodeName,fanInletNodeName );
          _supplyAirFan->setString(Fan_ConstantVolumeFields::AirOutletNodeName,fanOutletNodeName );
        }
        else if( _supplyAirFan->iddObject().type() == IddObjectType::Fan_OnOff )
        {
          
          _supplyAirFan->setString(Fan_OnOffFields::AirInletNodeName,fanInletNodeName );
          _supplyAirFan->setString(Fan_OnOffFields::AirOutletNodeName,fanOutletNodeName );
        }
        else if( _supplyAirFan->iddObject().type() == IddObjectType::Fan_VariableVolume )
        {
          _supplyAirFan->setString(Fan_VariableVolumeFields::AirInletNodeName,fanInletNodeName );
          _supplyAirFan->setString(Fan_VariableVolumeFields::AirOutletNodeName,fanOutletNodeName );
        }
      }
    }

    // Cooling Coil
    HVACComponent coolingCoil = modelObject.coolingCoil();
    if( boost::optional<IdfObject> _coolingCoil = translateAndMapModelObject(coolingCoil) )
    {
      // CoolingCoilObjectType
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::CoolingCoilObjectType,_coolingCoil->iddObject().name() );
      // CoolingCoilName
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::CoolingCoilName,_coolingCoil->name().get() );
      // Cooling Coil Inlet and Outlet Nodes
      if( _coolingCoil->iddObject().type() == IddObjectType::Coil_Cooling_Water )
      {
        _coolingCoil->setString(Coil_Cooling_WaterFields::AirInletNodeName,fanOutletNodeName );
        _coolingCoil->setString(Coil_Cooling_WaterFields::AirOutletNodeName,coolingCoilOutletNodeName );
      }
    }

    // Heating Coil
    HVACComponent heatingCoil = modelObject.heatingCoil();
    if( boost::optional<IdfObject> _heatingCoil = translateAndMapModelObject(heatingCoil) )
    {
      // HeatingCoilObjectType
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::HeatingCoilObjectType,_heatingCoil->iddObject().name() );
      // HeatingCoilName
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::HeatingCoilName,_heatingCoil->name().get() );
      // Heating Coil Inlet and Outlet Nodes
      if( _heatingCoil->iddObject().type() == IddObjectType::Coil_Heating_Water )
      {
        _heatingCoil->setString(Coil_Heating_WaterFields::AirInletNodeName,coolingCoilOutletNodeName );
        _heatingCoil->setString(Coil_Heating_WaterFields::AirOutletNodeName,airOutletNodeName.get() );
      }
    }
  }
  catch (std::exception& e) {
    LOG(Error,"Could not translate " << modelObject.briefDescription() << ", because "
        << e.what() << ".");
    return boost::none;
  }

  m_idfObjects.push_back(idfObject);

  // Name
  idfObject.setName(baseName);

  // CapacityControlMethod
  idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::CapacityControlMethod,
                      modelObject.capacityControlMethod());

  // MaximumSupplyAirFlowRate
  if( modelObject.isMaximumSupplyAirFlowRateAutosized() )
  {
    idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::MaximumSupplyAirFlowRate,"Autosize");
  }
  else if( (value = modelObject.maximumSupplyAirFlowRate()) )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::MaximumSupplyAirFlowRate,value.get());
  }

  // LowSpeedSupplyAirFlowRatio
  if(! modelObject.isLowSpeedSupplyAirFlowRatioDefaulted() )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::LowSpeedSupplyAirFlowRatio,modelObject.lowSpeedSupplyAirFlowRatio() );
  }

  // MediumSpeedSupplyAirFlowRatio
  if(! (modelObject.isMediumSpeedSupplyAirFlowRatioDefaulted()) )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::MediumSpeedSupplyAirFlowRatio,modelObject.mediumSpeedSupplyAirFlowRatio() );
  }

  // MaximumOutdoorAirFlowRate
  if( modelObject.isMaximumOutdoorAirFlowRateAutosized() )
  {
    idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::MaximumOutdoorAirFlowRate,"Autosize");
  }
  else if( (value = modelObject.maximumOutdoorAirFlowRate()) )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::MaximumOutdoorAirFlowRate,value.get());
  }

  // OutdoorAirScheduleName
  if( boost::optional<Schedule> schedule = modelObject.outdoorAirSchedule() )
  {
    if( boost::optional<IdfObject> _schedule = translateAndMapModelObject(schedule.get()) )
    {
      idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::OutdoorAirScheduleName,_schedule->name().get());
    }
  }

  if( ! t_airLoopHVAC ) {
    // OutdoorAirMixerObjectType
    idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::OutdoorAirMixerObjectType,
                        modelObject.outdoorAirMixerObjectType());

    // OutdoorAirMixerName
    std::string oaMixerName = modelObject.name().get() + " OA Mixer";
    idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::OutdoorAirMixerName,oaMixerName);

    // Create Outdoor Air Mixer
    IdfObject _outdoorAirMixer(IddObjectType::OutdoorAir_Mixer);
    _outdoorAirMixer.setName(oaMixerName);
    m_idfObjects.push_back(_outdoorAirMixer);

    _outdoorAirMixer.setString(OutdoorAir_MixerFields::MixedAirNodeName,mixedAirNodeName);
    _outdoorAirMixer.setString(OutdoorAir_MixerFields::OutdoorAirStreamNodeName,oaNodeName);
    _outdoorAirMixer.setString(OutdoorAir_MixerFields::ReliefAirStreamNodeName,reliefAirNodeName);
    if(airInletNodeName)
    {
      _outdoorAirMixer.setString(OutdoorAir_MixerFields::ReturnAirStreamNodeName,airInletNodeName.get());
    }

    // Create Outdoor Air Node List
    IdfObject _oaNodeList(openstudio::IddObjectType::OutdoorAir_NodeList);
    _oaNodeList.setString(0,oaNodeName);
    m_idfObjects.push_back(_oaNodeList);
  }

  // MaximumColdWaterFlowRate
  if( modelObject.isMaximumColdWaterFlowRateAutosized() )
  {
    idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::MaximumColdWaterFlowRate,"Autosize");
  }
  else if( (value = modelObject.maximumColdWaterFlowRate()) )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::MaximumColdWaterFlowRate,value.get());
  }

  // MinimumColdWaterFlowRate
  if(! modelObject.isMinimumColdWaterFlowRateDefaulted() )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::MinimumColdWaterFlowRate,modelObject.minimumColdWaterFlowRate() );
  }

  // CoolingConvergenceTolerance
  if(! modelObject.isCoolingConvergenceToleranceDefaulted() )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::CoolingConvergenceTolerance,modelObject.coolingConvergenceTolerance() );
  }

  // MaximumHotWaterFlowRate
  if( modelObject.isMaximumHotWaterFlowRateAutosized() )
  {
    idfObject.setString(ZoneHVAC_FourPipeFanCoilFields::MaximumHotWaterFlowRate,"Autosize");
  }
  else if( (value = modelObject.maximumHotWaterFlowRate()) )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::MaximumHotWaterFlowRate,value.get());
  }

  // MinimumHotWaterFlowRate
  if(! modelObject.isMinimumHotWaterFlowRateDefaulted() )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::MinimumHotWaterFlowRate,modelObject.minimumHotWaterFlowRate() );
  }

  // HeatingConvergenceTolerance
  if(! modelObject.isHeatingConvergenceToleranceDefaulted() )
  {
    idfObject.setDouble(ZoneHVAC_FourPipeFanCoilFields::HeatingConvergenceTolerance,modelObject.heatingConvergenceTolerance() );
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateSizingZone( SizingZone & modelObject )
{
  boost::optional<std::string> s;
  boost::optional<double> value;

  IdfObject idfObject(IddObjectType::Sizing_Zone);

  m_idfObjects.push_back(idfObject);

  // ZoneorZoneListName

  model::ThermalZone thermalZone = modelObject.thermalZone();

  boost::optional<IdfObject> _thermalZone = translateAndMapModelObject(thermalZone);

  boost::optional<std::string> name;

  if( _thermalZone )
  {
    name = _thermalZone->name();
  }

  if( name )
  {
    idfObject.setString(Sizing_ZoneFields::ZoneorZoneListName,name.get());
  }

  // ZoneCoolingDesignSupplyAirTemperatureInputMethod

  idfObject.setString(Sizing_ZoneFields::ZoneCoolingDesignSupplyAirTemperatureInputMethod,"SupplyAirTemperature");

  // ZoneCoolingDesignSupplyAirTemperature

  value = modelObject.zoneCoolingDesignSupplyAirTemperature();
  if( value )
  {
    idfObject.setDouble(Sizing_ZoneFields::ZoneCoolingDesignSupplyAirTemperature,value.get());
  }

  // ZoneHeatingDesignSupplyAirTemperatureInputMethod

  idfObject.setString(Sizing_ZoneFields::ZoneHeatingDesignSupplyAirTemperatureInputMethod,"SupplyAirTemperature");

  // ZoneHeatingDesignSupplyAirTemperature

  value = modelObject.zoneHeatingDesignSupplyAirTemperature();
  if( value )
  {
    idfObject.setDouble(Sizing_ZoneFields::ZoneHeatingDesignSupplyAirTemperature,value.get());
  }

  // ZoneCoolingDesignSupplyAirHumidityRatio
  
  value = modelObject.zoneCoolingDesignSupplyAirHumidityRatio();
  if( value )
  {
    idfObject.setDouble(Sizing_ZoneFields::ZoneCoolingDesignSupplyAirHumidityRatio,value.get());
  }

  // ZoneHeatingDesignSupplyAirHumidityRatio
  
  value = modelObject.zoneHeatingDesignSupplyAirHumidityRatio();
  if( value )
  {
    idfObject.setDouble(Sizing_ZoneFields::ZoneHeatingDesignSupplyAirHumidityRatio,value.get());
  }

  //  ((DesignSpecificationOutdoorAirObjectName)(Design Specification Outdoor Air Object Name))
  
  // ZoneHeatingSizingFactor 
  
  value = modelObject.zoneHeatingSizingFactor();
  if( value )
  {
    idfObject.setDouble(Sizing_ZoneFields::ZoneHeatingSizingFactor,value.get());
  }
  
  // ZoneCoolingSizingFactor 
  
  value = modelObject.zoneCoolingSizingFactor();
  if( value )
  {
    idfObject.setDouble(Sizing_ZoneFields::ZoneCoolingSizingFactor,value.get());
  }

  // CoolingDesignAirFlowMethod
  
  s = modelObject.coolingDesignAirFlowMethod();
  if( s )
  {
    idfObject.setString(Sizing_ZoneFields::CoolingDesignAirFlowMethod,s.get());
  }

  // CoolingDesignAirFlowRate
  
  value = modelObject.coolingDesignAirFlowRate();
  if( value )
  {
    idfObject.setDouble(Sizing_ZoneFields::CoolingDesignAirFlowRate,value.get());
  }

  // CoolingMinimumAirFlowperZoneFloorArea

  value = modelObject.coolingMinimumAirFlowperZoneFloorArea();
  if( value )
  {
    idfObject.setDouble(Sizing_ZoneFields::CoolingMinimumAirFlowperZoneFloorArea,value.get());
  }

  // CoolingMinimumAirFlow

  value = modelObject.coolingMinimumAirFlow();
  if( value )
  {
    idfObject.setDouble(Sizing_ZoneFields::CoolingMinimumAirFlow,value.get());
  }

  // CoolingMinimumAirFlowFraction

  value = modelObject.coolingMinimumAirFlowFraction();
  if( value )
  {
    idfObject.setDouble(Sizing_ZoneFields::CoolingMinimumAirFlowFraction,value.get());
  }

  // HeatingDesignAirFlowMethod
  
  s = modelObject.heatingDesignAirFlowMethod();
  if( s )
  {
    idfObject.setString(Sizing_ZoneFields::HeatingDesignAirFlowMethod,s.get());
  }

  // HeatingDesignAirFlowRate
  
  value = modelObject.heatingDesignAirFlowRate();
  if( value )
  {
    idfObject.setDouble(Sizing_ZoneFields::HeatingDesignAirFlowRate,value.get());
  }

  // HeatingMaximumAirFlowperZoneFloorArea

  value = modelObject.heatingMaximumAirFlowperZoneFloorArea();
  if( value )
  {
    idfObject.setDouble(Sizing_ZoneFields::HeatingMaximumAirFlowperZoneFloorArea,value.get());
  }

  // HeatingMaximumAirFlow

  value = modelObject.heatingMaximumAirFlow();
  if( value )
  {
    idfObject.setDouble(Sizing_ZoneFields::HeatingMaximumAirFlow,value.get());
  }

  // HeatingMaximumAirFlowFraction

  value = modelObject.heatingMaximumAirFlowFraction();
  if( value )
  {
    idfObject.setDouble(Sizing_ZoneFields::HeatingMaximumAirFlowFraction,value.get());
  }

  // DesignZoneAirDistributionEffectivenessinCoolingMode
  // DesignZoneAirDistributionEffectivenessinHeatingMode

  boost::optional<double> designZoneAirDistributionEffectivenessinCoolingMode = 
                            modelObject.designZoneAirDistributionEffectivenessinCoolingMode();
  boost::optional<double> designZoneAirDistributionEffectivenessinHeatingMode = 
                            modelObject.designZoneAirDistributionEffectivenessinHeatingMode();

  std::string designSpecificationZoneAirDistributionName;
  if( name )
  {
    designSpecificationZoneAirDistributionName = name.get() +  " Design Spec Zone Air Dist";
  }

  if( designZoneAirDistributionEffectivenessinCoolingMode ||
      designZoneAirDistributionEffectivenessinHeatingMode )
  {
    IdfObject _designSpecification_ZoneAirDistribution(IddObjectType::DesignSpecification_ZoneAirDistribution);

    if( name )
    {
      _designSpecification_ZoneAirDistribution.setName(designSpecificationZoneAirDistributionName);
    }

    m_idfObjects.push_back(_designSpecification_ZoneAirDistribution);

    if( designZoneAirDistributionEffectivenessinCoolingMode )
    {
      _designSpecification_ZoneAirDistribution.setDouble(
        DesignSpecification_ZoneAirDistributionFields::ZoneAirDistributionEffectivenessinCoolingMode,
        designZoneAirDistributionEffectivenessinCoolingMode.get() );
    }

    if( designZoneAirDistributionEffectivenessinHeatingMode )
    {
      _designSpecification_ZoneAirDistribution.setDouble(
        DesignSpecification_ZoneAirDistributionFields::ZoneAirDistributionEffectivenessinHeatingMode,
        designZoneAirDistributionEffectivenessinHeatingMode.get() );
    }

    idfObject.setString(Sizing_ZoneFields::DesignSpecificationZoneAirDistributionObjectName,_designSpecification_ZoneAirDistribution.name().get());
  }


  // Add ThermalZone and associated design objects to ControllerMechanicalVentilation.
  // This would be done in forwardTranslateControllerMechanicalVentilation except doing it here maintains proper order of the idf file.
  
  boost::optional<model::ControllerMechanicalVentilation> controllerMechanicalVentilation;
  boost::optional<IdfObject> _controllerMechanicalVentilation;

  if( boost::optional<model::AirLoopHVAC> airLoopHVAC = thermalZone.airLoopHVAC() )
  {
    if( boost::optional<model::AirLoopHVACOutdoorAirSystem> oaSystem = airLoopHVAC->airLoopHVACOutdoorAirSystem() )
    {
      model::ControllerOutdoorAir controllerOutdoorAir = oaSystem->getControllerOutdoorAir(); 

      controllerMechanicalVentilation = controllerOutdoorAir.controllerMechanicalVentilation();
    }
  }
  
  if( controllerMechanicalVentilation )
  {
    _controllerMechanicalVentilation = translateAndMapModelObject(controllerMechanicalVentilation.get());
  }

  if( _controllerMechanicalVentilation && _thermalZone )
  {
    IdfExtensibleGroup eg = _controllerMechanicalVentilation->pushExtensibleGroup();

    // Thermal Zone Name
    eg.setString(Controller_MechanicalVentilationExtensibleFields::ZoneName,_thermalZone->name().get());

    // DesignSpecificationOutdoorAir
    std::vector<model::Space> spaces = thermalZone.spaces();

    if( spaces.size() > 0 )
    {
      if( boost::optional<model::DesignSpecificationOutdoorAir> designOASpec = spaces.front().designSpecificationOutdoorAir()  )
      {
        if( boost::optional<IdfObject> _designOASpec = translateAndMapModelObject(designOASpec.get()) )
        {
          eg.setString(Controller_MechanicalVentilationExtensibleFields::DesignSpecificationOutdoorAirObjectName,_designOASpec->name().get());
        }
      }
    }

    // DesignSpecificationZoneAirDistributionObjectName
    if( _thermalZone )
    {
      eg.setString(Controller_MechanicalVentilationExtensibleFields::DesignSpecificationZoneAirDistributionObjectName,
                   designSpecificationZoneAirDistributionName);
    }
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateWaterUseConnections( 
    WaterUseConnections& modelObject)
{
  boost::optional<std::string> s;
  boost::optional<double> value;
  OptionalSchedule schedule;

  IdfObject idfObject(IddObjectType::WaterUse_Connections);

  m_idfObjects.push_back(idfObject);

  // Name

  s = modelObject.name();
  if( s )
  {
    idfObject.setName(*s);
  }

  // InletNodeName

  if( boost::optional<ModelObject> mo = modelObject.inletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(WaterUse_ConnectionsFields::InletNodeName,node->name().get());
    }
  }

  // OutletNodeName

  if( boost::optional<ModelObject> mo = modelObject.outletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(WaterUse_ConnectionsFields::OutletNodeName,node->name().get());
    }
  }

  // Hot Water Supply Temperature Schedule Name
  
  if( boost::optional<Schedule> s = modelObject.hotWaterSupplyTemperatureSchedule() )
  {
    translateAndMapModelObject(s.get());

    idfObject.setString(WaterUse_ConnectionsFields::HotWaterSupplyTemperatureScheduleName,s->name().get());
  }

  // Cold Water Supply Temperature Schedule Name

  if( boost::optional<Schedule> s = modelObject.coldWaterSupplyTemperatureSchedule() )
  {
    translateAndMapModelObject(s.get());

    idfObject.setString(WaterUse_ConnectionsFields::ColdWaterSupplyTemperatureScheduleName,s->name().get());
  }

  //  Water Use Equipment 1 Name

  std::vector<WaterUseEquipment> equipment = modelObject.waterUseEquipment();

  for( auto & elem : equipment )
  {
    boost::optional<IdfObject> _equipment = translateAndMapModelObject(elem); 

    if( _equipment )
    {
      IdfExtensibleGroup group = idfObject.pushExtensibleGroup();

      group.setString(WaterUse_ConnectionsExtensibleFields::WaterUseEquipmentName,_equipment->name().get());
    }
  }

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

  // Create a new IddObjectType::Fan_ConstantVolume
  IdfObject idfObject(IddObjectType::Fan_ConstantVolume);

  ///////////////////////////////////////////////////////////////////////////
  // Field: Name ////////////////////////////////////////////////////////////
  s = modelObject.name();
  if(s)
  {
    idfObject.setName(*s);
  }
  ///////////////////////////////////////////////////////////////////////////


  // hook up required objects
  try {
    if( boost::optional<model::AirLoopHVAC> airLoopHVAC = modelObject.airLoopHVAC() )
    {
      Schedule sched = airLoopHVAC->availabilitySchedule();
      boost::optional<IdfObject> schedIdf = translateAndMapModelObject(sched);
      if( schedIdf )
      {
        idfObject.setString(Fan_ConstantVolumeFields::AvailabilityScheduleName,schedIdf->name().get());
      }
    }
    else
    {
      Schedule sched = modelObject.availabilitySchedule();
      translateAndMapModelObject(sched);
      idfObject.setString(Fan_ConstantVolumeFields::AvailabilityScheduleName,sched.name().get());
    }
  }
  catch (std::exception& e) {
    LOG(Error,"Could not translate " << modelObject.briefDescription() << ", because " 
        << e.what() << ".");
    return boost::none;
  }


  ///////////////////////////////////////////////////////////////////////////
  // Fan Efficiency /////////////////////////////////////////////////////////
  idfObject.setDouble(openstudio::Fan_ConstantVolumeFields::FanTotalEfficiency,modelObject.fanEfficiency());
  ///////////////////////////////////////////////////////////////////////////

  ///////////////////////////////////////////////////////////////////////////
  // Pressure Rise //////////////////////////////////////////////////////////
  idfObject.setDouble(openstudio::Fan_ConstantVolumeFields::PressureRise,modelObject.pressureRise());
  ///////////////////////////////////////////////////////////////////////////

  ///////////////////////////////////////////////////////////////////////////
  // Maximum Flow Rate //////////////////////////////////////////////////////
  d = modelObject.maximumFlowRate();
  if(d)
  {
    idfObject.setDouble(openstudio::Fan_ConstantVolumeFields::MaximumFlowRate,*d);
  }
  else
  {
    idfObject.setString(openstudio::Fan_ConstantVolumeFields::MaximumFlowRate,"AutoSize");
  }
  ///////////////////////////////////////////////////////////////////////////

  ///////////////////////////////////////////////////////////////////////////
  // Motor Efficiency ///////////////////////////////////////////////////////
  idfObject.setDouble(openstudio::Fan_ConstantVolumeFields::MotorEfficiency,modelObject.motorEfficiency());
  ///////////////////////////////////////////////////////////////////////////

  ///////////////////////////////////////////////////////////////////////////
  // Motor In Airstream Fraction ////////////////////////////////////////////
  idfObject.setDouble(openstudio::Fan_ConstantVolumeFields::MotorInAirstreamFraction,modelObject.motorInAirstreamFraction());
  ///////////////////////////////////////////////////////////////////////////

  ///////////////////////////////////////////////////////////////////////////
  // Air Inlet Node Name ////////////////////////////////////////////////////
  temp = modelObject.inletModelObject();
  if(temp)
  {
    s = temp->name();
    if(s)
    {
      idfObject.setString(openstudio::Fan_ConstantVolumeFields::AirInletNodeName,*s);
    }
  }
  ///////////////////////////////////////////////////////////////////////////

  ///////////////////////////////////////////////////////////////////////////
  // Air Outlet Node Name ///////////////////////////////////////////////////
  temp = modelObject.outletModelObject();
  if(temp)
  {
    s = temp->name();
    if(s)
    {
      idfObject.setString(openstudio::Fan_ConstantVolumeFields::AirOutletNodeName,*s);
    }
  }
  ///
  ////////////////////////////////////////////////////////////////////////

  m_idfObjects.push_back(idfObject);
  return boost::optional<IdfObject>(idfObject);
}
boost::optional<IdfObject> ForwardTranslator::translateFanVariableVolume( FanVariableVolume& modelObject )
{
  OptionalString s;
  OptionalDouble d;
  OptionalModelObject temp;

  // Create a new IddObjectType::Fan_VariableVolume
  IdfObject idfObject(IddObjectType::Fan_VariableVolume);

  m_idfObjects.push_back(idfObject);

  // Field: Name ////////////////////////////////////////////////////////////
  s = modelObject.name();
  if(s)
  {
    idfObject.setName(*s);
  }

  // AvailabilityScheduleName

  if( boost::optional<model::AirLoopHVAC> airLoopHVAC = modelObject.airLoopHVAC() )
  {
    Schedule sched = airLoopHVAC->availabilitySchedule();
    boost::optional<IdfObject> schedIdf = translateAndMapModelObject(sched);
    if( schedIdf )
    {
      idfObject.setString(Fan_VariableVolumeFields::AvailabilityScheduleName,schedIdf->name().get());
    }
  }
  else
  {
    Schedule sched = modelObject.availabilitySchedule();
    translateAndMapModelObject(sched);
    idfObject.setString(Fan_VariableVolumeFields::AvailabilityScheduleName,sched.name().get());
  }

  // Fan Efficiency /////////////////////////////////////////////////////////
  idfObject.setDouble(openstudio::Fan_VariableVolumeFields::FanTotalEfficiency,modelObject.fanEfficiency());

  // Pressure Rise //////////////////////////////////////////////////////////
  idfObject.setDouble(openstudio::Fan_VariableVolumeFields::PressureRise,modelObject.pressureRise());

  // Maximum Flow Rate //////////////////////////////////////////////////////
  if( modelObject.isMaximumFlowRateAutosized() )
  {
    idfObject.setString(openstudio::Fan_VariableVolumeFields::MaximumFlowRate,"AutoSize");
  }
  else if( (d = modelObject.maximumFlowRate()) )
  {
    idfObject.setDouble(openstudio::Fan_VariableVolumeFields::MaximumFlowRate,d.get());
  }

  // FanPowerMinimumFlowRateInputMethod
  if( (s = modelObject.fanPowerMinimumFlowRateInputMethod()) )
  {
    idfObject.setString(Fan_VariableVolumeFields::FanPowerMinimumFlowRateInputMethod,s.get());
  }

  // FanPowerMinimumFlowFraction
  if( (d = modelObject.fanPowerMinimumFlowFraction()) )
  {
    idfObject.setDouble(Fan_VariableVolumeFields::FanPowerMinimumFlowFraction,d.get());
  }

  // FanPowerMinimumAirFlowRate

  if( (d = modelObject.fanPowerMinimumAirFlowRate()) )
  {
    idfObject.setDouble(Fan_VariableVolumeFields::FanPowerMinimumAirFlowRate,d.get());
  }

  // Motor Efficiency ///////////////////////////////////////////////////////
  idfObject.setDouble(openstudio::Fan_VariableVolumeFields::MotorEfficiency,modelObject.motorEfficiency());

  // FanPowerCoefficient1

  if( (d = modelObject.fanPowerCoefficient1()) )
  {
    idfObject.setDouble(Fan_VariableVolumeFields::FanPowerCoefficient1,d.get());
  }

  // FanPowerCoefficient2

  if( (d = modelObject.fanPowerCoefficient2()) )
  {
    idfObject.setDouble(Fan_VariableVolumeFields::FanPowerCoefficient2,d.get());
  }

  // FanPowerCoefficient3

  if( (d = modelObject.fanPowerCoefficient3()) )
  {
    idfObject.setDouble(Fan_VariableVolumeFields::FanPowerCoefficient3,d.get());
  }

  // FanPowerCoefficient4

  if( (d = modelObject.fanPowerCoefficient4()) )
  {
    idfObject.setDouble(Fan_VariableVolumeFields::FanPowerCoefficient4,d.get());
  }

  // FanPowerCoefficient5

  if( (d = modelObject.fanPowerCoefficient5()) )
  {
    idfObject.setDouble(Fan_VariableVolumeFields::FanPowerCoefficient5,d.get());
  }

  // Motor In Airstream Fraction ////////////////////////////////////////////
  idfObject.setDouble(openstudio::Fan_VariableVolumeFields::MotorInAirstreamFraction,modelObject.motorInAirstreamFraction());

  // Air Inlet Node Name ////////////////////////////////////////////////////
  temp = modelObject.inletModelObject();
  if(temp)
  {
    s = temp->name();
    if(s)
    {
      idfObject.setString(openstudio::Fan_VariableVolumeFields::AirInletNodeName,*s);
    }
  }

  // Air Outlet Node Name ///////////////////////////////////////////////////
  temp = modelObject.outletModelObject();
  if(temp)
  {
    s = temp->name();
    if(s)
    {
      idfObject.setString(openstudio::Fan_VariableVolumeFields::AirOutletNodeName,*s);
    }
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateAvailabilityManagerNightCycle(
    AvailabilityManagerNightCycle & modelObject)
{
  IdfObject idfObject(IddObjectType::AvailabilityManager_NightCycle);
  m_idfObjects.push_back(idfObject);

  boost::optional<AirLoopHVAC> airLoopHVAC;
  if( auto loop = modelObject.loop() ) {
    airLoopHVAC = loop->optionalCast<model::AirLoopHVAC>();
  }

  {
    auto schedule = modelObject.model().alwaysOnDiscreteSchedule();
    idfObject.setString(AvailabilityManager_NightCycleFields::ApplicabilityScheduleName,schedule.name().get());
  }

  if( airLoopHVAC ) {
    // Fan schedules are set to match the availabilitySchedule in the translator
    idfObject.setString(AvailabilityManager_NightCycleFields::FanScheduleName,airLoopHVAC->availabilitySchedule().name().get());
  }

  // TODO: @kbenne, we don't even translate the AVM:NightCycle if it's not on an airloop anyways
  // Translation is triggered from the AirLoopHVAC itself

  if( auto s = modelObject.name() ) {
    idfObject.setName(*s);
  }


  {
    auto value = modelObject.thermostatTolerance();
    idfObject.setDouble(AvailabilityManager_NightCycleFields::ThermostatTolerance,value);
  }


  // Cycling Run Time and Cycling Run Time Control Type
  {
    double runtime = modelObject.cyclingRunTime();
    idfObject.setDouble(AvailabilityManager_NightCycleFields::CyclingRunTime, runtime);
    std::string cycRTCType = modelObject.cyclingRunTimeControlType();

    if (istringEqual(cycRTCType, "Thermostat")) {
      LOG(Info, "With a Cycling Run Time Control Type set to '" << cycRTCType
          << "', the entered Cycling Run Time of '" << runtime << "' seconds will be ignored for "
          << modelObject.briefDescription());
    }
    idfObject.setString(AvailabilityManager_NightCycleFields::CyclingRunTimeControlType, cycRTCType);
  }


  // We'll use that later to default the control zone lists
  std::string controlType = modelObject.controlType();
  idfObject.setString(AvailabilityManager_NightCycleFields::ControlType, controlType);

  // Zone Lists
  std::vector<ThermalZone> controlThermalZones = modelObject.controlThermalZones();
  std::vector<ThermalZone> coolingControlThermalZones = modelObject.coolingControlThermalZones();
  std::vector<ThermalZone> heatingControlThermalZones = modelObject.heatingControlThermalZones();
  std::vector<ThermalZone> heatingZoneFansOnlyThermalZones = modelObject.heatingZoneFansOnlyThermalZones();

  // Size of Zone Lists for convenience
  auto n_controlThermalZones = controlThermalZones.size();
  auto n_coolingControlThermalZones = coolingControlThermalZones.size();
  auto n_heatingControlThermalZones = heatingControlThermalZones.size();
  auto n_heatingZoneFansOnlyThermalZones = heatingZoneFansOnlyThermalZones.size();

  // Boolean to decide whether defaulting a given ZoneList to all zones served by system is needed or not
  bool default_controlThermalZones = false;
  bool default_coolingControlThermalZones = false;
  bool default_heatingControlThermalZones = false;
  bool default_heatingZoneFansOnlyThermalZones = false;

  // Main logic to warn user and decide if defaulting is needed based on the Control Type entered
  if ( istringEqual(controlType, "StayOff") ||
       istringEqual(controlType, "CycleOnAny") ||
       istringEqual(controlType, "CycleOnAnyZoneFansOnly") ) {

    // All Control Zone Lists are ignored
    if ((  n_controlThermalZones
         + n_coolingControlThermalZones
         + n_heatingControlThermalZones
         + n_heatingZoneFansOnlyThermalZones) > 0 ) {
      LOG(Info, "All Control Zone Lists will be ignored for " << modelObject.briefDescription()
            << " due to the Control Type of '" << controlType << "'.");
    }

  } else if ( istringEqual(controlType, "CycleOnControlZone") ) {

    // Only the controlThermalZones isn't ignored
    if ((  n_coolingControlThermalZones
         + n_heatingControlThermalZones
         + n_heatingZoneFansOnlyThermalZones) > 0 ) {
      LOG(Info, "All Control Zone Lists other than 'Control Zone List' will be ignored for " << modelObject.briefDescription()
            << " due to the Control Type of '" << controlType << "'.");
    }

    // Check if need to default the controlThermalZones
    // Another option might have been to switch the control Type to CycleOnAny
    if (n_controlThermalZones == 0) {
      default_controlThermalZones = true;
    }

  } else if ( istringEqual(controlType, "CycleOnAnyCoolingZone") ) {

    // Only the coolingControlThermalZones isn't ignored
    if ((  n_controlThermalZones
         + n_heatingControlThermalZones
         + n_heatingZoneFansOnlyThermalZones) > 0 ) {
      LOG(Info, "All Control Zone Lists  other than 'Cooling Control Zone List' will be ignored for " << modelObject.briefDescription()
            << " due to the Control Type of '" << controlType << "'.");
    }

    // Check if need to default
    if (n_coolingControlThermalZones == 0) {
      default_coolingControlThermalZones = true;
    }


  } else if ( istringEqual(controlType, "CycleOnAnyHeatingZone") ) {

    // Only the heatingControlThermalZones, and heatingZoneFansOnlyThermalZones aren't ignored
    if (( n_controlThermalZones
          + n_coolingControlThermalZones) > 0 ) {
      LOG(Info, "All Control Zone Lists  other than 'Heating Control Zone List' and optionally "
                "'Heating Zone Fans Only Zone List' will be ignored for " << modelObject.briefDescription()
                << " due to the Control Type of '" << controlType << "'.");
    }

    // Check if need to default
    if (n_heatingControlThermalZones == 0) {
      default_heatingControlThermalZones = true;
    }
    // TODO: @kbenne
    // here we should't default the heatingZoneFansOnlyThermalZones
    // I view that as an option to enable cycling on zone fans only or not,
    // while you only get central heating operation (not possible with CycleOnAny)

  } else if ( istringEqual(controlType, "CycleOnAnyHeatingZoneFansOnly") ) {

    // Only the heatingZoneFansOnlyThermalZones isn't ignored
    if ((  n_controlThermalZones
          + n_coolingControlThermalZones
          + n_heatingControlThermalZones) > 0 ) {
      LOG(Info, "All Control Zone Lists  other than 'Heating Zone Fans Only Zone List' will be ignored for "
                << modelObject.briefDescription()
                << " due to the Control Type of '" << controlType << "'.");
    }

    // Check if need to default
    if (n_heatingZoneFansOnlyThermalZones == 0) {
      default_heatingZoneFansOnlyThermalZones = true;
    }


  } else if ( istringEqual(controlType, "CycleOnAnyCoolingOrHeatingZone") ) {

    // Only the coolingControlThermalZones, coolingControlThermalZones, and optionally heatingZoneFansOnlyThermalZones aren't ignored
      if ( n_controlThermalZones > 0 ) {
      LOG(Info, "All Control Zone Lists  other than 'Heating Control Zone List', 'Cooling Control Zone List' and optionally "
                "'Heating Zone Fans Only Zone List' will be ignored for " << modelObject.briefDescription()
                << " due to the Control Type of '" << controlType << "'.");
    }

    // Check if need to default
    if (n_heatingControlThermalZones == 0) {
      default_heatingControlThermalZones = true;
    }
    if (n_coolingControlThermalZones == 0) {
      default_coolingControlThermalZones = true;
    }
    // TODO: @kbenne
    // Here we should default the heatingZoneFansOnlyThermalZones
    // Because otherwise the user could have just chosen "CycleOnAny"
    if (n_heatingZoneFansOnlyThermalZones == 0) {
      default_heatingZoneFansOnlyThermalZones = true;
    }


  } else {
    // should never get there, unless a new ControlType is added later...
    LOG_AND_THROW("Unknown Control Type of '" << controlType << "' for " << modelObject.briefDescription());
  } // End of Main logic to warn user and decide if defaulting is needed based on the Control Type entered


  // Whether a Zone List will actually be unused or not, we still translate it (perhaps the user is going to use the IDF later)

  // Control Thermal Zones
  {
    // Create a ZoneList, and populate it
    IdfObject zoneList(IddObjectType::ZoneList);
    std::string zoneListName = modelObject.name().get() + " Control Zones List";
    zoneList.setName(zoneListName);
    bool write_zonelist;

    if (default_controlThermalZones) {
      // Get all zones served by the AirLoop attached to it
      if( airLoopHVAC ) {
        for( const ThermalZone & tz : airLoopHVAC->thermalZones() ) {
          auto eg = zoneList.pushExtensibleGroup();
          eg.setString(ZoneListExtensibleFields::ZoneName, tz.name().get());
        }
        LOG(Warn, "Defaulting the Control Zone List to all zones served by the AirLoopHVAC attached to "
               << modelObject.briefDescription());
        write_zonelist = true;
      } else {
        // Note: we never get here because the translation of the AVM:NightCyle isn't done if no AirLoopHVAC attached
        LOG(Error, "Control Zone List is expected for " << modelObject.briefDescription()
               << " but it cannot be defaulted because it isn't on an AirLoopHVAC");
        write_zonelist = false;
      }
    } else {
      if (n_controlThermalZones > 0) {
        if (n_controlThermalZones == 1) {
          // If only one, just write the thermalZone name directly
          write_zonelist = false;
          idfObject.setString(AvailabilityManager_NightCycleFields::ControlZoneorZoneListName,
                              controlThermalZones[0].name().get());
        } else {
          // More than one, we indeed create a zone list
          for (const ThermalZone& tz: controlThermalZones) {
            auto eg = zoneList.pushExtensibleGroup();
            eg.setString(ZoneListExtensibleFields::ZoneName, tz.name().get());
          }
          write_zonelist = true;
        }
      } else {
        // No zones = no zonelist
        write_zonelist = false;
      }
    }
    // Write ZoneList to the IDF and set the AVM ZoneList field to it only if something meaningful happened
    if (write_zonelist) {
      idfObject.setString(AvailabilityManager_NightCycleFields::ControlZoneorZoneListName, zoneListName);
      m_idfObjects.push_back(zoneList);
    }
  }


  // Cooling Control Thermal Zones
  {
    // Create a ZoneList, and populate it
    IdfObject zoneList(IddObjectType::ZoneList);
    std::string zoneListName = modelObject.name().get() + " Cooling Control Zones List";
    zoneList.setName(zoneListName);
    bool write_zonelist;

    if (default_coolingControlThermalZones) {
      // Get all zones served by the AirLoop attached to it
      if( airLoopHVAC ) {
        for( const ThermalZone & tz : airLoopHVAC->thermalZones() ) {
          auto eg = zoneList.pushExtensibleGroup();
          eg.setString(ZoneListExtensibleFields::ZoneName, tz.name().get());
        }
        LOG(Warn, "Defaulting the Cooling Control Zone List to all zones served by the AirLoopHVAC attached to "
               << modelObject.briefDescription());
        write_zonelist = true;
      } else {
        LOG(Error, "Cooling Control Zone List is expected for " << modelObject.briefDescription()
               << " but it cannot be defaulted because it isn't on an AirLoopHVAC");
        write_zonelist = false;
      }
    } else {
      if (n_coolingControlThermalZones > 0) {
        if (n_coolingControlThermalZones == 1) {
          // If only one, just write the thermalZone name directly
          write_zonelist = false;
          idfObject.setString(AvailabilityManager_NightCycleFields::CoolingControlZoneorZoneListName,
                              coolingControlThermalZones[0].name().get());
        } else {
          // More than one, we indeed create a zone list
          for (const ThermalZone& tz: coolingControlThermalZones) {
            auto eg = zoneList.pushExtensibleGroup();
            eg.setString(ZoneListExtensibleFields::ZoneName, tz.name().get());
          }
          write_zonelist = true;
        }
      } else {
        // No zones = no zonelist
        write_zonelist = false;
      }
    }
    // Write ZoneList to the IDF and set the AVM ZoneList field to it only if something meaningful happened
    if (write_zonelist) {
      idfObject.setString(AvailabilityManager_NightCycleFields::CoolingControlZoneorZoneListName, zoneListName);
      m_idfObjects.push_back(zoneList);
    }
  }


  // Heating Control Thermal Zones
  {
    // Create a ZoneList, and populate it
    IdfObject zoneList(IddObjectType::ZoneList);
    std::string zoneListName = modelObject.name().get() + " Heating Control Zones List";
    zoneList.setName(zoneListName);
    bool write_zonelist;

    if (default_heatingControlThermalZones) {
      // Get all zones served by the AirLoop attached to it
      if( airLoopHVAC ) {
        for( const ThermalZone & tz : airLoopHVAC->thermalZones() ) {
          auto eg = zoneList.pushExtensibleGroup();
          eg.setString(ZoneListExtensibleFields::ZoneName, tz.name().get());
        }
        LOG(Warn, "Defaulting the Heating Control Zone List to all zones served by the AirLoopHVAC attached to "
               << modelObject.briefDescription());
        write_zonelist = true;
      } else {
        LOG(Error, "Cooling Heating Zone List is expected for " << modelObject.briefDescription()
               << " but it cannot be defaulted because it isn't on an AirLoopHVAC");
        write_zonelist = false;
      }
    } else {
      if (n_heatingControlThermalZones > 0) {
        if (n_heatingControlThermalZones == 1) {
          // If only one, just write the thermalZone name directly
          write_zonelist = false;
          idfObject.setString(AvailabilityManager_NightCycleFields::HeatingControlZoneorZoneListName,
                              heatingControlThermalZones[0].name().get());
        } else {
          // More than one, we indeed create a zone list

          for (const ThermalZone& tz: heatingControlThermalZones) {
            auto eg = zoneList.pushExtensibleGroup();
            eg.setString(ZoneListExtensibleFields::ZoneName, tz.name().get());
          }
          write_zonelist = true;
        }
      } else {
        // No zones = no zonelist
        write_zonelist = false;
      }
    }
    // Write ZoneList to the IDF and set the AVM ZoneList field to it only if something meaningful happened
    if (write_zonelist) {
      idfObject.setString(AvailabilityManager_NightCycleFields::HeatingControlZoneorZoneListName, zoneListName);
      m_idfObjects.push_back(zoneList);
    }
  }

  // Heating Zone Fans Only Thermal Zones
  {
    // Create a ZoneList, and populate it
    IdfObject zoneList(IddObjectType::ZoneList);
    std::string zoneListName = modelObject.name().get() + " Heating Zone Fans Only Zones List";
    zoneList.setName(zoneListName);
    bool write_zonelist;

    if (default_heatingZoneFansOnlyThermalZones) {
      // Get all zones served by the AirLoop attached to it
      if( airLoopHVAC ) {
        for( const ThermalZone & tz : airLoopHVAC->thermalZones() ) {
          auto eg = zoneList.pushExtensibleGroup();
          eg.setString(ZoneListExtensibleFields::ZoneName, tz.name().get());
        }
        LOG(Warn, "Defaulting the Heating Zone Fans Only Zones List to all zones served by the AirLoopHVAC attached to "
               << modelObject.briefDescription());
        write_zonelist = true;
      } else {
        LOG(Error, "Heating Zone Fans Only Zones List is expected for " << modelObject.briefDescription()
               << " but it cannot be defaulted because it isn't on an AirLoopHVAC");
        write_zonelist = false;
      }
    } else {
      if (n_heatingZoneFansOnlyThermalZones > 0) {
        if (n_heatingZoneFansOnlyThermalZones == 1) {
          // If only one, just write the thermalZone name directly
          write_zonelist = false;
          idfObject.setString(AvailabilityManager_NightCycleFields::HeatingZoneFansOnlyZoneorZoneListName,
                              heatingZoneFansOnlyThermalZones[0].name().get());
        } else {
          // More than one, we indeed create a zone list
          for (const ThermalZone& tz: heatingZoneFansOnlyThermalZones) {
            auto eg = zoneList.pushExtensibleGroup();
            eg.setString(ZoneListExtensibleFields::ZoneName, tz.name().get());
          }
          write_zonelist = true;
        }
      } else {
        // No zones = no zonelist
        write_zonelist = false;
      }
    }
    // Write ZoneList to the IDF and set the AVM ZoneList field to it only if something meaningful happened
    if (write_zonelist) {
      idfObject.setString(AvailabilityManager_NightCycleFields::HeatingZoneFansOnlyZoneorZoneListName, zoneListName);
      m_idfObjects.push_back(zoneList);
    }
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateCoilSystemCoolingDXHeatExchangerAssisted( 
    CoilSystemCoolingDXHeatExchangerAssisted & modelObject)
{
  IdfObject idfObject(IddObjectType::CoilSystem_Cooling_DX_HeatExchangerAssisted);
  m_idfObjects.push_back(idfObject);

  // Name
  if( auto s = modelObject.name() ) {
    idfObject.setName(*s);
  }

  std::string hxSupplyAirInletNodeName;
  // InletNodeName
  if( auto mo = modelObject.inletModelObject() ) {
    if( auto node = mo->optionalCast<Node>() ) {
      hxSupplyAirInletNodeName = node->name().get();
    }
  }

  std::string hxExhaustAirOutletNodeName;
  // OutletNodeName
  if( auto mo = modelObject.outletModelObject() ) {
    if( auto node = mo->optionalCast<Node>() ) {
      hxExhaustAirOutletNodeName = node->name().get();
    }
  }

  std::string hxSupplyAirOutletNodeName = modelObject.name().get() + " HX Supply Air Outlet - Cooling Inlet Node";
  std::string hxExhaustAirInletNodeName = modelObject.name().get() + " HX Exhaust Air Inlet - Cooling Outlet Node";

  // HeatExchangerObjectType
  // HeatExchangerName
  {
    auto hx = modelObject.heatExchanger();
    if( auto idf = translateAndMapModelObject(hx) ) {
      idfObject.setString(CoilSystem_Cooling_DX_HeatExchangerAssistedFields::HeatExchangerObjectType,idf->iddObject().name());
      idfObject.setString(CoilSystem_Cooling_DX_HeatExchangerAssistedFields::HeatExchangerName,idf->name().get());
      if( idf->iddObject().type() == IddObjectType::HeatExchanger_AirToAir_SensibleAndLatent ) {
        idf->setString(HeatExchanger_AirToAir_SensibleAndLatentFields::SupplyAirInletNodeName,hxSupplyAirInletNodeName);
        idf->setString(HeatExchanger_AirToAir_SensibleAndLatentFields::SupplyAirOutletNodeName,hxSupplyAirOutletNodeName);
        idf->setString(HeatExchanger_AirToAir_SensibleAndLatentFields::ExhaustAirOutletNodeName,hxExhaustAirOutletNodeName);
        idf->setString(HeatExchanger_AirToAir_SensibleAndLatentFields::ExhaustAirInletNodeName,hxExhaustAirInletNodeName);
      }
    }
  }

  // CoolingCoilObjectType
  // CoolingCoilName
  {
    auto coolingCoil = modelObject.coolingCoil();
    if( auto idf = translateAndMapModelObject(coolingCoil) ) {
      idfObject.setString(CoilSystem_Cooling_DX_HeatExchangerAssistedFields::CoolingCoilObjectType,idf->iddObject().name());
      idfObject.setString(CoilSystem_Cooling_DX_HeatExchangerAssistedFields::CoolingCoilName,idf->name().get());
      if( idf->iddObject().type() == IddObjectType::Coil_Cooling_DX_SingleSpeed ) {
        idf->setString(Coil_Cooling_DX_SingleSpeedFields::AirInletNodeName,hxSupplyAirOutletNodeName);
        idf->setString(Coil_Cooling_DX_SingleSpeedFields::AirOutletNodeName,hxExhaustAirInletNodeName);
      } else if( idf->iddObject().type() == IddObjectType::Coil_Cooling_DX_MultiSpeed ) {
        idf->setString(Coil_Cooling_DX_MultiSpeedFields::AirInletNodeName,hxSupplyAirOutletNodeName);
        idf->setString(Coil_Cooling_DX_MultiSpeedFields::AirOutletNodeName,hxExhaustAirInletNodeName);
      } else if( idf->iddObject().type() == IddObjectType::Coil_Cooling_DX_SingleSpeed_ThermalStorage ) {
        idf->setString(Coil_Cooling_DX_SingleSpeed_ThermalStorageFields::CondenserAirInletNodeName,hxSupplyAirOutletNodeName);
        idf->setString(Coil_Cooling_DX_SingleSpeed_ThermalStorageFields::CondenserAirOutletNodeName,hxExhaustAirInletNodeName);
      } else if( idf->iddObject().type() == IddObjectType::Coil_Cooling_DX_TwoSpeed ) {
        idf->setString(Coil_Cooling_DX_TwoSpeedFields::AirInletNodeName,hxSupplyAirOutletNodeName);
        idf->setString(Coil_Cooling_DX_TwoSpeedFields::AirOutletNodeName,hxExhaustAirInletNodeName);
      } else if( idf->iddObject().type() == IddObjectType::Coil_Cooling_DX_TwoStageWithHumidityControlMode ) {
        idf->setString(Coil_Cooling_DX_TwoStageWithHumidityControlModeFields::AirInletNodeName,hxSupplyAirOutletNodeName);
        idf->setString(Coil_Cooling_DX_TwoStageWithHumidityControlModeFields::AirOutletNodeName,hxExhaustAirInletNodeName);
      } else if( idf->iddObject().type() == IddObjectType::Coil_Cooling_DX_VariableSpeed ) {
        idf->setString(Coil_Cooling_DX_VariableSpeedFields::IndoorAirInletNodeName,hxSupplyAirOutletNodeName);
        idf->setString(Coil_Cooling_DX_VariableSpeedFields::IndoorAirOutletNodeName,hxExhaustAirInletNodeName);
      }
    }
  }

  return idfObject;
}
boost::optional<IdfObject> ForwardTranslator::translateCoilHeatingWater( CoilHeatingWater & modelObject )
{
  boost::optional<std::string> s;
  boost::optional<double> value;

  IdfObject idfObject(IddObjectType::Coil_Heating_Water);

  m_idfObjects.push_back(idfObject);

  s = modelObject.name();
  if( s )
  {
    idfObject.setName(*s);
  }

  Schedule sched = modelObject.availableSchedule();
  boost::optional<IdfObject> _sched = translateAndMapModelObject(sched);
  if( _sched )
  {
    idfObject.setString(Coil_Heating_WaterFields::AvailabilityScheduleName,
                        _sched->name().get() );
  }

  // UFactorTimesAreaValue

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

  // MaximumWaterFlowRate

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

  // WaterInletNodeName

  if( boost::optional<ModelObject> mo = modelObject.waterInletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(Coil_Heating_WaterFields::WaterInletNodeName,node->name().get());
    }
  }

  // WaterOutletNodeName

  if( boost::optional<ModelObject> mo = modelObject.waterOutletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(Coil_Heating_WaterFields::WaterOutletNodeName,node->name().get());
    }
  }

  // AirInletNodeName

  if( boost::optional<ModelObject> mo = modelObject.airInletModelObject() )
  {
    if( boost::optional<Node> node = mo->optionalCast<Node>() )
    {
      idfObject.setString(Coil_Heating_WaterFields::AirInletNodeName,node->name().get());
    }
  }

  // AirOutletNodeName

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

  // PerformanceInputMethod

  s = modelObject.performanceInputMethod();
  if( s )
  {
    idfObject.setString(Coil_Heating_WaterFields::PerformanceInputMethod,s.get());
  }

  // RatedCapacity

  if( modelObject.isRatedCapacityAutosized() )
  {
    idfObject.setString(Coil_Heating_WaterFields::RatedCapacity,"Autosize");
  }
  else if( (value = modelObject.ratedCapacity()) )
  {
    idfObject.setDouble(Coil_Heating_WaterFields::RatedCapacity,value.get());
  }

  // RatedInletWaterTemperature

  if( (value = modelObject.ratedInletWaterTemperature()) )
  {
    idfObject.setDouble(Coil_Heating_WaterFields::RatedInletWaterTemperature,value.get());
  }

  // RatedInletAirTemperature

  if( (value = modelObject.ratedInletAirTemperature()) )
  {
    idfObject.setDouble(Coil_Heating_WaterFields::RatedInletAirTemperature,value.get());
  }

  // RatedOutletWaterTemperature

  if( (value = modelObject.ratedOutletWaterTemperature()) )
  {
    idfObject.setDouble(Coil_Heating_WaterFields::RatedOutletWaterTemperature,value.get());
  }

  // RatedOutletAirTemperature

  if( (value = modelObject.ratedOutletAirTemperature()) )
  {
    idfObject.setDouble(Coil_Heating_WaterFields::RatedOutletAirTemperature,value.get());
  }

  // RatedRatioforAirandWaterConvection

  if( (value = modelObject.ratedRatioForAirAndWaterConvection()) )
  {
    idfObject.setDouble(Coil_Heating_WaterFields::RatedRatioforAirandWaterConvection,value.get());
  }
  
  return boost::optional<IdfObject>(idfObject);
}
Пример #30
0
bool TreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
  bool success = false;

  if(action != Qt::CopyAction) return success;

 TreeItem * parentItem = getItem(parent);
 OS_ASSERT(parentItem);

 if(data->hasText()){
    if(!data->hasFormat("ListWidget data")) return success;
    QString string = data->text();
    QStringList strings = string.split(",");
    openstudio::IddFile iddFile = mTreeViewWidget->getIddFile();
    boost::optional<openstudio::IddObject> optionalIddObject;

    openstudio::OptionalWorkspaceObject optionalWorkspaceObject;
    openstudio::model::OptionalModelObject optionalModelObject;
    openstudio::model::OptionalParentObject optionalParentObject;
    for(int i=0; i<strings.size(); i++)
    {
      optionalIddObject = iddFile.getObject(strings.at(i).toStdString());
      if(optionalIddObject)
      {
        openstudio::IdfObject idfObject(optionalIddObject->type());
        optionalWorkspaceObject = mTreeViewWidget->getModel().addObject(idfObject);
        if(optionalWorkspaceObject)
        {
          optionalModelObject = parentItem->modelObject().model().getModelObject<ModelObject>(optionalWorkspaceObject->handle());
          if(optionalModelObject)
          {
            ///! OpenStudio model update...
            ModelObject temp(parentItem->modelObject());
            if(OptionalParentObject tempParent = temp.optionalCast<ParentObject>())
            {
              success = optionalModelObject->setParent(*tempParent);
            }
            if(success)
            {
              success = mTreeViewWidget->getModel().order().insert(optionalWorkspaceObject->handle(), this->modelAtIndex(parent)->handle());
            }
          }
        }
      }
    }
  }
  else{
    OS_ASSERT(mTreeViewWidget && mTreeViewWidget->getTreeView());
    QModelIndexList rowList;
    if(!mTreeViewWidget->getTreeView()->getSelectedRows(rowList)){
      return success;
    }

    //FIX THIS why is position unused? LER
    //int position = rowList.at(0).row();
    int rows = rowList.size();
    //QModelIndex sourceParent = rowList.at(0).parent();

    TreeItem * parentItem = getItem(parent);

    ///! OpenStudio model update...
    for(int i=0; i<rows; i++){
      ModelObject temp(parentItem->modelObject());
      if(OptionalParentObject tempParent = temp.optionalCast<ParentObject>())
      {
        success = this->modelAtIndex(rowList.at(i))->setParent(*tempParent);
      }
    }
  }

  mTreeViewWidget->loadModel();
  mTreeViewWidget->emitModelDirty();

  return success; // not updating Qt model
}