boost::optional<std::string> UtilityCost_Computation_Impl::computeStep(unsigned index) const {
  IdfExtensibleGroup eg = getExtensibleGroup(index);
  if (!eg.empty()) {
    return eg.getString(OS_UtilityCost_ComputationExtensibleFields::ComputeStep,true);
  }
  return boost::none;
}
Esempio n. 2
0
TEST_F(ModelFixture, ComponentWatcher_InComponent) {
  // create Component. ComponentWatcher should work here too (since Component is Model)
  Model model;
  DesignDay designDay(model);
  EXPECT_EQ(1u,model.numObjects());
  Component designDayComponent = designDay.createComponent();
  EXPECT_EQ(2u,designDayComponent.numObjects());
  ComponentData cd = designDayComponent.componentData();
  UUID versionUUID = cd.versionUUID();
  designDay = designDayComponent.primaryObject().cast<DesignDay>();

  // data changes ok--changes version
  EXPECT_TRUE(designDay.setName("My Design Day"));
  EXPECT_NE(versionUUID,cd.versionUUID());
  versionUUID = cd.versionUUID();

  // trying to assign contents results in refresh of contents
  IdfExtensibleGroup eg = cd.getExtensibleGroup(0);
  ASSERT_FALSE(eg.empty());
  std::string originalValue = eg.getString(0).get();
  EXPECT_FALSE(eg.setString(0,"Material"));
  EXPECT_TRUE(cd.initialized());
  EXPECT_EQ(2u,designDayComponent.numObjects());
  EXPECT_EQ(originalValue,eg.getString(0).get());
}
boost::optional<IdfObject> ForwardTranslator::createAirLoopHVACSupplyPath( const Node & demandInletNode )
{
  boost::optional<IdfObject> supplyPathIdf;

  if( auto t_airLoopHVAC = demandInletNode.airLoopHVAC() ) {
    IdfObject supplyPathIdf(openstudio::IddObjectType::AirLoopHVAC_SupplyPath);
    m_idfObjects.push_back(supplyPathIdf);

    supplyPathIdf.setName(t_airLoopHVAC->name().get() + " " + demandInletNode.name().get() + " Supply Path");

    supplyPathIdf.setString(openstudio::AirLoopHVAC_SupplyPathFields::SupplyAirPathInletNodeName,demandInletNode.name().get());

    auto t_comps = t_airLoopHVAC->demandComponents(demandInletNode,t_airLoopHVAC->demandOutletNode());
    auto splitters = subsetCastVector<model::AirLoopHVACZoneSplitter>(t_comps);
    OS_ASSERT(splitters.size() == 1u);

    boost::optional<IdfObject> _zoneSplitter = translateAndMapModelObject(splitters.front());
    OS_ASSERT(_zoneSplitter);
    IdfExtensibleGroup eg = supplyPathIdf.pushExtensibleGroup();
    eg.setString(AirLoopHVAC_SupplyPathExtensibleFields::ComponentObjectType,_zoneSplitter->iddObject().name());
    eg.setString(AirLoopHVAC_SupplyPathExtensibleFields::ComponentName,_zoneSplitter->name().get());

    std::vector<ModelObject> supplyPlenums = t_airLoopHVAC->demandComponents(demandInletNode,t_airLoopHVAC->demandOutletNode(),AirLoopHVACSupplyPlenum::iddObjectType());
    for( auto & supplyPlenum : supplyPlenums )
    {
      eg = supplyPathIdf.pushExtensibleGroup();
      boost::optional<IdfObject> _supplyPlenum = translateAndMapModelObject(supplyPlenum);
      OS_ASSERT(_supplyPlenum);
      eg.setString(AirLoopHVAC_SupplyPathExtensibleFields::ComponentObjectType,_supplyPlenum->iddObject().name());
      eg.setString(AirLoopHVAC_SupplyPathExtensibleFields::ComponentName,_supplyPlenum->name().get());
    }
  }

  return supplyPathIdf;
}
boost::optional<std::string> UtilityCost_Charge_Block_Impl::blockCostPerUnitValueOrVariableName(unsigned index) const {
  IdfExtensibleGroup eg = getExtensibleGroup(index);
  if (!eg.empty()) {
    return eg.getString(OS_UtilityCost_Charge_BlockExtensibleFields::BlockCostperUnitValueorVariableName,true);
  }
  return boost::none;
}
boost::optional<IdfObject> ForwardTranslator::createAirLoopHVACSupplyPath( AirLoopHVAC & airLoopHVAC )
{
  std::string s;

  IdfObject supplyPathIdf(openstudio::IddObjectType::AirLoopHVAC_SupplyPath);
  m_idfObjects.push_back(supplyPathIdf);

  supplyPathIdf.setName(airLoopHVAC.name().get() + " Supply Path");

  model::Node node = airLoopHVAC.demandInletNode();
  supplyPathIdf.setString(openstudio::AirLoopHVAC_SupplyPathFields::SupplyAirPathInletNodeName,node.name().get());

  model::AirLoopHVACZoneSplitter zoneSplitter = airLoopHVAC.zoneSplitter();

  boost::optional<IdfObject> _zoneSplitter = translateAndMapModelObject(zoneSplitter);
  OS_ASSERT(_zoneSplitter);
  IdfExtensibleGroup eg = supplyPathIdf.pushExtensibleGroup();
  eg.setString(AirLoopHVAC_SupplyPathExtensibleFields::ComponentObjectType,_zoneSplitter->iddObject().name());
  eg.setString(AirLoopHVAC_SupplyPathExtensibleFields::ComponentName,_zoneSplitter->name().get());

  std::vector<ModelObject> supplyPlenums = airLoopHVAC.demandComponents(AirLoopHVACSupplyPlenum::iddObjectType());
  for( std::vector<ModelObject>::iterator it = supplyPlenums.begin();
       it != supplyPlenums.end();
       it++ )
  {
    eg = supplyPathIdf.pushExtensibleGroup();
    boost::optional<IdfObject> _supplyPlenum = translateAndMapModelObject(*it);
    OS_ASSERT(_supplyPlenum);
    eg.setString(AirLoopHVAC_SupplyPathExtensibleFields::ComponentObjectType,_supplyPlenum->iddObject().name());
    eg.setString(AirLoopHVAC_SupplyPathExtensibleFields::ComponentName,_supplyPlenum->name().get());
  }

  return boost::optional<IdfObject>(supplyPathIdf);
}
  bool LayeredConstruction_Impl::insertLayer(unsigned layerIndex, 
                                             const Material& material) 
  {
    OS_ASSERT(material.model() == model());
    layerIndex = mf_clearNullLayers(layerIndex);

    unsigned n = numLayers();
    MaterialVector layers = this->layers();
    MaterialVector::iterator layersBegin = layers.begin();
    MaterialVector::iterator layersEnd = layers.end();
    MaterialVector::iterator insertAtIt = layersBegin;
    while ((static_cast<unsigned>(insertAtIt - layersBegin) < layerIndex) &&
           (insertAtIt != layersEnd)) 
    { ++insertAtIt; }
    layers.insert(insertAtIt, material);
    OS_ASSERT(layers.size() == ++n);
    if ((model().strictnessLevel() < StrictnessLevel::Final) || 
        LayeredConstruction::layersAreValid(layers)) 
    {
      IdfExtensibleGroup idfGroup = insertExtensibleGroup(layerIndex,StringVector());
      OS_ASSERT(!idfGroup.empty());
      ModelExtensibleGroup group = idfGroup.cast<ModelExtensibleGroup>();
      bool ok = group.setPointer(0,material.handle());
      OS_ASSERT(ok);
      return true;
    }

    return false;
  }
boost::optional<double> LifeCycleCostUsePriceEscalation_Impl::yearEscalation(unsigned index) const 
{
  IdfExtensibleGroup eg = getExtensibleGroup(index);
  if (!eg.empty()) {
    return eg.getDouble(OS_LifeCycleCost_UsePriceEscalationExtensibleFields::YearEscalation,true);
  }
  return boost::none;
}
Esempio n. 8
0
 ClimateZone ClimateZones_Impl::getClimateZone(unsigned index) const {
   IdfExtensibleGroup eg = getExtensibleGroup(index);
   if (eg.empty()) {
     std::shared_ptr<ClimateZones_Impl> p;
     return ClimateZone(p,numFields());
   }
   return eg.cast<ClimateZone>();
 }      
 boost::optional<std::string> PeopleDefinition_Impl::getThermalComfortModelType(int i) const {
   OptionalString result;
   if (i < numThermalComfortModelTypes()) {
     IdfExtensibleGroup eg = getExtensibleGroup(i);
     OS_ASSERT(!eg.empty());
     result = eg.getString(OS_People_DefinitionExtensibleFields::ThermalComfortModelType,true);
   }
   return result;
 }
Esempio n. 10
0
 bool ComponentData_Impl::registerObject(const ModelObject& object) {
   IdfExtensibleGroup eg = pushExtensibleGroup(StringVector());
   bool result = !eg.empty();
   if (result) {
     ModelExtensibleGroup meg = eg.cast<ModelExtensibleGroup>();
     result = result && meg.setPointer(OS_ComponentDataExtensibleFields::NameofObject,
                                       object.handle());
   }
   return result;
 }
bool UtilityCost_Computation_Impl::setComputeStep(unsigned index, const std::string& str) {
  IdfExtensibleGroup eg = getExtensibleGroup(index);
  if (!eg.empty()) {
    return eg.setString(OS_UtilityCost_ComputationExtensibleFields::ComputeStep,str);
  }
  else {
    StringVector values(1u,str);
    return !insertExtensibleGroup(index,values).empty();
  }
  OS_ASSERT(false);
  return false;
}
boost::optional<IdfObject> ForwardTranslator::translateScheduleDay( ScheduleDay & modelObject )
{
  IdfObject scheduleDay = createRegisterAndNameIdfObject(openstudio::IddObjectType::Schedule_Day_Interval,
                                                         modelObject);

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

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

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

  scheduleDay.clearExtensibleGroups();

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

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

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

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

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

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

  return scheduleDay;
}
bool UtilityCost_Charge_Block_Impl::setBlockCostPerUnitValueOrVariableName(unsigned index, const std::string& str) {
  IdfExtensibleGroup eg = getExtensibleGroup(index);
  if (!eg.empty()) {
    return eg.setString(OS_UtilityCost_Charge_BlockExtensibleFields::BlockCostperUnitValueorVariableName,str);
  }
  else {
    StringVector values(2u);
    values[OS_UtilityCost_Charge_BlockExtensibleFields::BlockCostperUnitValueorVariableName] = str;
    return !insertExtensibleGroup(index,values).empty();
  }
  OS_ASSERT(false);
  return false;
}
 bool EnergyManagementSystemProgramCallingManager_Impl::setProgram(const EnergyManagementSystemProgram& program, unsigned index) {
   //add program to {index} of vector of programs
   bool result = false;
   auto groups = extensibleGroups();
   unsigned sizeOfGroup = numExtensibleGroups();
   if (index <= sizeOfGroup) {
     IdfExtensibleGroup idfGroup = insertExtensibleGroup(index, StringVector());
     OS_ASSERT(!idfGroup.empty());
     ModelExtensibleGroup group = idfGroup.cast<ModelExtensibleGroup>();
     result = group.setPointer(0, program.handle());
   }
   return result;
 }
Esempio n. 15
0
TEST_F(ModelFixture, ComponentWatcher_FromScratch) {
  // create schedule component
  Model justASchedule;
  ScheduleTypeLimits typeLimits(justASchedule);
  typeLimits.setName("Fraction");
  typeLimits.setLowerLimitValue(0.0);
  typeLimits.setUpperLimitValue(1.0);
  typeLimits.setNumericType("Continuous");
  ScheduleCompact schedule(justASchedule);
  EXPECT_TRUE(schedule.setPointer(OS_Schedule_CompactFields::ScheduleTypeLimitsName,
                                  typeLimits.handle()));
  Component scheduleComponent = schedule.createComponent();

  // create model with Lights objects and insert schedule component
  Model justLights;
  LightsDefinition lightsDefinition(justLights);
  Lights light1(lightsDefinition);
  OptionalComponentData ocd = justLights.insertComponent(scheduleComponent);

  // get ComponentData object
  ASSERT_TRUE(ocd);
  ComponentData componentData = *ocd;
  UUID versionUUID = componentData.versionUUID();

  // setting lighting schedule does not invalidate schedule component, or change its version UUID
  OptionalScheduleCompact oSchedule = componentData.primaryComponentObject().optionalCast<ScheduleCompact>();
  ASSERT_TRUE(oSchedule);
  schedule = *oSchedule;
  EXPECT_TRUE(light1.setSchedule(schedule));
  ASSERT_TRUE(componentData.initialized());
  EXPECT_EQ(versionUUID,componentData.versionUUID());

  // changing data field in componentObject does not invalidate schedule component, but does change version UUID
  StringVector values;
  values.push_back("Through: 12/31");
  IdfExtensibleGroup eg = componentData.primaryComponentObject().pushExtensibleGroup(values);
  EXPECT_FALSE(eg.empty());
  ASSERT_TRUE(componentData.initialized());
  EXPECT_NE(versionUUID,componentData.versionUUID());
  versionUUID = componentData.versionUUID();

  // changing type limits used by schedule in component invalidates the component
  Handle h = componentData.handle();
  EXPECT_TRUE(justLights.isMember(h));
  ScheduleTypeLimits newTypeLimits = typeLimits.clone(justLights).cast<ScheduleTypeLimits>();
  EXPECT_FALSE(newTypeLimits.handle() == typeLimits.handle());
  EXPECT_TRUE(schedule.setPointer(OS_Schedule_CompactFields::ScheduleTypeLimitsName,newTypeLimits.handle()));
  EXPECT_FALSE(componentData.initialized());
  EXPECT_FALSE(justLights.isMember(h));
}
bool LifeCycleCostUsePriceEscalation_Impl::setYearEscalation(unsigned index, double num) {
  IdfExtensibleGroup eg = getExtensibleGroup(index);
  if (!eg.empty()) {
    return eg.setDouble(OS_LifeCycleCost_UsePriceEscalationExtensibleFields::YearEscalation,num);
  }
  else {
    StringVector values(1u);
    eg = insertExtensibleGroup(index,values);
    if (!eg.empty()) { 
      return eg.setDouble(OS_LifeCycleCost_UsePriceEscalationExtensibleFields::YearEscalation,num);
    }
  }
  return false;
}
Esempio n. 17
0
 bool PeopleDefinition_Impl::setThermalComfortModelType(
     int i, const std::string& thermalComfortModelType)
 {
   int n = numThermalComfortModelTypes();
   if (i == n) {
     return pushThermalComfortModelType(thermalComfortModelType);
   }
   if (i < n) {
     IdfExtensibleGroup eg = getExtensibleGroup(i);
     OS_ASSERT(!eg.empty());
     return eg.setString(OS_People_DefinitionExtensibleFields::ThermalComfortModelType,
                         thermalComfortModelType);
   }
   return false;
 }
Esempio n. 18
0
TEST_F(ModelFixture, ComponentWatcher_ComponentData_Interactions) {

  // create osm file that contains ComponentData
  Model model;
  DesignDay designDay(model);
  EXPECT_EQ(1u,model.numObjects());
  Component designDayComponent = designDay.createComponent();
  ComponentData componentData = designDayComponent.componentData();
  UUID uuid = componentData.uuid();
  UUID versionUUID = componentData.versionUUID();
  EXPECT_FALSE(versionUUID.isNull());
  model = Model();
  EXPECT_EQ(0u,model.numObjects());
  OptionalComponentData ocd = model.insertComponent(designDayComponent);
  ASSERT_TRUE(ocd);
  EXPECT_EQ(2u,model.numObjects());

  // simple insert should not change component UUIDs.
  componentData = *ocd;
  EXPECT_EQ(uuid,componentData.uuid());
  EXPECT_EQ(versionUUID,componentData.versionUUID());

  // changing data fields of component objects causes version id to change
  componentData.primaryComponentObject().cast<DesignDay>().setMaximumDryBulbTemperature(50.0);
  EXPECT_EQ(uuid,componentData.uuid());
  EXPECT_NE(versionUUID,componentData.versionUUID());
  versionUUID = componentData.versionUUID();

  // trying to change contents field to an invalid value directly is not allowed
  IdfExtensibleGroup eg = componentData.getExtensibleGroup(0);
  ASSERT_FALSE(eg.empty());
  std::string originalValue = eg.getString(0).get();
  EXPECT_EQ("Sizing Period Design Day 1",originalValue);
  EXPECT_FALSE(eg.setString(0,"My Material"));
  EXPECT_TRUE(componentData.initialized());
  EXPECT_EQ(2u,model.numObjects());
  EXPECT_EQ(originalValue,eg.getString(0).get());

  // ComponentData.remove() is okay (should automatically delete the ComponentWatcher)
  ocd = model.insertComponent(designDayComponent);
  ASSERT_TRUE(ocd);
  // should find original DesignDay and reinstantiate ComponentData
  EXPECT_EQ(2u,model.numObjects());
  componentData = *ocd;
  ASSERT_TRUE(componentData.initialized());
  EXPECT_FALSE(componentData.remove().empty());
  EXPECT_EQ(static_cast<unsigned>(1),model.numObjects());
}
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;
  }

  IdfObject idfObject(IddObjectType::ZoneHVAC_EquipmentList);

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

  for( std::vector<ModelObject>::iterator it = objects.begin();
       it != objects.end();
       it++ )
  {
    unsigned coolingPriority = modelObject.coolingPriority(*it);
    unsigned heatingPriority = modelObject.heatingPriority(*it);

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

    if( _equipment )
    {
      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); 
    }
  }

  m_idfObjects.push_back(idfObject);

  return idfObject;
}
Esempio n. 20
0
 ClimateZone ClimateZones_Impl::appendClimateZone(const std::string& institution, 
                                                  const std::string documentName, 
                                                  unsigned year, 
                                                  const std::string& value) 
 {
   StringVector values;
   values.push_back(institution);
   values.push_back(documentName);
   std::stringstream ss;
   ss << year;
   values.push_back(ss.str());
   values.push_back(value);
   IdfExtensibleGroup eg = pushExtensibleGroup(values);
   if (eg.empty()) {
     std::shared_ptr<ClimateZones_Impl> p;
     return ClimateZone(p,numFields());
   }
   return eg.cast<ClimateZone>();
 }
Esempio n. 21
0
  bool ScheduleDay_Impl::addValue(const openstudio::Time& untilTime, double value) {
    if (untilTime.totalMinutes() <= 0.5 || untilTime.totalDays() > 1.0) {
      return false;
    }

    int untilHours = untilTime.hours() + 24*untilTime.days();
    int untilMinutes = untilTime.minutes() + floor((untilTime.seconds()/60.0) + 0.5);

    if (untilMinutes >= 60){
      untilHours += 1;
      untilMinutes += -60;
    }

    // use set to determine whether to overwrite or insert, and where
    std::set<openstudio::Time> times;
    std::pair<std::set<openstudio::Time>::const_iterator,bool> insertResult;
    for (const openstudio::Time& time : this->times()) {
      insertResult = times.insert(time);
      OS_ASSERT(insertResult.second);
    }

    insertResult = times.insert(untilTime);
    unsigned index = std::distance<std::set<openstudio::Time>::const_iterator>(times.begin(),insertResult.first);
    OS_ASSERT(index <= numExtensibleGroups());
    bool result(true);
    if (insertResult.second) {
      // new time--insert an extensible group
      std::vector<std::string> groupValues;
      groupValues.push_back(boost::lexical_cast<std::string>(untilHours));
      groupValues.push_back(boost::lexical_cast<std::string>(untilMinutes));
      groupValues.push_back(toString(value));

      IdfExtensibleGroup group = insertExtensibleGroup(index, groupValues);
      OS_ASSERT(!group.empty());
    }
    else {
      // time already exists, overwrite value
      IdfExtensibleGroup group = getExtensibleGroup(index);
      result = group.setDouble(OS_Schedule_DayExtensibleFields::ValueUntilTime,value);
    }

    return result;
  }
Esempio n. 22
0
  ModelObject ComponentData_Impl::getComponentObject(unsigned objectIndex) const {
    if (objectIndex >= numComponentObjects()) {
      LOG_AND_THROW("objectIndex = " << objectIndex << " >= numComponentObjects() = " << numComponentObjects() << ".");
    }

    IdfExtensibleGroup eg = getExtensibleGroup(objectIndex);
    if (eg.empty()) {
      LOG_AND_THROW("Cannot retrieve IdfExtensibleGroup at objectIndex = " << objectIndex);
    }

    ModelExtensibleGroup componentObjectData = eg.cast<ModelExtensibleGroup>();
    OptionalModelObject omo = componentObjectData.getModelObjectTarget<ModelObject>(
        OS_ComponentDataExtensibleFields::NameofObject);
    if (!omo) {
      LOG_AND_THROW("Cannot retrieve ModelObject at objectIndex = " << objectIndex);
    }

    return *omo;
  }
void makeUsePriceEscalation(boost::optional<double> rate, const std::string& fuelName, const std::string& baseDateMonth, int baseDateYear, int lengthOfStudyPeriodInYears, std::vector<IdfObject>& idfObjects)
{
  if (!rate || rate.get() == 0){
    return;
  }

  IdfObject idfObject(IddObjectType::LifeCycleCost_UsePriceEscalation);
  idfObject.setName(fuelName + " Use Price Escalation");
  idfObject.setString(LifeCycleCost_UsePriceEscalationFields::Resource, fuelName);
  idfObject.setInt(LifeCycleCost_UsePriceEscalationFields::EscalationStartYear, baseDateYear);
  idfObject.setString(LifeCycleCost_UsePriceEscalationFields::EscalationStartMonth, baseDateMonth);

  for (int i = 0; i < lengthOfStudyPeriodInYears; ++i){
    IdfExtensibleGroup group = idfObject.pushExtensibleGroup();
    double value = pow(1.0+rate.get(), i);
    group.setDouble(LifeCycleCost_UsePriceEscalationExtensibleFields::YearEscalation, value);
  }

  idfObjects.push_back(idfObject);
}
boost::optional<IdfObject> ForwardTranslator::translatePortList( PortList & modelObject )
{
  OptionalString s;
  OptionalDouble d;
  OptionalModelObject temp;

  // Create a new IddObjectType::NodeList
  // If you don't want a node list based on the port list, don't use this translator

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

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

  IdfObject idfObject(IddObjectType::NodeList);

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

  for( std::vector<ModelObject>::iterator it = modelObjects.begin();
       it != modelObjects.end();
       it++ )
  {
    if( boost::optional<Node> node = it->optionalCast<Node>() )
    {
      IdfExtensibleGroup group = idfObject.pushExtensibleGroup();

      group.setString(NodeListExtensibleFields::NodeName,node->name().get());
    }
  }

  m_idfObjects.push_back(idfObject);

  return idfObject;
}
Esempio n. 25
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::createAirLoopHVACReturnPath( AirLoopHVAC & airLoopHVAC )
{
  IdfObject returnPathIdf(openstudio::IddObjectType::AirLoopHVAC_ReturnPath);
  m_idfObjects.push_back(returnPathIdf);

  returnPathIdf.setName(airLoopHVAC.name().get() + " Return Path");

  Node node = airLoopHVAC.demandOutletNode();
  returnPathIdf.setString(openstudio::AirLoopHVAC_ReturnPathFields::ReturnAirPathOutletNodeName,node.name().get());

  std::vector<ModelObject> returnPlenums = airLoopHVAC.demandComponents(AirLoopHVACReturnPlenum::iddObjectType());
  for( auto & returnPlenum : returnPlenums )
  {
    IdfExtensibleGroup eg = returnPathIdf.pushExtensibleGroup();
    boost::optional<IdfObject> _returnPlenum = translateAndMapModelObject(returnPlenum);
    OS_ASSERT(_returnPlenum);
    eg.setString(AirLoopHVAC_ReturnPathExtensibleFields::ComponentObjectType,_returnPlenum->iddObject().name());
    eg.setString(AirLoopHVAC_ReturnPathExtensibleFields::ComponentName,_returnPlenum->name().get());
  }

  AirLoopHVACZoneMixer zoneMixer = airLoopHVAC.zoneMixer();
  boost::optional<IdfObject> _zoneMixer = translateAndMapModelObject(zoneMixer);
  OS_ASSERT(_zoneMixer);
  IdfExtensibleGroup eg = returnPathIdf.pushExtensibleGroup();
  eg.setString(AirLoopHVAC_ReturnPathExtensibleFields::ComponentObjectType,_zoneMixer->iddObject().name());
  eg.setString(AirLoopHVAC_ReturnPathExtensibleFields::ComponentName,_zoneMixer->name().get());

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

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

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

    return boost::none;
  }

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

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

  scheduleYear.clearExtensibleGroups();

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

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

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

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

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

  m_idfObjects.push_back(idfObject);

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

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

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

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

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

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

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

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

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

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

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

  // Hot Water Inlet Node Name
  // deprecated

  // Cold Water Inlet Node Name
  //deprecated

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return _airDistributionUnit;
}
boost::optional<IdfObject> ForwardTranslator::translatePlantEquipmentOperationSchemes( PlantLoop & plantLoop )
{
  IdfObject operationSchemes(IddObjectType::PlantEquipmentOperationSchemes);
  m_idfObjects.push_back(operationSchemes);

  operationSchemes.setName(plantLoop.name().get() + " Operation Schemes");

  // Lambda does what the name suggests, create setpoint operation schemes.
  // This is for any component that has a setpoint manager on its outlet node
  auto createSetpointOperationScheme = [&](PlantLoop & plantLoop) {
    const auto & t_setpointComponents = setpointComponents(plantLoop);
    if( ! t_setpointComponents.empty() ) {
      Schedule alwaysOn = plantLoop.model().alwaysOnDiscreteSchedule();

      IdfObject setpointOperation(IddObjectType::PlantEquipmentOperation_ComponentSetpoint);
      setpointOperation.setName(plantLoop.name().get() + " Setpoint Operation Scheme");
      m_idfObjects.push_back(setpointOperation);
      setpointOperation.clearExtensibleGroups();

      IdfExtensibleGroup eg = operationSchemes.pushExtensibleGroup();
      eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeObjectType,setpointOperation.iddObject().name());
      eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeName,setpointOperation.name().get());
      eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeScheduleName,alwaysOn.name().get());

      for( auto setpointComponent : t_setpointComponents )
      {
        boost::optional<IdfObject> _idfObject = translateAndMapModelObject(setpointComponent);
        OS_ASSERT(_idfObject);

        IdfExtensibleGroup eg = setpointOperation.pushExtensibleGroup();
        eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::EquipmentObjectType,_idfObject->iddObject().name());
        eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::EquipmentName,_idfObject->name().get());
        if( const auto & t_inletNode = inletNode(plantLoop,setpointComponent) ) {
          eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::DemandCalculationNodeName,t_inletNode->name().get());
        }
        if( const auto & t_outletNode = outletNode(plantLoop,setpointComponent) ) {
          eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::SetpointNodeName,t_outletNode->name().get());
        }
        if( auto value = flowrate(setpointComponent) ) {
          eg.setDouble(PlantEquipmentOperation_ComponentSetpointExtensibleFields::ComponentFlowRate,value.get());
        } else {
          eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::ComponentFlowRate,"Autosize");
        }
        auto t_componentType = componentType(setpointComponent);
        switch(t_componentType)
        {
          case ComponentType::HEATING :
            eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::OperationType,"Heating");
            break;
          case ComponentType::COOLING :
            eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::OperationType,"Cooling");
            break;
          default :
            eg.setString(PlantEquipmentOperation_ComponentSetpointExtensibleFields::OperationType,"Dual");
            break;
        }
      }
    }
  };

  Schedule alwaysOn = plantLoop.model().alwaysOnDiscreteSchedule();
  bool applyDefault = true;

  // If any operation schemes are defined in the model then don't apply default operation schemes

  if( auto coolingLoadScheme = plantLoop.plantEquipmentOperationCoolingLoad() ) {
    auto _scheme = translateAndMapModelObject(coolingLoadScheme.get());
    OS_ASSERT(_scheme);
    auto eg = operationSchemes.pushExtensibleGroup();
    eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeObjectType,_scheme->iddObject().name());
    eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeName,_scheme->name().get());
    eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeScheduleName,alwaysOn.name().get());

    applyDefault = false;
  } 

  if( auto heatingLoadScheme = plantLoop.plantEquipmentOperationHeatingLoad() ) {
    auto _scheme = translateAndMapModelObject(heatingLoadScheme.get());
    OS_ASSERT(_scheme);
    auto eg = operationSchemes.pushExtensibleGroup();
    eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeObjectType,_scheme->iddObject().name());
    eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeName,_scheme->name().get());
    eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeScheduleName,alwaysOn.name().get());

    applyDefault = false;
  }

  if( auto primaryScheme = plantLoop.primaryPlantEquipmentOperationScheme() ) {
    auto _scheme = translateAndMapModelObject(primaryScheme.get());
    OS_ASSERT(_scheme);
    auto eg = operationSchemes.pushExtensibleGroup();
    eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeObjectType,_scheme->iddObject().name());
    eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeName,_scheme->name().get());
    eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeScheduleName,alwaysOn.name().get());

    createSetpointOperationScheme(plantLoop);
    applyDefault = false;
  }

  if( applyDefault ) {
    // If we get here then there must not be any operation schemes defined in the model 
    // and we should go ahead and create default schemes.
    const auto & t_heatingComponents = heatingComponents( plantLoop );
    if( ! t_heatingComponents.empty() ) {
      IdfObject heatingOperation(IddObjectType::PlantEquipmentOperation_HeatingLoad);
      heatingOperation.setName(plantLoop.name().get() + " Heating Operation Scheme");
      m_idfObjects.push_back(heatingOperation);
      heatingOperation.clearExtensibleGroups();

      IdfObject plantEquipmentList(IddObjectType::PlantEquipmentList);
      plantEquipmentList.setName(plantLoop.name().get() + " Heating Equipment List");
      plantEquipmentList.clearExtensibleGroups();
      m_idfObjects.push_back(plantEquipmentList);

      IdfExtensibleGroup eg = heatingOperation.pushExtensibleGroup();
      eg.setDouble(PlantEquipmentOperation_HeatingLoadExtensibleFields::LoadRangeLowerLimit,0.0);
      eg.setDouble(PlantEquipmentOperation_HeatingLoadExtensibleFields::LoadRangeUpperLimit,1E9);
      eg.setString(PlantEquipmentOperation_HeatingLoadExtensibleFields::RangeEquipmentListName,plantEquipmentList.name().get());

      eg = operationSchemes.pushExtensibleGroup();
      eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeObjectType,heatingOperation.iddObject().name());
      eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeName,heatingOperation.name().get());
      eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeScheduleName,alwaysOn.name().get());

      for( auto heatingComponent : t_heatingComponents ) {
        if( const auto & idfObject = translateAndMapModelObject(heatingComponent) ) {
          IdfExtensibleGroup eg = plantEquipmentList.pushExtensibleGroup();
          eg.setString(PlantEquipmentListExtensibleFields::EquipmentObjectType,idfObject->iddObject().name());
          eg.setString(PlantEquipmentListExtensibleFields::EquipmentName,idfObject->name().get());
        }
      }
    }

    const auto & t_coolingComponents = coolingComponents( plantLoop );
    if( ! t_coolingComponents.empty() ) {
      IdfObject coolingOperation(IddObjectType::PlantEquipmentOperation_CoolingLoad);
      coolingOperation.setName(plantLoop.name().get() + " Cooling Operation Scheme");
      m_idfObjects.push_back(coolingOperation);
      coolingOperation.clearExtensibleGroups();

      IdfObject plantEquipmentList(IddObjectType::PlantEquipmentList);
      plantEquipmentList.setName(plantLoop.name().get() + " Cooling Equipment List");
      plantEquipmentList.clearExtensibleGroups();
      m_idfObjects.push_back(plantEquipmentList);

      IdfExtensibleGroup eg = coolingOperation.pushExtensibleGroup();
      eg.setDouble(PlantEquipmentOperation_CoolingLoadExtensibleFields::LoadRangeLowerLimit,0.0);
      eg.setDouble(PlantEquipmentOperation_CoolingLoadExtensibleFields::LoadRangeUpperLimit,1E9);
      eg.setString(PlantEquipmentOperation_CoolingLoadExtensibleFields::RangeEquipmentListName,plantEquipmentList.name().get());

      eg = operationSchemes.pushExtensibleGroup();
      eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeObjectType,coolingOperation.iddObject().name());
      eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeName,coolingOperation.name().get());
      eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeScheduleName,alwaysOn.name().get());

      for( auto coolingComponent : t_coolingComponents ) {
        if( const auto & idfObject = translateAndMapModelObject(coolingComponent) ) {
          IdfExtensibleGroup eg = plantEquipmentList.pushExtensibleGroup();
          eg.setString(PlantEquipmentListExtensibleFields::EquipmentObjectType,idfObject->iddObject().name());
          eg.setString(PlantEquipmentListExtensibleFields::EquipmentName,idfObject->name().get());
        }
      }
    }

    const auto & t_uncontrolledComponents = uncontrolledComponents( plantLoop );
    if( ! t_uncontrolledComponents.empty() ) {

      IdfObject uncontrolledOperation(IddObjectType::PlantEquipmentOperation_Uncontrolled);
      uncontrolledOperation.setName(plantLoop.name().get() + " Uncontrolled Operation Scheme");
      m_idfObjects.push_back(uncontrolledOperation);
      uncontrolledOperation.clearExtensibleGroups();

      IdfObject plantEquipmentList(IddObjectType::PlantEquipmentList);
      plantEquipmentList.setName(plantLoop.name().get() + " Uncontrolled Equipment List");
      plantEquipmentList.clearExtensibleGroups();
      m_idfObjects.push_back(plantEquipmentList);

      uncontrolledOperation.setString(PlantEquipmentOperation_UncontrolledFields::EquipmentListName,plantEquipmentList.name().get());

      auto eg = operationSchemes.pushExtensibleGroup();
      eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeObjectType,uncontrolledOperation.iddObject().name());
      eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeName,uncontrolledOperation.name().get());
      eg.setString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeScheduleName,alwaysOn.name().get());

      for( auto uncontrolledComponent : t_uncontrolledComponents ) {
        if( const auto & idfObject = translateAndMapModelObject(uncontrolledComponent) ) {
          IdfExtensibleGroup eg = plantEquipmentList.pushExtensibleGroup();
          eg.setString(PlantEquipmentListExtensibleFields::EquipmentObjectType,idfObject->iddObject().name());
          eg.setString(PlantEquipmentListExtensibleFields::EquipmentName,idfObject->name().get());
        }
      }
    }

    createSetpointOperationScheme(plantLoop);
  }

  return operationSchemes;
}