boost::optional<IdfObject> ForwardTranslator::translateMaterialPropertyGlazingSpectralData( MaterialPropertyGlazingSpectralData & modelObject )
{
  IdfObject idfObject(openstudio::IddObjectType::MaterialProperty_GlazingSpectralData);

  m_idfObjects.push_back(idfObject);

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

  idfObject.clearExtensibleGroups();
  for (const auto& spectralDataField : modelObject.spectralDataFields()){
    IdfExtensibleGroup group = idfObject.pushExtensibleGroup();
    OS_ASSERT(group.numFields() == 4);
    group.setDouble(MaterialProperty_GlazingSpectralDataExtensibleFields::Wavelength, spectralDataField.wavelength());
    group.setDouble(MaterialProperty_GlazingSpectralDataExtensibleFields::transmittance, spectralDataField.transmittance());
    group.setDouble(MaterialProperty_GlazingSpectralDataExtensibleFields::frontreflectance, spectralDataField.frontReflectance());
    group.setDouble(MaterialProperty_GlazingSpectralDataExtensibleFields::backreflectance, spectralDataField.backReflectance());
  }

  return boost::optional<IdfObject>(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::translateShadingSurface( model::ShadingSurface & modelObject )
{
  boost::optional<IdfObject> idfObject;

  boost::optional<Schedule> transmittanceSchedule = modelObject.transmittanceSchedule();
  Transformation transformation;
  Point3dVector points;

  boost::optional<ShadingSurfaceGroup> shadingSurfaceGroup = modelObject.shadingSurfaceGroup();
  if (shadingSurfaceGroup){

    transformation = shadingSurfaceGroup->transformation();
    points = transformation * modelObject.vertices();

    if (istringEqual("Space", shadingSurfaceGroup->shadingSurfaceType())){

      idfObject = IdfObject(openstudio::IddObjectType::Shading_Zone_Detailed);
      idfObject->setString(Shading_Zone_DetailedFields::Name, modelObject.name().get());

      boost::optional<Space> space = shadingSurfaceGroup->space();
      if (space){
        
        boost::optional<Surface> baseSurface;
        double minDistance = std::numeric_limits<double>::max();

        // at this point zone has one space and internal surfaces have already been combined
        for (const Surface& surface : space->surfaces()){
          if (istringEqual(surface.outsideBoundaryCondition(), "Outdoors")){
            Point3dVector surfaceVertices = surface.vertices();
            for (const Point3d& point : points){
              for (const Point3d& surfaceVertex : surfaceVertices){
                double distance = getDistance(point, surfaceVertex);
                if (distance < minDistance){
                  baseSurface = surface;
                  minDistance = distance;
                }
              }
            }
          }
        }

        if (!baseSurface){
          LOG(Error, "Cannot find appropriate base surface for shading surface '" << modelObject.name().get() << 
                     "', the shading surface will not be translated");
          return boost::none;
        }

        idfObject->setString(Shading_Zone_DetailedFields::BaseSurfaceName, baseSurface->name().get());
      }

      if (transmittanceSchedule){
        idfObject->setString(Shading_Zone_DetailedFields::TransmittanceScheduleName, transmittanceSchedule->name().get());
      }

    }else if (istringEqual("Site", shadingSurfaceGroup->shadingSurfaceType())){

      idfObject = IdfObject(openstudio::IddObjectType::Shading_Site_Detailed);
      idfObject->setString(Shading_Site_DetailedFields::Name, modelObject.name().get());
      
      if (transmittanceSchedule){
        idfObject->setString(Shading_Site_DetailedFields::TransmittanceScheduleName, transmittanceSchedule->name().get());
      }

    }else{
      boost::optional<Building> building = modelObject.model().getUniqueModelObject<Building>();
      if (building){
        transformation = building->transformation().inverse()*transformation;
      }

      idfObject = IdfObject(openstudio::IddObjectType::Shading_Building_Detailed);
      idfObject->setString(Shading_Building_DetailedFields::Name, modelObject.name().get());
      
      if (transmittanceSchedule){
        idfObject->setString(Shading_Building_DetailedFields::TransmittanceScheduleName, transmittanceSchedule->name().get());
      }
    }

  }else{
    idfObject = IdfObject(openstudio::IddObjectType::Shading_Building_Detailed);
    idfObject->setString(Shading_Building_DetailedFields::Name, modelObject.name().get());
    
    if (transmittanceSchedule){
      idfObject->setString(Shading_Building_DetailedFields::TransmittanceScheduleName, transmittanceSchedule->name().get());
    }
  }

  m_idfObjects.push_back(*idfObject);

  idfObject->clearExtensibleGroups();

  for (const Point3d& point : points){
    IdfExtensibleGroup group = idfObject->pushExtensibleGroup();
    OS_ASSERT(group.numFields() == 3);
    group.setDouble(0, point.x());
    group.setDouble(1, point.y());
    group.setDouble(2, point.z());
  }

  // get reflectance properties from construction if possible
  bool addShadingPropertyObject = false;

  IdfObject shadingPropertyObject = IdfObject(openstudio::IddObjectType::ShadingProperty_Reflectance);
  shadingPropertyObject.setString(ShadingProperty_ReflectanceFields::ShadingSurfaceName, modelObject.name().get());

  boost::optional<model::ConstructionBase> constructionBase = modelObject.construction();
  if (constructionBase){
    if (constructionBase->isFenestration()){

      shadingPropertyObject.setDouble(ShadingProperty_ReflectanceFields::FractionofShadingSurfaceThatIsGlazed, 1.0);
      shadingPropertyObject.setString(ShadingProperty_ReflectanceFields::GlazingConstructionName, constructionBase->name().get());
      addShadingPropertyObject = true;

    }else{

      shadingPropertyObject.setDouble(ShadingProperty_ReflectanceFields::FractionofShadingSurfaceThatIsGlazed, 0.0);

      boost::optional<model::Construction> construction = constructionBase->optionalCast<model::Construction>();
      if (construction){

        std::vector<model::Material> layers = construction->layers();

        // we want the outer layer
        if (!layers.empty()){

          if (layers[0].optionalCast<model::StandardOpaqueMaterial>()){
            model::StandardOpaqueMaterial outerMaterial = layers[0].cast<model::StandardOpaqueMaterial>();

            boost::optional<double> solRefl = outerMaterial.solarReflectance();
            if (solRefl){
              shadingPropertyObject.setDouble(ShadingProperty_ReflectanceFields::DiffuseSolarReflectanceofUnglazedPartofShadingSurface, *solRefl);
              addShadingPropertyObject = true;
            }

            boost::optional<double> visRefl = outerMaterial.visibleReflectance();
            if (visRefl){
              shadingPropertyObject.setDouble(ShadingProperty_ReflectanceFields::DiffuseVisibleReflectanceofUnglazedPartofShadingSurface, *visRefl);
              addShadingPropertyObject = true;
            }
          }

          
          if (layers[0].optionalCast<model::MasslessOpaqueMaterial>()){
            model::MasslessOpaqueMaterial outerMaterial = layers[0].cast<model::MasslessOpaqueMaterial>();

            boost::optional<double> solRefl = outerMaterial.solarReflectance();
            if (solRefl){
              shadingPropertyObject.setDouble(ShadingProperty_ReflectanceFields::DiffuseSolarReflectanceofUnglazedPartofShadingSurface, *solRefl);
              addShadingPropertyObject = true;
            }

            boost::optional<double> visRefl = outerMaterial.visibleReflectance();
            if (visRefl){
              shadingPropertyObject.setDouble(ShadingProperty_ReflectanceFields::DiffuseVisibleReflectanceofUnglazedPartofShadingSurface, *visRefl);
              addShadingPropertyObject = true;
            }
          }

        }
      }
    }
  }

  if (addShadingPropertyObject){
    m_idfObjects.push_back(shadingPropertyObject);
  }

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

  IdfObject idfObject(IddObjectType::ZoneHVAC_LowTemperatureRadiant_VariableFlow);
  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_VariableFlowFields::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_VariableFlowFields::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_VariableFlowFields::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_VariableFlowFields::HydronicTubingInsideDiameter,value.get());
  }

  //field Hydronic Tubing Length
  if( modelObject.isHydronicTubingLengthAutosized() )
  {
    idfObject.setString(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::HydronicTubingLength,"Autosize");
  }
  else if( (value = modelObject.hydronicTubingLength()) )
  {
    idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::HydronicTubingLength,value.get());
  }

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

  // Heating Coil
  HVACComponent heatingCoil = modelObject.heatingCoil();
  boost::optional<CoilHeatingLowTempRadiantVarFlow>  coilOptionalHeating = heatingCoil.optionalCast<CoilHeatingLowTempRadiantVarFlow>();

  if (coilOptionalHeating)
  {
    CoilHeatingLowTempRadiantVarFlow coilHeat = *coilOptionalHeating;

    // Heating Design Capacity Method - introduced in 8.2.0 and not yet supported in OS
    idfObject.setString(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::HeatingDesignCapacityMethod,"HeatingDesignCapacity");

    // Heating Design Capacity - introduced in 8.2.0 and not yet supported in OS
    idfObject.setString(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::HeatingDesignCapacity,"Autosize");
    
    // field Maximum Hot Water Flow
    if( coilHeat.isMaximumHotWaterFlowAutosized() )
    {
        idfObject.setString(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::MaximumHotWaterFlow,"Autosize");
    }
    else if( (value = coilHeat.maximumHotWaterFlow()) )
    {
        idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::MaximumHotWaterFlow,value.get());
    }

    // field Heating Water Inlet Node Name
    temp = coilHeat.inletModelObject();
    if(temp)
    {
      s = temp->name();
      if(s)
      {
        idfObject.setString(openstudio::ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::HeatingWaterInletNodeName,*s);
      }
    }

    //field Heating Water Outlet Node Name
    temp = coilHeat.outletModelObject();
    if(temp)
    {
      s = temp->name();
      if(s)
      {
        idfObject.setString(openstudio::ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::HeatingWaterOutletNodeName,*s);
      }
    }

    //field Heating Control Throttling Range
    if( (value = coilHeat.heatingControlThrottlingRange()) )
    {
        idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::HeatingControlThrottlingRange,value.get());
    }

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

  // Cooling Coil
  HVACComponent coolingCoil = modelObject.coolingCoil();
  boost::optional<CoilCoolingLowTempRadiantVarFlow>  coilOptionalCooling = coolingCoil.optionalCast<CoilCoolingLowTempRadiantVarFlow>();

  if (coilOptionalCooling)
  {
    CoilCoolingLowTempRadiantVarFlow coilCool = *coilOptionalCooling;

    // Cooling Design Capacity Method - introduced in 8.2.0 and not yet supported in OS
    idfObject.setString(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::CoolingDesignCapacityMethod,"CoolingDesignCapacity");

    // Cooling Design Capacity - introduced in 8.2.0 and not yet supported in OS
    idfObject.setString(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::CoolingDesignCapacity,"Autosize");

    // Field Maximum Cold Water Flow
    if( coilCool.isMaximumColdWaterFlowAutosized() )
    {
      idfObject.setString(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::MaximumColdWaterFlow,"Autosize");
    }
    else if( (value = coilCool.maximumColdWaterFlow()) )
    {
      idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::MaximumColdWaterFlow,value.get());
    }

    // field Cooling Water Inlet Node Name
    temp = coilCool.inletModelObject();
    if(temp)
    {
      s = temp->name();
      if(s)
      {
        idfObject.setString(openstudio::ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::CoolingWaterInletNodeName,*s);
      }
    }

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

    //field Cooling Control Throttling Range

    if( (value = coilCool.coolingControlThrottlingRange()) )
    {
      idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::CoolingControlThrottlingRange,value.get());
    }

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

    //field Condensation Control Type
    idfObject.setString(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::CondensationControlType,coilCool.condensationControlType());

    //field Condensation Control Dewpoint Offset
    if( (value = coilCool.condensationControlDewpointOffset()) )
    {
      idfObject.setDouble(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::CondensationControlDewpointOffset,value.get());
    }
  }

  //field Number of Circuits
  idfObject.setString(ZoneHVAC_LowTemperatureRadiant_VariableFlowFields::NumberofCircuits,modelObject.numberofCircuits());

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

  return idfObject;
}