Example #1
0
TEST_F(IdfFixture, IdfObject_NameGetterWithReturnDefaultOption) {
  // OBJECT WITH DEFAULT NAME
  std::stringstream text;
  text << "Building," << std::endl
    << "," << std::endl
    << "," << std::endl
    << "," << std::endl
    << "," << std::endl
    << "," << std::endl
    << "," << std::endl
    << ";";
  OptionalIdfObject oObj = IdfObject::load(text.str());
  ASSERT_TRUE(oObj);
  IdfObject object = *oObj;
  OptionalString name = object.name();
  ASSERT_TRUE(name);
  EXPECT_TRUE(name->empty());
  name = object.name(true);
  ASSERT_TRUE(name);
  EXPECT_EQ("NONE",*name);
  object.setName("MyBuilding");
  name = object.name();
  ASSERT_TRUE(name);
  EXPECT_EQ("MyBuilding",*name);
  OptionalString name2 = object.name(true);
  ASSERT_TRUE(name2);
  EXPECT_EQ(*name,*name2);
}
 std::string EnergyManagementSystemProgramCallingManager_Impl::callingPoint() const {
   OptionalString results = getString(OS_EnergyManagementSystem_ProgramCallingManagerFields::EnergyPlusModelCallingPoint,true);
   if (results) {
     return results.get();
   }
   return "";
 }
bool IdfExtensibleGroup::isEmpty(unsigned fieldIndex) const
{
  OptionalString test = this->getString(fieldIndex, false);
  if (!test || test.get() == ""){
    return true;
  }
  return false;
}
  void WeatherFileFinder::extractDetails(
      const IdfFile &t_idffile,
      ToolVersion &t_version,
      boost::optional<std::string> &t_filelocationname,
      boost::optional<std::string> &t_weatherfilename)
  {
    IdfObjectVector versionObjects = t_idffile.getObjectsByType(IddObjectType::Version);
    if(versionObjects.size() == 1){
      OptionalString version = versionObjects[0].getString(VersionFields::VersionIdentifier, true);
      if (version){
        boost::regex majorMinorBuildRegex("^(\\d*?)\\.(\\d*?)\\.(\\d*?)$");
        boost::regex majorMinorRegex("^(\\d*?)\\.(\\d*?)$");
        boost::regex majorRegex("^(\\d*?)$");

        boost::smatch matches;
        if (boost::regex_search(*version, matches, majorMinorBuildRegex)){
          unsigned major = boost::lexical_cast<unsigned>(std::string(matches[1].first, matches[1].second));
          unsigned minor = boost::lexical_cast<unsigned>(std::string(matches[2].first, matches[2].second));
          unsigned build = boost::lexical_cast<unsigned>(std::string(matches[3].first, matches[3].second));
          t_version = ToolVersion(major, minor, build);
        }else if(boost::regex_search(*version, matches, majorMinorRegex)){
          unsigned major = boost::lexical_cast<unsigned>(std::string(matches[1].first, matches[1].second));
          unsigned minor = boost::lexical_cast<unsigned>(std::string(matches[2].first, matches[2].second));
          t_version = ToolVersion(major, minor);
        }else if(boost::regex_search(*version, matches, majorRegex)){
          unsigned major = boost::lexical_cast<unsigned>(std::string(matches[1].first, matches[1].second));
          t_version = ToolVersion(major);
        }
      }
    }

    IdfObjectVector locationObjects = t_idffile.getObjectsByType(IddObjectType::Site_Location);
    if(locationObjects.size() == 1){
      OptionalString locationname = locationObjects[0].getString(Site_LocationFields::Name, true);
      if (locationname && !locationname->empty()){
        LOG(Debug, "Location name field from IDF: " << *locationname);
        t_filelocationname = locationname;
      }
    }

    std::string header = t_idffile.header();
    std::vector<std::string> headerlines;
    boost::split(headerlines, header, boost::is_any_of("\n\r"), boost::algorithm::token_compress_on);
    for (std::vector<std::string>::const_iterator itr = headerlines.begin();
         itr != headerlines.end();
         ++itr)
    {
      boost::smatch matches;
     
      if (boost::regex_match(*itr, matches, boost::regex(".*!\\s+WeatherFileName=(.*)"),boost::regex_constants::match_all))
      {
        std::string match = matches[1];
        t_weatherfilename = match;
        break;
      }
    }
  }
Example #5
0
TEST_F(DataFixture, Attribute_DisplayName) {
  Attribute attribute("WWR",0.23);
  OptionalString displayName = attribute.displayName();
  EXPECT_FALSE(displayName);
  displayName = attribute.displayName(true);
  ASSERT_TRUE(displayName);
  EXPECT_EQ("WWR",displayName.get());
  attribute.setDisplayName("Window-to-wall ratio (ratio of fenestration area to gross surface area).");
  displayName = attribute.displayName(true);
  ASSERT_TRUE(displayName);
  EXPECT_NE("WWR",displayName.get());
}
Example #6
0
TEST_F(ModelFixture, ComponentWatcher_BadComponentDataFromWorkspace) {
  Workspace ws;
  OptionalWorkspaceObject owo = ws.addObject(IdfObject(IddObjectType::OS_ComponentData));
  ASSERT_TRUE(owo);
  // make component data ok except points to non-existent object
  WorkspaceObject cd = *owo;
  OptionalString oName = cd.name(); // should have been set by constructor
  ASSERT_TRUE(oName);
  EXPECT_FALSE(oName->empty());
  cd.setString(OS_ComponentDataFields::UUID,toString(createUUID()));
  cd.setString(OS_ComponentDataFields::VersionUUID,toString(createUUID()));
  StringVector values;
  values.push_back("My Material");
  IdfExtensibleGroup eg = cd.pushExtensibleGroup(values);
  EXPECT_TRUE(eg.empty()); // Cannot register a bad pointer.

  EXPECT_EQ(1u,ws.numObjects());
  Model model(ws);
  // expect ComponentWatcher creation to kick out ComponentData
  EXPECT_EQ(0u,model.numObjects());
}
boost::optional<IdfObject> ForwardTranslator::translateDaylightingDeviceShelf( model::DaylightingDeviceShelf & modelObject )
{
  IdfObject idfObject(openstudio::IddObjectType::DaylightingDevice_Shelf);

  m_idfObjects.push_back(idfObject);

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

  OptionalString s = modelObject.getString(OS_DaylightingDevice_ShelfFields::WindowName, false, true);
  if (s){
    idfObject.setString(DaylightingDevice_ShelfFields::WindowName, *s);
  }else{
    LOG(Error, "Missing required input 'Window Name' for DaylightingDevice:Shelf named '" << modelObject.name().get() << "'");
  }

  // TODO: make sure inside shelf is converted to a surface
  s = modelObject.getString(OS_DaylightingDevice_ShelfFields::InsideShelfName, false, true);
  if (s){
    idfObject.setString(DaylightingDevice_ShelfFields::InsideShelfName, *s);
  }

  s = modelObject.getString(OS_DaylightingDevice_ShelfFields::OutsideShelfName, false, true);
  if (s){
    idfObject.setString(DaylightingDevice_ShelfFields::OutsideShelfName, *s);
  }

  // TODO: map construction from shading surface
  s.reset();
  if (s){
    idfObject.setString(DaylightingDevice_ShelfFields::OutsideShelfConstructionName, *s);
  }

  OptionalDouble d = modelObject.getDouble(OS_DaylightingDevice_ShelfFields::ViewFactortoOutsideShelf, false);
  if (d){
    idfObject.setDouble(DaylightingDevice_ShelfFields::ViewFactortoOutsideShelf, *d);
  }

  return boost::none;
}
TEST_F(IdfFixture, IdfObject_StringFieldGetterWithReturnDefaultOption) {
  // NON-EXTENSIBLE OBJECT
  std::stringstream text;
  text << "Refrigeration:Condenser:AirCooled," << std::endl
       << "  MyCondenser," << std::endl
       << "  ," << std::endl
       << "  ," << std::endl // default is 0.0
       << "  ," << std::endl // default is "Fixed"
       << "  125.0;";        // default is 250.0
                             // default is 0.2
                             //
                             // default is "General"
                             // default is 0.0
                             // default is 0.0
                             // default is 0.0
  OptionalIdfObject oObj = IdfObject::load(text.str());
  ASSERT_TRUE(oObj);
  IdfObject object = *oObj;

  // returns set values
  OptionalString idfField = object.getString(0,true);
  ASSERT_TRUE(idfField);
  EXPECT_EQ("MyCondenser",*idfField);
  idfField = object.getString(1,true);
  ASSERT_TRUE(idfField);
  EXPECT_EQ("",*idfField);
  idfField = object.getString(4,true);
  ASSERT_TRUE(idfField);
  EXPECT_EQ("125.0",*idfField);

  // returns default for fields behind fields with set values
  idfField = object.getString(2,true);
  ASSERT_TRUE(idfField);
  EXPECT_EQ("0.0",*idfField);
  idfField = object.getString(3,true);
  ASSERT_TRUE(idfField);
  EXPECT_EQ("Fixed",*idfField);

  // returns default for non-existent fields
  idfField = object.getString(6,true);
  EXPECT_FALSE(idfField);
  idfField = object.getString(7,true);
  ASSERT_TRUE(idfField);
  EXPECT_EQ("General",*idfField);
  idfField = object.getString(8,true);
  ASSERT_TRUE(idfField);
  EXPECT_EQ("0.0",*idfField);
  idfField = object.getString(10,true);
  ASSERT_TRUE(idfField);
  EXPECT_EQ("0.0",*idfField);
  idfField = object.getString(11,true);
  EXPECT_FALSE(idfField);

  // EXTENSIBLE OBJECT
  text.str("");
  text << "DaylightingDevice:Tubular," << std::endl
       << "  MyTDD," << std::endl
       << "  MyDome," << std::endl
       << "  MyDiffuser," << std::endl
       << "  MyConstruction," << std::endl
       << "  1.0," << std::endl
       << "  2.0;";
       // \default 0.28
       // Transition Zone 1 Name
       // Transition Zone 1 Length
       // ... (extensible 2)
  oObj = IdfObject::load(text.str());
  ASSERT_TRUE(oObj);
  object = *oObj;
  EXPECT_EQ(6u,object.numFields());

  // returns set values
  idfField = object.getString(0,true);
  ASSERT_TRUE(idfField);
  EXPECT_EQ("MyTDD",*idfField);
  idfField = object.getString(5,true);
  ASSERT_TRUE(idfField);
  EXPECT_EQ("2.0",*idfField);

  // returns default for non-existent, non-extensible fields
  idfField = object.getString(6,true);
  ASSERT_TRUE(idfField);
  EXPECT_EQ("0.28",*idfField);
  EXPECT_EQ(6u,object.numFields());
  idfField = object.getString(6);
  EXPECT_FALSE(idfField);

  StringVector newGroup;
  newGroup.push_back("MyFirstTransistionZone");
  newGroup.push_back("1.5");
  ASSERT_FALSE(object.pushExtensibleGroup(newGroup).empty());

  // returns default for fields behind fields with set values
  idfField = object.getString(6,true);
  ASSERT_TRUE(idfField);
  EXPECT_EQ("0.28",*idfField);
  idfField = object.getString(6);
  ASSERT_TRUE(idfField);
  EXPECT_TRUE(idfField->empty());

  // return evaluates to false for extensible fields that do not exist
  idfField = object.getString(10);
  EXPECT_FALSE(idfField);
}
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;
}
OptionalModelObject ReverseTranslator::translateEnergyManagementSystemSubroutine(const WorkspaceObject & workspaceObject)
{
  if (workspaceObject.iddObject().type() != IddObjectType::EnergyManagementSystem_Subroutine) {
    LOG(Error, "WorkspaceObject is not IddObjectType: EnergyManagementSystem_Subroutine");
    return boost::none;
  }

  OptionalString s = workspaceObject.getString(EnergyManagementSystem_SubroutineFields::Name);
  if (!s) {
    LOG(Error, "WorkspaceObject EnergyManagementSystem_Subroutine has no Name");
    return boost::none;
  }

  // Make sure we translate the objects that can be referenced here
  for (const WorkspaceObject& workspaceObject : m_workspace.objects()) {

    // Note: JM 2018-08-17
    // I think an EMS:Subroutine can reference another EMS:Subroutine, we might get problems from that:
    // The one that is being referenced would need be translated before the one that references before the name/uuid substitution happen.
    // But it's harder to control that order*, and this is really an edge case though, so not handling it.
    // * Can't add this condition without getting into a loop:
    // (workspaceObject.iddObject().type() == IddObjectType::EnergyManagementSystem_Subroutine)
    if (
        // These I'm sure we do need.
        (workspaceObject.iddObject().type() == IddObjectType::EnergyManagementSystem_Actuator)
        || (workspaceObject.iddObject().type() == IddObjectType::EnergyManagementSystem_Sensor)
        || (workspaceObject.iddObject().type() == IddObjectType::EnergyManagementSystem_ConstructionIndexVariable)
        || (workspaceObject.iddObject().type() == IddObjectType::EnergyManagementSystem_CurveOrTableIndexVariable)
        || (workspaceObject.iddObject().type() == IddObjectType::EnergyManagementSystem_GlobalVariable)
        || (workspaceObject.iddObject().type() == IddObjectType::EnergyManagementSystem_InternalVariable)
        || (workspaceObject.iddObject().type() == IddObjectType::EnergyManagementSystem_TrendVariable)
       ) {
      translateAndMapWorkspaceObject(workspaceObject);
    }
  }
  openstudio::model::EnergyManagementSystemSubroutine emsProgram(m_model);
  emsProgram.setName(*s);

  // Get all model objects that can be referenced int he EMS Program so we can do name / uid substitution
  const std::vector<IddObjectType> validIddObjectTypes{
    IddObjectType::OS_EnergyManagementSystem_Subroutine,
    IddObjectType::OS_EnergyManagementSystem_Actuator,
    IddObjectType::OS_EnergyManagementSystem_Sensor,
    IddObjectType::OS_EnergyManagementSystem_ConstructionIndexVariable,
    IddObjectType::OS_EnergyManagementSystem_CurveOrTableIndexVariable,
    IddObjectType::OS_EnergyManagementSystem_GlobalVariable,
    IddObjectType::OS_EnergyManagementSystem_InternalVariable,
    IddObjectType::OS_EnergyManagementSystem_TrendVariable
  };

  std::vector<model::ModelObject> modelObjects;
  for (const model::ModelObject& mo: m_model.modelObjects()) {
    if( std::find(validIddObjectTypes.begin(), validIddObjectTypes.end(), mo.iddObjectType()) != validIddObjectTypes.end() ) {
      modelObjects.push_back(mo);
    }
  }


  // Now, we should do the actual name/uid substitution on all lines of the program

  size_t pos, len;
  std::string newline, uid;

  unsigned n = workspaceObject.numExtensibleGroups();
  OptionalString line;

  // Loop on each line of the program
  for (unsigned i = 0; i < n; ++i) {
    line = workspaceObject.getExtensibleGroup(i).cast<WorkspaceExtensibleGroup>().getString(EnergyManagementSystem_SubroutineExtensibleFields::ProgramLine);
    if (line) {
      newline = line.get();

      // Split line to get 'tokens' and look for ModelObject names
      // splitEMSLineToTokens returns already sanitized tokens (excludes reserved keywords, blank ones, functions, removes parenthesis, etc)
      std::vector<std::string> tokens = splitEMSLineToTokens(newline);

      for (std::string& token: tokens) {
        for (const model::ModelObject& mo: modelObjects) {
          // Check if program item is the name of a model object
          boost::optional<std::string> _name = mo.name();
          if ( _name && (_name.get() == token) ) {
            // replace model object's name with its handle
            pos = newline.find(token);
            len = token.length();
            uid = toString(mo.handle());
            newline.replace(pos, len, uid);
            // Now that we have done the replacement, no need to keep looping.
            // Plus, we should break out of the nested loop and go to the next "j"
            // Otherwise pos could become giberish if there's another object named the same
            // since it won't be able to find the already-replaced string (this shouldn't happen though)
            break;
          }
        } // end loop on all modelObjects

      } // end loop on all results in line
      emsProgram.addLine(newline);
    } // end if(line)
  } // End loop on each line of the program

  return emsProgram;

}
boost::optional<IdfObject> ForwardTranslator::translateControllerOutdoorAir( ControllerOutdoorAir& modelObject )
{
  OptionalString s;
  OptionalDouble d;

  // Create a new IddObjectType::AirLoopHVAC_OutdoorAirSystem
  IdfObject idfObject(IddObjectType::Controller_OutdoorAir);

  m_idfObjects.push_back(idfObject);

  ///////////////////////////////////////////////////////////////////////////
  // Field: Name ////////////////////////////////////////////////////////////
  s = modelObject.name();
  if(s)
  {
    idfObject.setString(openstudio::Controller_OutdoorAirFields::Name,*s);
  }
  ///////////////////////////////////////////////////////////////////////////
  // Field: Relief Air Outlet Node Name /////////////////////////////////////
  s = modelObject.airLoopHVACOutdoorAirSystem()->reliefAirModelObject()->name();
  if(s)
  {
    idfObject.setString( openstudio::Controller_OutdoorAirFields::ReliefAirOutletNodeName,*s );
  }

  ///////////////////////////////////////////////////////////////////////////
  // Field: Return Air Outlet Node Name /////////////////////////////////////
  s = modelObject.airLoopHVACOutdoorAirSystem()->returnAirModelObject()->name();
  if(s)
  {
    idfObject.setString( openstudio::Controller_OutdoorAirFields::ReturnAirNodeName,*s );
  }

  ///////////////////////////////////////////////////////////////////////////
  // Field: Mixed Air Outlet Node Name //////////////////////////////////////
  s = modelObject.airLoopHVACOutdoorAirSystem()->mixedAirModelObject()->name();
  if(s)
  {
    idfObject.setString( openstudio::Controller_OutdoorAirFields::MixedAirNodeName,*s );
  }

  ///////////////////////////////////////////////////////////////////////////
  // Field: Actuator Node Name //////////////////////////////////////////////
  s = modelObject.airLoopHVACOutdoorAirSystem()->outboardOANode()->name();
  if(s)
  {
    idfObject.setString( openstudio::Controller_OutdoorAirFields::ActuatorNodeName,*s );
  }

  ///////////////////////////////////////////////////////////////////////////
  // Field: Minimum Outdoor Air Flow Rate ///////////////////////////////////
  if( modelObject.controllerMechanicalVentilation().demandControlledVentilation() )
  {
    idfObject.setDouble(openstudio::Controller_OutdoorAirFields::MinimumOutdoorAirFlowRate,0.0);
  }
  else
  {
    d = modelObject.minimumOutdoorAirFlowRate();
    if(d)
    {
      idfObject.setDouble(openstudio::Controller_OutdoorAirFields::MinimumOutdoorAirFlowRate,*d);
    }
    else
    {
      idfObject.setString(openstudio::Controller_OutdoorAirFields::MinimumOutdoorAirFlowRate,"Autosize");
    }
  }

  ///////////////////////////////////////////////////////////////////////////
  // Field: Maximum Outdoor Air Flow Rate ///////////////////////////////////
  d = modelObject.maximumOutdoorAirFlowRate();
  if(d)
  {
    idfObject.setDouble(openstudio::Controller_OutdoorAirFields::MaximumOutdoorAirFlowRate,*d);
  }
  else
  {
    idfObject.setString(openstudio::Controller_OutdoorAirFields::MaximumOutdoorAirFlowRate,"Autosize");
  }

  ///////////////////////////////////////////////////////////////////////////
  // Field: Economizer Control Type /////////////////////////////////////////
  idfObject.setString(openstudio::Controller_OutdoorAirFields::EconomizerControlType,
                      modelObject.getEconomizerControlType());

  ///////////////////////////////////////////////////////////////////////////
  // Field: Economizer Control Action Type //////////////////////////////////
  idfObject.setString(openstudio::Controller_OutdoorAirFields::EconomizerControlActionType,
                      modelObject.getEconomizerControlActionType());

  ///////////////////////////////////////////////////////////////////////////
  // Field: Economizer Maximum Limit DryBulb Temperature ////////////////////
  d = modelObject.getEconomizerMaximumLimitDryBulbTemperature();
  if (d){
    idfObject.setDouble(openstudio::Controller_OutdoorAirFields::EconomizerMaximumLimitDryBulbTemperature,d.get());
    }
  else {
    idfObject.setString(openstudio::Controller_OutdoorAirFields::EconomizerMaximumLimitDryBulbTemperature, "");
  }

  ///////////////////////////////////////////////////////////////////////////
  // Field: Economizer Maximum Limit Enthalpy ///////////////////////////////
  d = modelObject.getEconomizerMaximumLimitEnthalpy();
  if (d) {
    idfObject.setDouble(openstudio::Controller_OutdoorAirFields::EconomizerMaximumLimitEnthalpy,d.get());
  }
  else {
    idfObject.setString(openstudio::Controller_OutdoorAirFields::EconomizerMaximumLimitEnthalpy, "");
  }

  ///////////////////////////////////////////////////////////////////////////
  // Field: Economizer Maximum Limit Dewpoint Temperature ///////////////////
  d = modelObject.getEconomizerMaximumLimitDewpointTemperature();
  if (d) {
    idfObject.setDouble(openstudio::Controller_OutdoorAirFields::EconomizerMaximumLimitDewpointTemperature,d.get());
  }
  else {
    idfObject.setString(openstudio::Controller_OutdoorAirFields::EconomizerMaximumLimitDewpointTemperature, "");
  }
  ///////////////////////////////////////////////////////////////////////////
  // Field: Electronic Enthalpy Limit Curve Name ////////////////////////////
  idfObject.setString(openstudio::Controller_OutdoorAirFields::ElectronicEnthalpyLimitCurveName,"");

  ///////////////////////////////////////////////////////////////////////////
  // Field: Economizer Minimum Limit DryBulb Temperature ////////////////////
  d = modelObject.getEconomizerMinimumLimitDryBulbTemperature();
  if (d) {
    idfObject.setDouble(openstudio::Controller_OutdoorAirFields::EconomizerMinimumLimitDryBulbTemperature,d.get());
  }
  else {
    idfObject.setString(openstudio::Controller_OutdoorAirFields::EconomizerMinimumLimitDryBulbTemperature, "");
  }

  ///////////////////////////////////////////////////////////////////////////
  // Field: Lockout Type ////////////////////////////////////////////////////
  idfObject.setString(openstudio::Controller_OutdoorAirFields::LockoutType,
                      modelObject.getLockoutType());

  ///////////////////////////////////////////////////////////////////////////
  // Field: Minimum Limit Type //////////////////////////////////////////////
  idfObject.setString(openstudio::Controller_OutdoorAirFields::MinimumLimitType,
                      modelObject.getMinimumLimitType());


  // HighHumidityControl
  boost::optional<bool> ob;
  ob=modelObject.getHighHumidityControl();
  if(ob)
  {
    if(*ob)
    {
      idfObject.setString(openstudio::Controller_OutdoorAirFields::HighHumidityControl,"Yes");
    }
    else
    {
      idfObject.setString(openstudio::Controller_OutdoorAirFields::HighHumidityControl,"No");
    }
  }

  // HighHumidityOutdoorAirFlowRatio
  d=modelObject.getHighHumidityOutdoorAirFlowRatio();
  if(d)
  {
    idfObject.setDouble(openstudio::Controller_OutdoorAirFields::HighHumidityOutdoorAirFlowRatio,*d);
  }

  // ControlHighIndoorHumidityBasedonOutdoorHumidityRatio
  ob=modelObject.getControlHighIndoorHumidityBasedOnOutdoorHumidityRatio();
  if(ob)
  {
    if(*ob)
    {
      idfObject.setString(openstudio::Controller_OutdoorAirFields::ControlHighIndoorHumidityBasedonOutdoorHumidityRatio,"Yes");
    }
    else
    {
      idfObject.setString(openstudio::Controller_OutdoorAirFields::ControlHighIndoorHumidityBasedonOutdoorHumidityRatio,"No");
    }
  }

  // HeatRecoveryBypassControlType
  s=modelObject.getHeatRecoveryBypassControlType();
  if(s)
  {
    idfObject.setString(openstudio::Controller_OutdoorAirFields::HeatRecoveryBypassControlType, *s );
  }

  // Controller Mechanical Ventilation
  model::ControllerMechanicalVentilation controllerMechanicalVentilation = modelObject.controllerMechanicalVentilation(); 

  boost::optional<IdfObject> controllerMechanicalVentilationIdf = translateAndMapModelObject(controllerMechanicalVentilation);
  if( controllerMechanicalVentilationIdf )
  {
    idfObject.setString(openstudio::Controller_OutdoorAirFields::MechanicalVentilationControllerName,
                        controllerMechanicalVentilationIdf->name().get());
  }

  // MinimumOutdoorAirSchedule

  if( boost::optional<Schedule> s = modelObject.minimumOutdoorAirSchedule() )
  {
    if( boost::optional<IdfObject> _s = translateAndMapModelObject(s.get()) )
    {
      idfObject.setString(openstudio::Controller_OutdoorAirFields::MinimumOutdoorAirScheduleName,_s->name().get());
    } 
  }

  // MinimumFractionofOutdoorAirSchedule

  if( boost::optional<Schedule> s = modelObject.minimumFractionofOutdoorAirSchedule() )
  {
    if( boost::optional<IdfObject> _s = translateAndMapModelObject(s.get()) )
    {
      idfObject.setString(openstudio::Controller_OutdoorAirFields::MinimumFractionofOutdoorAirScheduleName,_s->name().get());
    } 
  }
  
  // MaximumFractionofOutdoorAirSchedule

  if( boost::optional<Schedule> s = modelObject.maximumFractionofOutdoorAirSchedule() )
  {
    if( boost::optional<IdfObject> _s = translateAndMapModelObject(s.get()) )
    {
      idfObject.setString(openstudio::Controller_OutdoorAirFields::MaximumFractionofOutdoorAirScheduleName,_s->name().get());
    } 
  }
  
  // TimeofDayEconomizerControlSchedule

  if( boost::optional<Schedule> s = modelObject.timeofDayEconomizerControlSchedule() )
  {
    if( boost::optional<IdfObject> _s = translateAndMapModelObject(s.get()) )
    {
      idfObject.setString(openstudio::Controller_OutdoorAirFields::TimeofDayEconomizerControlScheduleName,_s->name().get());
    } 
  }

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

  IdfObject idfObject(IddObjectType::CoolingTower_VariableSpeed);

  m_idfObjects.push_back(idfObject);

  // Name

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

  // WaterInletNodeName

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

  // WaterOutletNodeName

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

  // ModelType

  if( s = modelObject.modelType() )
  {
    idfObject.setString(CoolingTower_VariableSpeedFields::ModelType,s.get());
  }

  // ModelCoefficient

  if( boost::optional<ModelObject> mo = modelObject.modelCoefficient() )
  {
    if( boost::optional<IdfObject> _mo = translateAndMapModelObject(mo.get()) )
    {
      idfObject.setString(CoolingTower_VariableSpeedFields::ModelCoefficientName,_mo->name().get());
    }
  }

  // DesignInletAirWetBulbTemperature

  if( d = modelObject.designInletAirWetBulbTemperature() )
  {
    idfObject.setDouble(CoolingTower_VariableSpeedFields::DesignInletAirWetBulbTemperature,d.get());
  }

  // DesignApproachTemperature

  if( d = modelObject.designApproachTemperature() )
  {
    idfObject.setDouble(CoolingTower_VariableSpeedFields::DesignApproachTemperature,d.get());
  }

  // DesignRangeTemperature
  
  if( d = modelObject.designRangeTemperature() )
  {
    idfObject.setDouble(CoolingTower_VariableSpeedFields::DesignRangeTemperature,d.get());
  }

  // DesignWaterFlowRate 

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

  // DesignAirFlowRate 

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

  // DesignFanPower

  if( d = modelObject.designFanPower() )
  {
    idfObject.setDouble(CoolingTower_VariableSpeedFields::DesignFanPower,d.get());
  }
  else if( modelObject.isDesignFanPowerAutosized() )
  {
    idfObject.setString(CoolingTower_VariableSpeedFields::DesignFanPower,"Autosize");
  }

  // FanPowerRatioFunctionofAirFlowRateRatioCurve

  if( boost::optional<CurveCubic> curve = modelObject.fanPowerRatioFunctionofAirFlowRateRatioCurve() )
  {
    if( boost::optional<IdfObject> _curve = translateAndMapModelObject(curve.get()) )
    {
      idfObject.setString(CoolingTower_VariableSpeedFields::FanPowerRatioFunctionofAirFlowRateRatioCurveName,_curve->name().get()); 
    }
  }

  // MinimumAirFlowRateRatio

  if( d = modelObject.minimumAirFlowRateRatio() )
  {
    idfObject.setDouble(CoolingTower_VariableSpeedFields::MinimumAirFlowRateRatio,d.get());
  }

  // FractionofTowerCapacityinFreeConvectionRegime

  if( d = modelObject.fractionofTowerCapacityinFreeConvectionRegime() )
  {
    idfObject.setDouble(CoolingTower_VariableSpeedFields::FractionofTowerCapacityinFreeConvectionRegime,d.get());
  }

  // BasinHeaterCapacity

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

  // BasinHeaterSetpointTemperature

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

  // BasinHeaterOperatingSchedule

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

  // EvaporationLossMode

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

  // EvaporationLossFactor

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

  // DriftLossPercent

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

  // BlowdownCalculationMode

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

  // BlowdownMakeupWaterUsageScheduleName

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

  // NumberofCells

  if( boost::optional<int> n = modelObject.numberofCells() )
  {
    idfObject.setUnsigned(openstudio::CoolingTower_VariableSpeedFields::NumberofCells,n.get());
  }

  // CellControl

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

  // CellMinimumWaterFlowRateFraction

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

  // CellMaximumWaterFlowRateFraction

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

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

  return boost::optional<IdfObject>(idfObject);
}
OptionalModelObject ReverseTranslator::translateZoneMixing( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::ZoneMixing ){
    LOG(Error, "WorkspaceObject is not IddObjectType: ZoneMixing");
    return boost::none;
  }

  OptionalWorkspaceObject target = workspaceObject.getTarget(openstudio::ZoneMixingFields::ZoneName);
  OptionalThermalZone zone;
  if (target){
    OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
    if (modelObject){
      zone = modelObject->optionalCast<ThermalZone>();
    }
  }
  
  if (!zone){
    return boost::none;
  }

  openstudio::model::ZoneMixing mixing(*zone);
  
  OptionalString s = workspaceObject.name();
  if(s){
    mixing.setName(*s);
  }

  target = workspaceObject.getTarget(openstudio::ZoneMixingFields::ScheduleName);
  if (target){
    OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
    if (modelObject){
      if (auto s = modelObject->optionalCast<Schedule>()){
        mixing.setSchedule(s.get());
      }
    }
  }

  s = workspaceObject.getString(openstudio::ZoneMixingFields::DesignFlowRateCalculationMethod, true);
  OS_ASSERT(s);

  OptionalDouble d;
  if (istringEqual("Flow/Zone", *s)){
    d = workspaceObject.getDouble(openstudio::ZoneMixingFields::DesignFlowRate);
    if (d){
      mixing.setDesignFlowRate(*d);
    } else{
      LOG(Error, "Flow/Zone value not found for workspace object " << workspaceObject);
    }
  } else if (istringEqual("Flow/Area", *s)){
    d = workspaceObject.getDouble(openstudio::ZoneMixingFields::FlowRateperZoneFloorArea);
    if (d){
      mixing.setFlowRateperZoneFloorArea(*d);
    } else{
      LOG(Error, "Flow/Area value not found for workspace object " << workspaceObject);
    }
  } else if (istringEqual("Flow/Person", *s)){
    d = workspaceObject.getDouble(openstudio::ZoneMixingFields::FlowRateperPerson);
    if (d){
      mixing.setFlowRateperPerson(*d);
    } else{
      LOG(Error, "Flow/Person value not found for workspace object " << workspaceObject);
    }
  } else if (istringEqual("AirChanges/Hour", *s)){
    d = workspaceObject.getDouble(openstudio::ZoneMixingFields::AirChangesperHour);
    if (d){
      mixing.setAirChangesperHour(*d);
    } else{
      LOG(Error, "AirChanges/Hour value not found for workspace object " << workspaceObject);
    }
  } else{
    LOG(Error, "Unknown DesignFlowRateCalculationMethod value for workspace object" << workspaceObject);
  }

  target = workspaceObject.getTarget(openstudio::ZoneMixingFields::SourceZoneName);
  if (target){
    OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
    if (modelObject){
      if (modelObject->optionalCast<ThermalZone>()){
        mixing.setSourceZone(modelObject->cast<ThermalZone>());
      }
    }
  }

  d = workspaceObject.getDouble(openstudio::ZoneMixingFields::DeltaTemperature);
  if (d){
    mixing.setDeltaTemperature(*d);
  }

  target = workspaceObject.getTarget(openstudio::ZoneMixingFields::DeltaTemperatureScheduleName);
  if (target){
    OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
    if (modelObject){
      if (auto s = modelObject->optionalCast<Schedule>()){
        mixing.setDeltaTemperatureSchedule(s.get());
      }
    }
  }

  target = workspaceObject.getTarget(openstudio::ZoneMixingFields::MinimumZoneTemperatureScheduleName);
  if (target){
    OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
    if (modelObject){
      if (auto s = modelObject->optionalCast<Schedule>()){
        mixing.setMinimumZoneTemperatureSchedule(s.get());
      }
    }
  }

  target = workspaceObject.getTarget(openstudio::ZoneMixingFields::MaximumZoneTemperatureScheduleName);
  if (target){
    OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
    if (modelObject){
      if (auto s = modelObject->optionalCast<Schedule>()){
        mixing.setMaximumZoneTemperatureSchedule(s.get());
      }
    }
  }

  target = workspaceObject.getTarget(openstudio::ZoneMixingFields::MinimumSourceZoneTemperatureScheduleName);
  if (target){
    OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
    if (modelObject){
      if (auto s = modelObject->optionalCast<Schedule>()){
        mixing.setMinimumSourceZoneTemperatureSchedule(s.get());
      }
    }
  }

  target = workspaceObject.getTarget(openstudio::ZoneMixingFields::MaximumSourceZoneTemperatureScheduleName);
  if (target){
    OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
    if (modelObject){
      if (auto s = modelObject->optionalCast<Schedule>()){
        mixing.setMaximumSourceZoneTemperatureSchedule(s.get());
      }
    }
  }

  target = workspaceObject.getTarget(openstudio::ZoneMixingFields::MinimumOutdoorTemperatureScheduleName);
  if (target){
    OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
    if (modelObject){
      if (auto s = modelObject->optionalCast<Schedule>()){
        mixing.setMinimumOutdoorTemperatureSchedule(s.get());
      }
    }
  }

  target = workspaceObject.getTarget(openstudio::ZoneMixingFields::MaximumOutdoorTemperatureScheduleName);
  if (target){
    OptionalModelObject modelObject = translateAndMapWorkspaceObject(*target);
    if (modelObject){
      if (auto s = modelObject->optionalCast<Schedule>()){
        mixing.setMaximumOutdoorTemperatureSchedule(s.get());
      }
    }
  }

  return mixing;
}
boost::optional<IdfObject> ForwardTranslator::translateChillerHeaterPerformanceElectricEIR( ChillerHeaterPerformanceElectricEIR & modelObject )
{
  OptionalString s;
  OptionalDouble value;
  OptionalModelObject temp;

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

  // ReferenceCoolingModeEvaporatorCapacity
  if( modelObject.isReferenceCoolingModeEvaporatorCapacityAutosized() ) {
    idfObject.setString(ChillerHeaterPerformance_Electric_EIRFields::ReferenceCoolingModeEvaporatorCapacity,"Autosize");
  }
  else if( (value = modelObject.referenceCoolingModeEvaporatorCapacity()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::ReferenceCoolingModeEvaporatorCapacity,value.get()); 
  }

  // ReferenceCoolingModeCOP
  if( (value = modelObject.referenceCoolingModeCOP()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::ReferenceCoolingModeCOP,value.get()); 
  }

  // ReferenceCoolingModeLeavingChilledWaterTemperature
  if( (value = modelObject.referenceCoolingModeLeavingChilledWaterTemperature()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::ReferenceCoolingModeLeavingChilledWaterTemperature,value.get()); 
  }

  // ReferenceCoolingModeEnteringCondenserFluidTemperature
  if( (value = modelObject.referenceCoolingModeEnteringCondenserFluidTemperature()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::ReferenceCoolingModeEnteringCondenserFluidTemperature,value.get()); 
  }

  // ReferenceCoolingModeLeavingCondenserWaterTemperature
  if( (value = modelObject.referenceCoolingModeLeavingCondenserWaterTemperature()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::ReferenceCoolingModeLeavingCondenserWaterTemperature,value.get()); 
  }

  // ReferenceHeatingModeCoolingCapacityRatio
  if( (value = modelObject.referenceHeatingModeCoolingCapacityRatio()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::ReferenceHeatingModeCoolingCapacityRatio,value.get()); 
  }

  // ReferenceHeatingModeCoolingPowerInputRatio
  if( (value = modelObject.referenceHeatingModeCoolingPowerInputRatio()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::ReferenceHeatingModeCoolingPowerInputRatio,value.get()); 
  }

  // ReferenceHeatingModeLeavingChilledWaterTemperature
  if( (value = modelObject.referenceHeatingModeLeavingChilledWaterTemperature()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::ReferenceHeatingModeLeavingChilledWaterTemperature,value.get()); 
  }

  // ReferenceHeatingModeLeavingCondenserWaterTemperature
  if( (value = modelObject.referenceHeatingModeLeavingCondenserWaterTemperature()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::ReferenceHeatingModeLeavingCondenserWaterTemperature,value.get()); 
  }

  // ReferenceHeatingModeEnteringCondenserFluidTemperature
  if( (value = modelObject.referenceHeatingModeEnteringCondenserFluidTemperature()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::ReferenceHeatingModeEnteringCondenserFluidTemperature,value.get()); 
  }

  // HeatingModeEnteringChilledWaterTemperatureLowLimit
  if( (value = modelObject.heatingModeEnteringChilledWaterTemperatureLowLimit()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::HeatingModeEnteringChilledWaterTemperatureLowLimit,value.get()); 
  }

  // ChilledWaterFlowModeType
  if( (s = modelObject.chilledWaterFlowModeType()) ) {
    idfObject.setString(ChillerHeaterPerformance_Electric_EIRFields::ChilledWaterFlowModeType,s.get()); 
  }

  // DesignChilledWaterFlowRate
  if( modelObject.isDesignChilledWaterFlowRateAutosized() ) {
    idfObject.setString(ChillerHeaterPerformance_Electric_EIRFields::DesignChilledWaterFlowRate,"Autosize");
  }
  else if( (value = modelObject.designChilledWaterFlowRate()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::DesignChilledWaterFlowRate,value.get()); 
  }

  // DesignCondenserWaterFlowRate
  if( modelObject.isDesignCondenserWaterFlowRateAutosized() ) {
    idfObject.setString(ChillerHeaterPerformance_Electric_EIRFields::DesignCondenserWaterFlowRate,"Autosize");
  }
  else if( (value = modelObject.designCondenserWaterFlowRate()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::DesignCondenserWaterFlowRate,value.get()); 
  }

  // DesignHotWaterFlowRate
  if( (value = modelObject.designHotWaterFlowRate()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::DesignHotWaterFlowRate,value.get()); 
  }

  // CompressorMotorEfficiency
  if( (value = modelObject.compressorMotorEfficiency()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::CompressorMotorEfficiency,value.get()); 
  }

  // CondenserType
  if( (s = modelObject.condenserType()) ) {
    idfObject.setString(ChillerHeaterPerformance_Electric_EIRFields::CondenserType,s.get()); 
  }

  // CoolingModeTemperatureCurveCondenserWaterIndependentVariable
  if( (s = modelObject.coolingModeTemperatureCurveCondenserWaterIndependentVariable()) ) {
    idfObject.setString(ChillerHeaterPerformance_Electric_EIRFields::CoolingModeTemperatureCurveCondenserWaterIndependentVariable,s.get()); 
  }

  // CoolingModeCoolingCapacityFunctionofTemperatureCurveName
  { 
    auto curve = modelObject.coolingModeCoolingCapacityFunctionofTemperatureCurve();
    if( auto _curve = translateAndMapModelObject(curve) ) {
      idfObject.setString(ChillerHeaterPerformance_Electric_EIRFields::CoolingModeCoolingCapacityFunctionofTemperatureCurveName,_curve->name().get());
    }
  }

  // CoolingModeElectricInputtoCoolingOutputRatioFunctionofTemperatureCurveName
  { 
    auto curve = modelObject.coolingModeElectricInputtoCoolingOutputRatioFunctionofTemperatureCurve();
    if( auto _curve = translateAndMapModelObject(curve) ) {
      idfObject.setString(ChillerHeaterPerformance_Electric_EIRFields::CoolingModeElectricInputtoCoolingOutputRatioFunctionofTemperatureCurveName,_curve->name().get());
    }
  }

  // CoolingModeElectricInputtoCoolingOutputRatioFunctionofPartLoadRatioCurveName
  { 
    auto curve = modelObject.coolingModeElectricInputtoCoolingOutputRatioFunctionofPartLoadRatioCurve();
    if( auto _curve = translateAndMapModelObject(curve) ) {
      idfObject.setString(ChillerHeaterPerformance_Electric_EIRFields::CoolingModeElectricInputtoCoolingOutputRatioFunctionofPartLoadRatioCurveName,_curve->name().get());
    }
  }

  // CoolingModeCoolingCapacityOptimumPartLoadRatio
  if( (value = modelObject.coolingModeCoolingCapacityOptimumPartLoadRatio()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::CoolingModeCoolingCapacityOptimumPartLoadRatio,value.get()); 
  }

  // HeatingModeTemperatureCurveCondenserWaterIndependentVariable
  if( (s = modelObject.heatingModeTemperatureCurveCondenserWaterIndependentVariable()) ) {
    idfObject.setString(ChillerHeaterPerformance_Electric_EIRFields::HeatingModeTemperatureCurveCondenserWaterIndependentVariable,s.get()); 
  }

  // HeatingModeCoolingCapacityFunctionofTemperatureCurveName
  { 
    auto curve = modelObject.heatingModeCoolingCapacityFunctionofTemperatureCurve();
    if( auto _curve = translateAndMapModelObject(curve) ) {
      idfObject.setString(ChillerHeaterPerformance_Electric_EIRFields::HeatingModeCoolingCapacityFunctionofTemperatureCurveName,_curve->name().get());
    }
  }

  // HeatingModeElectricInputtoCoolingOutputRatioFunctionofTemperatureCurveName
  { 
    auto curve = modelObject.heatingModeElectricInputtoCoolingOutputRatioFunctionofTemperatureCurve();
    if( auto _curve = translateAndMapModelObject(curve) ) {
      idfObject.setString(ChillerHeaterPerformance_Electric_EIRFields::HeatingModeElectricInputtoCoolingOutputRatioFunctionofTemperatureCurveName,_curve->name().get());
    }
  }

  // HeatingModeElectricInputtoCoolingOutputRatioFunctionofPartLoadRatioCurveName
  { 
    auto curve = modelObject.heatingModeElectricInputtoCoolingOutputRatioFunctionofPartLoadRatioCurve();
    if( auto _curve = translateAndMapModelObject(curve) ) {
      idfObject.setString(ChillerHeaterPerformance_Electric_EIRFields::HeatingModeElectricInputtoCoolingOutputRatioFunctionofPartLoadRatioCurveName,_curve->name().get());
    }
  }

  // HeatingModeCoolingCapacityOptimumPartLoadRatio
  if( (value = modelObject.heatingModeCoolingCapacityOptimumPartLoadRatio()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::HeatingModeCoolingCapacityOptimumPartLoadRatio,value.get()); 
  }

  // SizingFactor
  if( (value = modelObject.sizingFactor()) ) {
    idfObject.setDouble(ChillerHeaterPerformance_Electric_EIRFields::SizingFactor,value.get()); 
  }

  return idfObject;
}
Example #15
0
TEST_F(IdfFixture, IdfObject_CommentGettersAndSetters) {
  // DEFAULT OBJECT COMMENTS
  IdfObject object(IddObjectType::Zone);
  // exist? if so, are comments according to regex?
  std::string str = object.comment();
  if (!str.empty()) { EXPECT_EQ(str,makeComment(str)); }
  unsigned n = object.numFields();
  for (unsigned i = 0; i < n; ++i) {
    OptionalString oStr = object.fieldComment(i);
    if (oStr && !oStr->empty()) {
      EXPECT_EQ(*oStr,makeComment(*oStr));
    }
  }

  // comment setter works (already comments, and needs comment character prepended)
  str = "! New object comment";
  object.setComment(str);
  EXPECT_EQ(str,object.comment());
  str = "\n\nThis is my object.\n";
  object.setComment(str);
  str = "\n\n! This is my object.\n";
  EXPECT_EQ(str,object.comment());

  // field comment setter works for valid indices
  for (int i = n-1; i >= 0; --i) {
    std::stringstream ss;
    ss << "Field " << i; str = ss.str(); ss.str("");
    EXPECT_TRUE(object.setFieldComment(i,str));
    ss << "! " << str;
    EXPECT_EQ(ss.str(),object.fieldComment(i));
  }

  // field comment setter returns false, does not crash for invalid indices
  EXPECT_FALSE(object.setFieldComment(n+3,str));

  // TEXT OBJECT COMMENTS
  std::stringstream text;
  text << "  Branch," << std::endl
       << "    Central Chiller Branch," << std::endl
       << "    0,                       !- Maximum Flow Rate {m3/s}" << std::endl
       << "    ," << std::endl
       << "    Chiller:Electric, ! i think we have an electric chiller" << std::endl
       << "    Central Chiller," << std::endl
       << "    Central Chiller Inlet Node," << std::endl
       << "    Central Chiller Outlet Node," << std::endl
       << "    Active;";
  OptionalIdfObject oObj = IdfObject::load(text.str());
  ASSERT_TRUE(oObj);
  object = *oObj;
  // field comments setter properly extends field comments vector as needed
  OptionalString optStr = object.fieldComment(0); 
  ASSERT_TRUE(optStr);
  EXPECT_EQ("",*optStr);
  optStr = object.fieldComment(1); ASSERT_TRUE(optStr);
  EXPECT_EQ("",*optStr); // auto-generated comments are stripped
  optStr = object.fieldComment(3);
  ASSERT_TRUE(optStr);
  EXPECT_EQ("! i think we have an electric chiller",*optStr);
  EXPECT_TRUE(object.setFieldComment(5,"my comment"));
  optStr = object.fieldComment(5); ASSERT_TRUE(optStr);
  EXPECT_EQ("! my comment",*optStr);
  optStr = object.fieldComment(4); ASSERT_TRUE(optStr);
  EXPECT_EQ("",*optStr);
  optStr = object.fieldComment(6); ASSERT_TRUE(optStr); EXPECT_TRUE(optStr->empty());

  // field comments setter returns false, does not crash if exceed number of fields.
  EXPECT_FALSE(object.setFieldComment(10,"hi"));

}
boost::optional<IdfObject> ForwardTranslator::translateEvaporativeFluidCoolerTwoSpeed( EvaporativeFluidCoolerTwoSpeed & modelObject )
{
  OptionalString s;
  OptionalDouble d;
  OptionalModelObject temp;
 
  //Name
  IdfObject idfObject = createRegisterAndNameIdfObject(openstudio::IddObjectType::EvaporativeFluidCooler_TwoSpeed, modelObject);

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

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

  // HighFanSpeedAirFlowRate
  if( modelObject.isHighFanSpeedAirFlowRateAutosized() )
  {
    idfObject.setString(openstudio::EvaporativeFluidCooler_TwoSpeedFields::HighFanSpeedAirFlowRate,"Autosize");
  } 
  else if( (d = modelObject.highFanSpeedAirFlowRate()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::HighFanSpeedAirFlowRate,d.get());
  }

  // HighFanSpeedFanPower
  if( modelObject.isHighFanSpeedFanPowerAutosized() )
  {
    idfObject.setString(openstudio::EvaporativeFluidCooler_TwoSpeedFields::HighFanSpeedFanPower,"Autosize");
  } 
  else if( (d = modelObject.highFanSpeedFanPower()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::HighFanSpeedFanPower,d.get());
  }

  // LowFanSpeedAirFlowRate
  if( modelObject.isLowFanSpeedAirFlowRateAutosized() )
  {
    idfObject.setString(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowFanSpeedAirFlowRate,"Autocalculate");
  } 
  else if( (d = modelObject.lowFanSpeedAirFlowRate()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowFanSpeedAirFlowRate,d.get());
  }

  // LowFanSpeedAirFlowRateSizingFactor
  if( (d = modelObject.lowFanSpeedAirFlowRateSizingFactor()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowFanSpeedAirFlowRateSizingFactor,d.get());
  }

  // LowFanSpeedFanPower
  if( modelObject.isLowFanSpeedFanPowerAutosized() )
  {
    idfObject.setString(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowFanSpeedFanPower,"Autocalculate");
  } 
  else if( (d = modelObject.lowFanSpeedFanPower()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowFanSpeedFanPower,d.get());
  }

  // LowFanSpeedFanPowerSizingFactor
  if( (d = modelObject.lowFanSpeedFanPowerSizingFactor()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowFanSpeedFanPowerSizingFactor,d.get());
  }

  // DesignSprayWaterFlowRate
  if( (d = modelObject.designSprayWaterFlowRate()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::DesignSprayWaterFlowRate,d.get());
  }

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

  // OutdoorAirInletNodeName
  idfObject.setString(openstudio::EvaporativeFluidCooler_TwoSpeedFields::OutdoorAirInletNodeName,"");

  // HeatRejectionCapacityandNominalCapacitySizingRatio
  if( (d = modelObject.heatRejectionCapacityandNominalCapacitySizingRatio()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::HeatRejectionCapacityandNominalCapacitySizingRatio,d.get());
  }

  // HighSpeedStandardDesignCapacity
  if( (d = modelObject.highSpeedStandardDesignCapacity()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::HighSpeedStandardDesignCapacity,d.get());
  }

  // LowSpeedStandardDesignCapacity
  if( modelObject.isLowSpeedStandardDesignCapacityAutosized() )
  {
    idfObject.setString(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowSpeedStandardDesignCapacity,"Autosize");
  } 
  else if( (d = modelObject.lowSpeedStandardDesignCapacity()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowSpeedStandardDesignCapacity,d.get());
  }

  // LowSpeedStandardCapacitySizingFactor
  if( (d = modelObject.lowSpeedStandardCapacitySizingFactor()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowSpeedStandardCapacitySizingFactor,d.get());
  }

  // HighFanSpeedUfactorTimesAreaValue
  if( modelObject.isHighFanSpeedUfactorTimesAreaValueAutosized() )
  {
    idfObject.setString(openstudio::EvaporativeFluidCooler_TwoSpeedFields::HighFanSpeedUfactorTimesAreaValue,"Autosize");
  } 
  else if( (d = modelObject.highFanSpeedUfactorTimesAreaValue()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::HighFanSpeedUfactorTimesAreaValue,d.get());
  }

  // LowFanSpeedUfactorTimesAreaValue
  if( modelObject.isLowFanSpeedUfactorTimesAreaValueAutosized() )
  {
    idfObject.setString(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowFanSpeedUfactorTimesAreaValue,"Autocalculate");
  } 
  else if( (d = modelObject.lowFanSpeedUfactorTimesAreaValue()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowFanSpeedUfactorTimesAreaValue,d.get());
  }

  // LowFanSpeedUFactorTimesAreaSizingFactor
  if( (d = modelObject.lowFanSpeedUFactorTimesAreaSizingFactor()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowFanSpeedUFactorTimesAreaSizingFactor,d.get());
  }

  // DesignWaterFlowRate
  if( modelObject.isDesignWaterFlowRateAutosized() )
  {
    idfObject.setString(openstudio::EvaporativeFluidCooler_TwoSpeedFields::DesignWaterFlowRate,"Autosize");
  } 
  else if( (d = modelObject.designWaterFlowRate()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::DesignWaterFlowRate,d.get());
  }

  // HighSpeedUserSpecifiedDesignCapacity
  if( (d = modelObject.highSpeedUserSpecifiedDesignCapacity()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::HighSpeedUserSpecifiedDesignCapacity,d.get());
  }

  // LowSpeedUserSpecifiedDesignCapacity
  if( modelObject.isLowSpeedUserSpecifiedDesignCapacityAutosized() )
  {
    idfObject.setString(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowSpeedUserSpecifiedDesignCapacity,"Autocalculate");
  } 
  else if( (d = modelObject.lowSpeedUserSpecifiedDesignCapacity()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowSpeedUserSpecifiedDesignCapacity,d.get());
  }

  // LowSpeedUserSpecifiedDesignCapacitySizingFactor
  if( (d = modelObject.lowSpeedUserSpecifiedDesignCapacitySizingFactor()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::LowSpeedUserSpecifiedDesignCapacitySizingFactor,d.get());
  }

  // DesignEnteringWaterTemperature
  if( (d = modelObject.designEnteringWaterTemperature()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::DesignEnteringWaterTemperature,d.get());
  }

  // DesignEnteringAirTemperature
  if( (d = modelObject.designEnteringAirTemperature()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::DesignEnteringAirTemperature,d.get());
  }

  // DesignEnteringAirWetbulbTemperature
  if( (d = modelObject.designEnteringAirWetbulbTemperature()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::DesignEnteringAirWetbulbTemperature,d.get());
  }

  // HighSpeedSizingFactor
  if( (d = modelObject.highSpeedSizingFactor()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::HighSpeedSizingFactor,d.get());
  }

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

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

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

  // BlowdownCalculationMode
  if( (s = modelObject.blowdownCalculationMode()) )
  {
    idfObject.setString(openstudio::EvaporativeFluidCooler_TwoSpeedFields::BlowdownCalculationMode,s.get());
  }

  // BlowdownConcentrationRatio
  if( (d = modelObject.blowdownConcentrationRatio()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_TwoSpeedFields::BlowdownConcentrationRatio,d.get());
  }

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

  // SupplyWaterStorageTankName

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

  // Create a new IddObjectType::Evaporative_FluidCoolerSingleSpeed
  IdfObject idfObject(IddObjectType::EvaporativeFluidCooler_SingleSpeed);

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

  // WaterInletNodeName

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

  // WaterOutletNodeName

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

  
  // DesignAirFlowRate 

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

     
  // DesignWaterFlowRate 

  if( (d = modelObject.designWaterFlowRate()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_SingleSpeedFields::DesignWaterFlowRate,d.get());
  }
  else if( modelObject.isDesignWaterFlowRateAutosized() )
  {
    idfObject.setString(openstudio::EvaporativeFluidCooler_SingleSpeedFields::DesignWaterFlowRate,"Autosize");
  }

  // DesignSprayWaterFlowRate
  
  if( (d = modelObject.designSprayWaterFlowRate()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_SingleSpeedFields::DesignSprayWaterFlowRate,d.get());
  }

  
 // PerformanceInputMethod

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

  idfObject.setString(openstudio::EvaporativeFluidCooler_SingleSpeedFields::OutdoorAirInletNodeName,"");


// StandardDesignCapacity

   if( (d = modelObject.standardDesignCapacity()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_SingleSpeedFields::StandardDesignCapacity,d.get());
  }
 
  // UFactorTimesAreaValueatDesignAirFlowRate

  if( (d = modelObject.ufactorTimesAreaValueatDesignAirFlowRate()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_SingleSpeedFields::DesignAirFlowRateUfactorTimesAreaValue,d.get());
  }
  else if( modelObject.isUfactorTimesAreaValueatDesignAirFlowRateAutosized() )
  {
    idfObject.setString(openstudio::EvaporativeFluidCooler_SingleSpeedFields::DesignAirFlowRateUfactorTimesAreaValue,"Autosize");
  }


  // UserSpecifiedDesignCapacity

  if( (d = modelObject.userSpecifiedDesignCapacity()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_SingleSpeedFields::UserSpecifiedDesignCapacity,d.get());
  }

    
// DesignEnteringWaterTemperature

  if( (d = modelObject.designEnteringWaterTemperature()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_SingleSpeedFields::DesignEnteringWaterTemperature,d.get());
  }

// DesignEnteringAirTemperature

  if( (d = modelObject.designEnteringAirTemperature()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_SingleSpeedFields::DesignEnteringAirTemperature,d.get());
  }

// DesignEnteringAirWetbulbTemperature
  if( (d = modelObject.designEnteringAirWetbulbTemperature()) )
  {
    idfObject.setDouble(openstudio::EvaporativeFluidCooler_SingleSpeedFields::DesignEnteringAirWetbulbTemperature,d.get());
  }

  // CapacityControl

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

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

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

  // EvaporationLossFactor

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

  // DriftLossPercent

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

  // BlowdownCalculationMode

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

  // BlowdownMakeupWaterUsageScheduleName

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

 // supplyWaterStorageTankName

  //if( (s = modelObject.supplyWaterStorageTankName()) )
  //{
  //  idfObject.setString(openstudio::EvaporativeFluidCooler_SingleSpeedFields::SupplyWaterStorageTankName,s.get());
  //}

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

  std::vector<ModelObject> objects = modelObject.equipment();

  if (objects.empty()){
    // do not write out this object
    return boost::none;
  }

  std::vector<ModelObject> coolingVector = modelObject.equipmentInCoolingOrder();
  std::vector<ModelObject> heatingVector = modelObject.equipmentInHeatingOrder();

  std::vector<ModelObject> airChillers;
  std::vector<ModelObject> stdEquipment;

  for( const auto & elem : objects )
  {
    if (boost::optional<RefrigerationAirChiller> airChiller = elem.optionalCast<RefrigerationAirChiller>()) {
      airChillers.push_back(airChiller.get());
    } else {
      stdEquipment.push_back(elem);
    }
  }

  boost::optional<RefrigerationAirChiller> airChiller;
  std::map<ModelObject, unsigned> coolingMap;
  unsigned chillerSetCoolingPriority = 0;
  unsigned priority = 1;
  int airChillerOffset = -1;
  for( const auto & elem : coolingVector )
  {
    if (airChillers.size() > 0 && (airChiller = elem.optionalCast<RefrigerationAirChiller>()) )
    {
      if (chillerSetCoolingPriority == 0) {
        chillerSetCoolingPriority = priority;
      }
      airChillerOffset++;
    }
    else {
      coolingMap.insert ( std::pair<ModelObject,unsigned>(elem, ((airChillerOffset > 0) ? (priority - airChillerOffset) : priority) ) );
    }
    priority++;
  }

  std::map<ModelObject, unsigned> heatingMap;
  unsigned chillerSetHeatingPriority = 0;
  priority = 1;
  airChillerOffset = -1;
  for( const auto & elem : heatingVector )
  {
    if (airChillers.size() > 0 && (airChiller= elem.optionalCast<RefrigerationAirChiller>()) )
    {
      if (chillerSetHeatingPriority == 0) {
        chillerSetHeatingPriority = priority;
      }
      airChillerOffset++;
    }
    else {
      heatingMap.insert ( std::pair<ModelObject,unsigned>(elem, ((airChillerOffset > 0) ? (priority - airChillerOffset) : priority) ) );
    }
    priority++;
  }

  IdfObject idfObject(IddObjectType::ZoneHVAC_EquipmentList);

  // Name
  std::string name;
  s = modelObject.thermalZone().name();
  if(s)
  {
    name = s.get() + " Equipment List";
    idfObject.setName(name);
  }

  for( auto & elem : stdEquipment )
  {
    unsigned coolingPriority = coolingMap[elem];
    unsigned heatingPriority = heatingMap[elem];

    boost::optional<IdfObject> _equipment = translateAndMapModelObject(elem);

    if( _equipment && (! elem.optionalCast<ZoneVentilationDesignFlowRate>()) )
    {
      IdfExtensibleGroup eg = idfObject.pushExtensibleGroup();

      eg.setString(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentObjectType,_equipment->iddObject().name()); 
      eg.setString(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentName,_equipment->name().get()); 
      eg.setUnsigned(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentCoolingSequence,coolingPriority); 
      eg.setUnsigned(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentHeatingorNoLoadSequence,heatingPriority); 
    }
  }

  if (!airChillers.empty()) {
    // ZoneHVAC:RefrigerationChillerSet
    // Name
      IdfObject _chillerSet(IddObjectType::ZoneHVAC_RefrigerationChillerSet);

      m_idfObjects.push_back(_chillerSet);

      _chillerSet.setName(name + " Refrigeration Chiller Set");

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

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

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

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

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

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

    // AirInletNodeName
      _chillerSet.setString(ZoneHVAC_RefrigerationChillerSetFields::AirInletNodeName,"");

    // AirOutletNodeName
      _chillerSet.setString(ZoneHVAC_RefrigerationChillerSetFields::AirOutletNodeName,"");

    // AirChiller (extensible)
      for( auto & elem : airChillers )
      {
        boost::optional<IdfObject> _airChiller = translateAndMapModelObject(elem);

        if( _airChiller )
        {
          IdfExtensibleGroup eg = _chillerSet.pushExtensibleGroup();

          eg.setString(ZoneHVAC_RefrigerationChillerSetExtensibleFields::AirChillerName,_airChiller->name().get()); 
        }
      }

    IdfExtensibleGroup eg = idfObject.pushExtensibleGroup();

    eg.setString(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentObjectType,_chillerSet.iddObject().name()); 
    eg.setString(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentName,_chillerSet.name().get()); 
    eg.setUnsigned(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentCoolingSequence, chillerSetCoolingPriority); 
    eg.setUnsigned(ZoneHVAC_EquipmentListExtensibleFields::ZoneEquipmentHeatingorNoLoadSequence, chillerSetHeatingPriority); 
  }

  m_idfObjects.push_back(idfObject);

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

  auto const& modules = modelObject.getImpl<model::detail::CentralHeatPumpSystem_Impl>()->modules();

  // If the CentralHeatPumpSystem doesn't have at least one CentralHeatPumpSystemModule, then it shouldn't be translated
  if (modules.empty()) {
    LOG(Warn, "CentralHeatPumpSystem " << modelObject.name().get() << " has no CentralHeatPumpSystemModules, it will not be translated");
    return boost::none;
  }

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

  // ControlMethod
  if( (s = modelObject.controlMethod()) ) {
    idfObject.setString(CentralHeatPumpSystemFields::ControlMethod,s.get());
  }

  // AncillaryPower
  if( (d = modelObject.ancillaryPower()) ) {
    idfObject.setDouble(CentralHeatPumpSystemFields::AncillaryPower,d.get());
  }

  // AncillaryOperationScheduleName
  {
   if( auto schedule = modelObject.ancillaryOperationSchedule() ) {
     if( auto _schedule = translateAndMapModelObject(schedule.get()) ) {
       idfObject.setString(CentralHeatPumpSystemFields::AncillaryOperationScheduleName,_schedule->name().get());
     }
   }
  }

  // supply = Cooling Loop, demand=Source Loop, tertiary = Heating Loop

  // CoolingLoopInletNodeName
  if( auto mo = modelObject.supplyInletModelObject() ) {
    if( auto node = mo->optionalCast<Node>() ) {
      idfObject.setString(CentralHeatPumpSystemFields::CoolingLoopInletNodeName,node->name().get());
    }
  }

  // CoolingLoopOutletNodeName
  if( auto mo = modelObject.supplyOutletModelObject() ) {
    if( auto node = mo->optionalCast<Node>() ) {
      idfObject.setString(CentralHeatPumpSystemFields::CoolingLoopOutletNodeName,node->name().get());
    }
  }

  // SourceLoopInletNodeName
  if( auto mo = modelObject.demandInletModelObject() ) {
    if( auto node = mo->optionalCast<Node>() ) {
      idfObject.setString(CentralHeatPumpSystemFields::SourceLoopInletNodeName,node->name().get());
    }
  }

  // SourceLoopOutletNodeName
  if( auto mo = modelObject.demandOutletModelObject() ) {
    if( auto node = mo->optionalCast<Node>() ) {
      idfObject.setString(CentralHeatPumpSystemFields::SourceLoopOutletNodeName,node->name().get());
    }
  }


  // HeatingLoopInletNodeName
  if ( auto mo = modelObject.tertiaryInletModelObject() ) {
    if ( auto node = mo->optionalCast<Node>() ) {
      idfObject.setString(CentralHeatPumpSystemFields::HeatingLoopInletNodeName, node->name().get());
    }
  }
  // HeatingLoopOutletNodeName
  if ( auto mo = modelObject.tertiaryOutletModelObject() ) {
    if ( auto node = mo->optionalCast<Node>() ) {
      idfObject.setString(CentralHeatPumpSystemFields::HeatingLoopOutletNodeName, node->name().get());
    }
  }

  // ChillerHeaterModulesPerformanceComponentObjectType1
  // ChillerHeaterModulesPerformanceComponentName1
  // ChillerHeaterModulesControlScheduleName1
  // NumberofChillerHeaterModules1

  for ( auto const& module : modules ) {
    IdfExtensibleGroup group = idfObject.pushExtensibleGroup();

    auto performanceComponent = module.chillerHeaterModulesPerformanceComponent();
    if( auto _performanceComponent = translateAndMapModelObject(performanceComponent) ) {
      group.setString(CentralHeatPumpSystemExtensibleFields::ChillerHeaterModulesPerformanceComponentObjectType, _performanceComponent->iddObject().name());
      group.setString(CentralHeatPumpSystemExtensibleFields::ChillerHeaterModulesPerformanceComponentName, _performanceComponent->name().get());
    }
    {
      auto schedule = module.chillerHeaterModulesControlSchedule();
      if( auto _schedule = translateAndMapModelObject(schedule) ) {
        group.setString(CentralHeatPumpSystemExtensibleFields::ChillerHeaterModulesControlScheduleName,_schedule->name().get());
     }
    }
    group.setInt(CentralHeatPumpSystemExtensibleFields::NumberofChillerHeaterModules, module.numberofChillerHeaterModules() );
  }

  return 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;
}
OptionalModelObject ReverseTranslator::translateAirLoopHVAC( const WorkspaceObject & workspaceObject )
{
  if( workspaceObject.iddObject().type() != IddObjectType::AirLoopHVAC )
  {
     LOG(Error, "WorkspaceObject is not IddObjectType: AirLoopHVAC");
     return boost::none;
  }

  OptionalModelObject result;
  boost::optional<double> val;
  boost::optional<std::string> optionalString;
  Workspace _workspace = workspaceObject.workspace();

  openstudio::model::AirLoopHVAC airLoopHVAC( m_model );

  boost::optional<std::string> supplyInletNodeName = workspaceObject.getString(AirLoopHVACFields::SupplySideInletNodeName);
  boost::optional<std::string> supplyOutletNodeName = workspaceObject.getString(AirLoopHVACFields::SupplySideOutletNodeNames);
  boost::optional<std::string> demandInletNodeName = workspaceObject.getString(AirLoopHVACFields::DemandSideInletNodeNames);
  boost::optional<std::string> demandOutletNodeName = workspaceObject.getString(AirLoopHVACFields::DemandSideOutletNodeName);

  Node supplyInletNode = airLoopHVAC.supplyInletNode();
  Node supplyOutletNode = airLoopHVAC.supplyOutletNode();
  Node demandInletNode = airLoopHVAC.demandInletNode();
  Node demandOutletNode = airLoopHVAC.demandOutletNode();

  if( supplyInletNodeName ) { supplyInletNode.setName(supplyInletNodeName.get()); }
  if( supplyOutletNodeName ) { supplyOutletNode.setName(supplyOutletNodeName.get()); }
  if( demandInletNodeName ) { demandInletNode.setName(demandInletNodeName.get()); }
  if( demandOutletNodeName ) { demandOutletNode.setName(demandOutletNodeName.get()); }

  optionalString = workspaceObject.getString(AirLoopHVACFields::Name);
  if( optionalString )
  {
    airLoopHVAC.setName(optionalString.get());
  }

  optionalString = workspaceObject.getString(AirLoopHVACFields::DesignSupplyAirFlowRate);
  if( optionalString && istringEqual(optionalString.get(),"AutoSize") )
  {
    airLoopHVAC.autosizeDesignSupplyAirFlowRate();
  }
  else if( (val = workspaceObject.getDouble(AirLoopHVACFields::DesignSupplyAirFlowRate)) )
  {
    airLoopHVAC.setDesignSupplyAirFlowRate(val.get());
  }

  // Go find the supply branch.
  // Currently only supporting one supply branch.
  // Dual ducts are not supported.
  OptionalWorkspaceObject _supplyBranchList;
  OptionalWorkspaceObject _supplyBranch;

  _supplyBranchList = workspaceObject.getTarget(AirLoopHVACFields::BranchListName);
  if( _supplyBranchList )
  {
    _supplyBranch = _supplyBranchList->getExtensibleGroup(0).cast<WorkspaceExtensibleGroup>().getTarget(BranchListExtensibleFields::BranchName);
    if( ! _supplyBranch )
    {
      LOG(Error, _supplyBranchList->briefDescription() << ": Missing supply branch");
    }
    else
    {
      // March through the equipment on the supply branch and convert them.
      for( unsigned i = 0; ! _supplyBranch->getExtensibleGroup(i).empty(); i++ )
      {
        WorkspaceExtensibleGroup eg = _supplyBranch->getExtensibleGroup(i).cast<WorkspaceExtensibleGroup>();
        boost::optional<std::string> componentName = eg.getString(BranchExtensibleFields::ComponentName);
        boost::optional<std::string> componentType = eg.getString(BranchExtensibleFields::ComponentObjectType);
        boost::optional<std::string> componentInletNodeName = eg.getString(BranchExtensibleFields::ComponentInletNodeName);
        boost::optional<std::string> componentOutletNodeName = eg.getString(BranchExtensibleFields::ComponentOutletNodeName);
        boost::optional<WorkspaceObject> wo;
        OptionalNode node;
        OptionalModelObject targetModelObject;

        if( componentName && (componentName.get() != "") && componentType && (componentType.get() != "") )
        {
          IddObjectType iddType(componentType.get());
          wo = _workspace.getObjectByTypeAndName(iddType,componentName.get());
        }

        if( wo )
        {
          targetModelObject = translateAndMapWorkspaceObject( wo.get() );
          if( !targetModelObject)
          {
            LOG(Error, "Error importing object: " << wo->briefDescription() );
            continue;
          }

          if( OptionalHVACComponent hvacComponent = targetModelObject->optionalCast<HVACComponent>() )
          {
            Node node = airLoopHVAC.supplyOutletNode();
            if( hvacComponent->addToNode(node) )
            {
              if( boost::optional<StraightComponent> straightComponent = hvacComponent->optionalCast<StraightComponent>() )
              {
                Node outletNode = straightComponent->outletModelObject()->cast<Node>();
                Node inletNode = straightComponent->inletModelObject()->cast<Node>();
                if( componentOutletNodeName )
                {
                  outletNode.setName(componentOutletNodeName.get());
                }
                if( componentInletNodeName )
                {
                  inletNode.setName(componentInletNodeName.get());
                }
              }
              else if( boost::optional<AirLoopHVACOutdoorAirSystem> oaSystem = hvacComponent->optionalCast<AirLoopHVACOutdoorAirSystem>() )
              {
                Node outletNode = oaSystem->mixedAirModelObject()->cast<Node>();
                Node inletNode = oaSystem->returnAirModelObject()->cast<Node>();
                if( componentOutletNodeName )
                {
                  outletNode.setName(componentOutletNodeName.get());
                }
                if( componentInletNodeName )
                {
                  inletNode.setName(componentInletNodeName.get());
                }
              }
            }
          }
        }
        else
        {
          LOG(Error, _supplyBranch->briefDescription() << ": Missing object listed at ComponentName " << i);
        }
      }
    }
  }
  else
  {
    LOG( Error, workspaceObject.briefDescription() << ": Missing supply branch list, "
              << "Supply equipment will be incomplete");
  }

  // March through the zone on the demand side and add branches for them.
  if( demandOutletNodeName )
  {
    // Find the zone mixer for this air loop
    std::vector<WorkspaceObject> _airLoopHVACZoneMixers;
    _airLoopHVACZoneMixers = workspaceObject.workspace().getObjectsByType(IddObjectType::AirLoopHVAC_ZoneMixer);

    boost::optional<WorkspaceObject> _airLoopHVACZoneMixer;
    for( const auto & elem : _airLoopHVACZoneMixers )
    {
      boost::optional<std::string> mixerOutletNodeName;
      mixerOutletNodeName = elem.getString(AirLoopHVAC_ZoneMixerFields::OutletNodeName);

      if( mixerOutletNodeName && mixerOutletNodeName.get() == demandOutletNodeName.get() )
      {
        _airLoopHVACZoneMixer = elem;
        break;
      }
    }
    if( _airLoopHVACZoneMixer )
    {
      for( int i = 2;
           _airLoopHVACZoneMixer->getString(i);
           i++ )
      {

        std::vector<WorkspaceObject> _zoneHVACEquipmentConnections;

        std::string mixerInletNodeName = _airLoopHVACZoneMixer->getString(i).get();

        _zoneHVACEquipmentConnections = _workspace.getObjectsByType(IddObjectType::ZoneHVAC_EquipmentConnections);

        for( const auto & _zoneHVACEquipmentConnection : _zoneHVACEquipmentConnections )
        {

          OptionalString returnAirNodeName = _zoneHVACEquipmentConnection.getString(ZoneHVAC_EquipmentConnectionsFields::ZoneReturnAirNodeName);
          OptionalString inletAirNodeName = _zoneHVACEquipmentConnection.getString(ZoneHVAC_EquipmentConnectionsFields::ZoneAirInletNodeorNodeListName);
          OptionalString zoneName = _zoneHVACEquipmentConnection.getString(ZoneHVAC_EquipmentConnectionsFields::ZoneName);
          OptionalString zoneEquipListName = _zoneHVACEquipmentConnection.getString(ZoneHVAC_EquipmentConnectionsFields::ZoneConditioningEquipmentListName);

          OptionalWorkspaceObject _zone;
          OptionalWorkspaceObject _zoneEquipmentList;
          OptionalWorkspaceObject _zoneEquipment;
          OptionalWorkspaceObject _airTerminal; 

          if( returnAirNodeName &&
              returnAirNodeName.get() == mixerInletNodeName &&
              zoneName &&
              zoneEquipListName )
          {
            _zone = _workspace.getObjectByTypeAndName(IddObjectType::Zone,*zoneName);

            _zoneEquipmentList = _workspace.getObjectByTypeAndName(IddObjectType::ZoneHVAC_EquipmentList,zoneEquipListName.get());

            if( ! _zone )
            {
              LOG( Error, 
                  airLoopHVAC.briefDescription()
                  << " is connected to a zone that does not exist." );

              break;
            }

            if( ! _zoneEquipmentList )
            {
              LOG( Error, 
                  _zone->briefDescription()
                  << " does not have a zone equipment list, but it is attached to a loop." );

              break;
            }

            for( int j = 1; (optionalString = _zoneEquipmentList->getString(j)); j = j + 4 )
            {
              boost::optional<std::string> zoneEquipmentName = _zoneEquipmentList->getString(j+1) ;
              // Possible Zone Equipment
              //
              // ZoneHVAC:AirDistributionUnit
              // AirTerminal:SingleDuct:Uncontrolled
              // ZoneHVAC:EnergyRecoveryVentilator
              // ZoneHVAC:FourPipeFanCoil
              // ZoneHVAC:OutdoorAirUnit
              // ZoneHVAC:PackagedTerminalAirConditioner
              // ZoneHVAC:PackagedTerminalHeatPump
              // ZoneHVAC:UnitHeater
              // ZoneHVAC:UnitVentilator
              // ZoneHVAC:VentilatedSlab
              // ZoneHVAC:WaterToAirHeatPump
              // ZoneHVAC:WindowAirConditioner
              // ZoneHVAC:Baseboard:RadiantConvective:Electric
              // ZoneHVAC:Baseboard:RadiantConvective:Water
              // ZoneHVAC:Baseboard:RadiantConvective:Steam
              // ZoneHVAC:Baseboard:Convective:Electric
              // ZoneHVAC:Baseboard:Convective:Water
              // ZoneHVAC:HighTemperatureRadiant
              // ZoneHVAC:LowTemperatureRadiant:VariableFlow
              // ZoneHVAC:LowTemperatureRadiant:ConstantFlow
              // ZoneHVAC:LowTemperatureRadiant:Electric
              // ZoneHVAC:Dehumidifier:DX
              // ZoneHVAC:IdealLoadsAirSystem
              // Fan:ZoneExhaust
              // WaterHeater:HeatPump
              //
              if( zoneEquipmentName )
              {
                if( istringEqual(optionalString.get(),"AirTerminal:SingleDuct:Uncontrolled") )
                {
                  _airTerminal = _workspace.getObjectByTypeAndName(IddObjectType::AirTerminal_SingleDuct_Uncontrolled,zoneEquipmentName.get());

                  break;
                }
                else if( istringEqual(optionalString.get(),"ZoneHVAC:AirDistributionUnit") )
                {
                  boost::optional<WorkspaceObject> _airDistributionUnit = 
                    _workspace.getObjectByTypeAndName(IddObjectType::ZoneHVAC_AirDistributionUnit,zoneEquipmentName.get());

                  if( _airDistributionUnit )
                  {
                    boost::optional<std::string> airUnitName;
                    boost::optional<std::string> airUnitType;

                    airUnitType = _airDistributionUnit->getString(ZoneHVAC_AirDistributionUnitFields::AirTerminalObjectType);
                    airUnitName = _airDistributionUnit->getString(ZoneHVAC_AirDistributionUnitFields::AirTerminalName);

                    if( airUnitName && airUnitType )
                    {
                      _airTerminal = _workspace.getObjectByTypeAndName(IddObjectType(airUnitType.get()),airUnitName.get());
                    }
                  }

                  break;
                }
              }
            }

            OptionalModelObject airTerminalModelObject;
            OptionalSpace space;
            OptionalStraightComponent straightComponent;
            OptionalThermalZone thermalZone;

            if( _airTerminal )
            {
              airTerminalModelObject = translateAndMapWorkspaceObject( _airTerminal.get() );
            }

            if( _zone )
            {
              if( OptionalModelObject mo = translateAndMapWorkspaceObject( _zone.get() ) )
              {
                space = mo->optionalCast<Space>();
              }
            }

            if( space )
            {
              thermalZone = space->thermalZone();
            }

            if( airTerminalModelObject )
            {
              straightComponent = airTerminalModelObject->optionalCast<StraightComponent>();
            }

            bool success = false;

            if( straightComponent && thermalZone )
            {
              success = airLoopHVAC.addBranchForZone(thermalZone.get(),straightComponent.get());
            }
            else if( thermalZone )
            {
              Model m;

              success = airLoopHVAC.addBranchForZone(thermalZone.get(),boost::none);
            }

            if( success )
            {
              if( inletAirNodeName ) { thermalZone->inletPortList().airLoopHVACModelObject()->cast<Node>().setName(inletAirNodeName.get()); }
              if( returnAirNodeName ) { thermalZone->returnAirModelObject()->cast<Node>().setName(returnAirNodeName.get()); }
            }
          }
        }
      }
    }
  }

  return airLoopHVAC;
}
Example #22
0
TEST_F(IdfFixture, IdfObject_DefaultFieldComments) {
  // OBJECT WITH NO FIELD COMMENTS
  std::stringstream text;
  text << "  Schedule:Day:Interval," << std::endl
       << "    A Schedule," << std::endl
       << "    Any Number," << std::endl
       << "    ," << std::endl
       << "    09:00," << std::endl
       << "    0," << std::endl
       << "    22:00," << std::endl
       << "    1," << std::endl
       << "    24:00," << std::endl
       << "    0;";
  OptionalIdfObject oObj = IdfObject::load(text.str());
  ASSERT_TRUE(oObj);
  IdfObject object = *oObj;
  // non-extensible fields
  OptionalString fc = object.fieldComment(0,true);
  OptionalIddField iddField = object.iddObject().getField(0);
  ASSERT_TRUE(fc); ASSERT_TRUE(iddField);
  EXPECT_EQ(makeIdfEditorComment(iddField->name()),*fc);
  fc = object.fieldComment(0);
  ASSERT_TRUE(fc); EXPECT_TRUE(fc->empty());

  fc = object.fieldComment(2,true);
  iddField = object.iddObject().getField(2);
  ASSERT_TRUE(fc); ASSERT_TRUE(iddField);
  EXPECT_EQ(makeIdfEditorComment(iddField->name()),*fc);
  fc = object.fieldComment(2);
  ASSERT_TRUE(fc); EXPECT_TRUE(fc->empty());

  // extensible fields
  fc = object.fieldComment(6,true);
  iddField = object.iddObject().getField(6);
  ASSERT_TRUE(fc); ASSERT_TRUE(iddField);
  EXPECT_EQ(makeIdfEditorComment(iddField->name()) + " 2",*fc);
  fc = object.fieldComment(6);
  ASSERT_TRUE(fc); EXPECT_TRUE(fc->empty());

  // non-existant fields
  fc = object.fieldComment(14,true);
  EXPECT_FALSE(fc);

  // OBJECT WITH SOME FIELD COMMENTS
  text.str("");
  text << "  Schedule:Day:Interval," << std::endl
       << "    A Schedule," << std::endl
       << "    Any Number," << std::endl
       << "    ," << std::endl
       << "    09:00, ! opening time" << std::endl
       << "    0," << std::endl
       << "    22:00, ! closing time" << std::endl
       << "    1," << std::endl
       << "    24:00," << std::endl
       << "    0;";
  oObj = IdfObject::load(text.str());
  ASSERT_TRUE(oObj);
  object = *oObj;
  // returns set values
  fc = object.fieldComment(3,true);
  ASSERT_TRUE(fc);
  EXPECT_EQ("! opening time",*fc);
  fc = object.fieldComment(5,true);
  ASSERT_TRUE(fc);
  EXPECT_EQ("! closing time",*fc);

  // returns default for fields behind fields with set values
  fc = object.fieldComment(4,true);
  iddField = object.iddObject().getField(4);
  ASSERT_TRUE(fc); ASSERT_TRUE(iddField);
  EXPECT_EQ(makeIdfEditorComment(iddField->name()) + " 1",*fc);
  fc = object.fieldComment(6);
  ASSERT_TRUE(fc); EXPECT_TRUE(fc->empty());

  // returns default for fields past fields with set values
  fc = object.fieldComment(6,true);
  iddField = object.iddObject().getField(6);
  ASSERT_TRUE(fc); ASSERT_TRUE(iddField);
  EXPECT_EQ(makeIdfEditorComment(iddField->name()) + " 2",*fc);
  fc = object.fieldComment(6);
  ASSERT_TRUE(fc); EXPECT_TRUE(fc->empty());

}
boost::optional<IdfObject> ForwardTranslator::translateHeatExchangerFluidToFluid( HeatExchangerFluidToFluid & modelObject )
{
  OptionalString s;
  OptionalDouble d;
  OptionalModelObject mo;
  boost::optional<IdfObject> idfo;

  IdfObject idfObject(IddObjectType::HeatExchanger_FluidToFluid);

  m_idfObjects.push_back(idfObject);

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

  // AvailabilityScheduleName
  boost::optional<Schedule> sched = modelObject.availabilitySchedule();
  if( (idfo = translateAndMapModelObject(sched.get())) )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::AvailabilityScheduleName,idfo->name().get());
  }

  // LoopDemandSideInletNode
  mo = modelObject.demandInletModelObject();
  if( mo )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::LoopDemandSideInletNodeName,mo->name().get());
  }

  // LoopDemandSideOutletNode
  mo = modelObject.demandOutletModelObject();
  if( mo )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::LoopDemandSideOutletNodeName,mo->name().get());
  }

  // LoopDemandSideDesignFlowRate
  if( modelObject.isLoopDemandSideDesignFlowRateAutosized() )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::LoopDemandSideDesignFlowRate,"Autosize");
  }
  else
  {
    if( (d = modelObject.loopDemandSideDesignFlowRate()) )
    {
      idfObject.setDouble(HeatExchanger_FluidToFluidFields::LoopDemandSideDesignFlowRate,d.get());
    }
  }

  // LoopSupplySideInletNode
  mo = modelObject.supplyInletModelObject();
  if( mo )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::LoopSupplySideInletNodeName,mo->name().get());
  }

  // LoopSupplySideOutletNode
  mo = modelObject.supplyOutletModelObject();
  if( mo )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::LoopSupplySideOutletNodeName,mo->name().get());
  }

  // LoopSupplySideDesignFlowRate
  if( modelObject.isLoopSupplySideDesignFlowRateAutosized() )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::LoopSupplySideDesignFlowRate,"Autosize");
  }
  else
  {
    if( (d = modelObject.loopSupplySideDesignFlowRate()) )
    {
      idfObject.setDouble(HeatExchanger_FluidToFluidFields::LoopSupplySideDesignFlowRate,d.get());
    }
  }

  // HeatExchangeModelType
  if( (s = modelObject.heatExchangeModelType()) )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::HeatExchangeModelType,s.get());
  }

  // HeatExchangerUFactorTimesAreaValue
  if( modelObject.isHeatExchangerUFactorTimesAreaValueAutosized() )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::HeatExchangerUFactorTimesAreaValue,"Autosize");
  }
  else
  {
    if( (d = modelObject.heatExchangerUFactorTimesAreaValue()) )
    {
      idfObject.setDouble(HeatExchanger_FluidToFluidFields::HeatExchangerUFactorTimesAreaValue,d.get());
    }
  }

  // ControlType
  if( (s = modelObject.controlType()) )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::ControlType,s.get());
  }

  // HeatExchangerSetpointNodeName
  if( (mo = modelObject.supplyOutletModelObject()) )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::HeatExchangerSetpointNodeName,mo->name().get());
  }

  // MinimumTemperatureDifferencetoActivateHeatExchanger
  if(  (d = modelObject.minimumTemperatureDifferencetoActivateHeatExchanger()) )
  {
    idfObject.setDouble(HeatExchanger_FluidToFluidFields::MinimumTemperatureDifferencetoActivateHeatExchanger,d.get());
  }

  // HeatTransferMeteringEndUseType
  if( (s = modelObject.heatTransferMeteringEndUseType()) )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::HeatTransferMeteringEndUseType,s.get());
  }

  // ComponentOverrideLoopSupplySideInletNode
  if( (mo = modelObject.componentOverrideLoopSupplySideInletNode()) )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::ComponentOverrideLoopSupplySideInletNodeName,mo->name().get());
  }

  // ComponentOverrideLoopDemandSideInletNode
  if( (mo = modelObject.componentOverrideLoopDemandSideInletNode()) )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::ComponentOverrideLoopDemandSideInletNodeName,mo->name().get());
  }

  // ComponentOverrideCoolingControlTemperatureMode
  if( (s = modelObject.componentOverrideCoolingControlTemperatureMode()) )
  {
    idfObject.setString(HeatExchanger_FluidToFluidFields::ComponentOverrideCoolingControlTemperatureMode,s.get());
  }

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

  // OperationMinimumTemperatureLimit
  if( (d = modelObject.operationMinimumTemperatureLimit()) )
  {
    idfObject.setDouble(HeatExchanger_FluidToFluidFields::OperationMinimumTemperatureLimit,d.get());
  }

  // OperationMaximumTemperatureLimit
  if( (d = modelObject.operationMaximumTemperatureLimit()) )
  {
    idfObject.setDouble(HeatExchanger_FluidToFluidFields::OperationMaximumTemperatureLimit,d.get());
  }

  return 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::translateControllerMechanicalVentilation( ControllerMechanicalVentilation& modelObject )
{
  OptionalString s;
  OptionalDouble d;
  OptionalModelObject temp;

  IdfObject idfObject(IddObjectType::Controller_MechanicalVentilation);

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

  // Availability Schedule
  // If there is a ControllerOutdoorAir::minimumOutdoorAirSchedule
  // then use that for the ControllerMechanicalVentilation::availabilitySchedule
  // Note that this scheme will not support fractions (schedule values above 0) because anything greater than 0 will
  // make the mechanical ventilation controller avaiable and thus taking precedence.
  bool useAvailabiltySchedule = true;
  auto availabilitySchedule = modelObject.availabilitySchedule();

  // Find the associated oa controller
  auto oaControllers = modelObject.model().getConcreteModelObjects<ControllerOutdoorAir>();
  auto predicate = [&] (const ControllerOutdoorAir & oaController) {
    auto mechanicalVentilationController = oaController.controllerMechanicalVentilation();
    if( mechanicalVentilationController.handle() == modelObject.handle() ) {
      return true;
    }
    return false;
  };
  auto oaController = std::find_if(oaControllers.begin(),oaControllers.end(),predicate);
  // alwaysOnDiscreteSchedule is the default availability schedule for the mechanical ventilation controller
  // if the default is still in place BUT the user has defined a minimumOutdoorAirSchedule for the oa controller,
  // then use the minimumOutdoorAirSchedule for the mechanical ventilation controller availability schedule
  // The minimumOutdoorAirSchedule will not do its job while the controller mechanical ventilation object is available.
  if( availabilitySchedule == modelObject.model().alwaysOnDiscreteSchedule() ) {
    if( oaController != oaControllers.end() ) {
      if( auto minOASchedule = oaController->minimumOutdoorAirSchedule() ) {
        auto _schedule = translateAndMapModelObject(minOASchedule.get());
        OS_ASSERT(_schedule);
        idfObject.setString(Controller_MechanicalVentilationFields::AvailabilityScheduleName,_schedule->name().get());
        useAvailabiltySchedule = false;
      }
    }
  }

  if( useAvailabiltySchedule ) {
    boost::optional<IdfObject> availabilityScheduleIdf = translateAndMapModelObject(availabilitySchedule);
    OS_ASSERT(availabilityScheduleIdf);
    idfObject.setString(openstudio::Controller_MechanicalVentilationFields::AvailabilityScheduleName,availabilityScheduleIdf->name().get());
  }

  // Demand Controlled Ventilation
  if( modelObject.demandControlledVentilation() )
  {
    idfObject.setString(openstudio::Controller_MechanicalVentilationFields::DemandControlledVentilation,"Yes");
  }
  else
  {
    idfObject.setString(openstudio::Controller_MechanicalVentilationFields::DemandControlledVentilation,"No");
  }

  // System Outdoor Air Method
  s = modelObject.systemOutdoorAirMethod();
  if( s )
  {
    if( istringEqual("ProportionalControl",s.get()) ) {
      idfObject.setString(openstudio::Controller_MechanicalVentilationFields::SystemOutdoorAirMethod,"ProportionalControlBasedonOccupancySchedule");
    } else {
      idfObject.setString(openstudio::Controller_MechanicalVentilationFields::SystemOutdoorAirMethod,s.get());
    }
  }

  m_idfObjects.push_back(idfObject);
  return boost::optional<IdfObject>(idfObject);
}