TEST_F(EnergyPlusFixture, ForwardTranslator_ExternalInterfaceFunctionalMockupUnitImportToSchedule) {

  Model model;

  ExternalInterfaceFunctionalMockupUnitImport eifmui(model, "test name");

  ExternalInterfaceFunctionalMockupUnitImportToSchedule schedule(model, eifmui, "FMU", "FMU name", 10);

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::ExternalInterface_FunctionalMockupUnitImport_To_Schedule).size());
  //EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::ScheduleTypeLimits).size());

  WorkspaceObject object = workspace.getObjectsByType(IddObjectType::ExternalInterface_FunctionalMockupUnitImport_To_Schedule)[0];
  //WorkspaceObject object2 = workspace.getObjectsByType(IddObjectType::ScheduleTypeLimits)[0];

  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ScheduleFields::Name, false));
  EXPECT_EQ("External Interface Functional Mockup Unit Import To Schedule 1", object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ScheduleFields::Name, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ScheduleFields::ScheduleTypeLimitsNames, false));
  //EXPECT_EQ(object2.nameString(), object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ScheduleFields::ScheduleTypeLimitsNames, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ScheduleFields::FMUFileName, false));
  EXPECT_EQ(eifmui.fMUFileName(), object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ScheduleFields::FMUFileName, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ScheduleFields::FMUInstanceName, false));
  EXPECT_EQ("FMU", object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ScheduleFields::FMUInstanceName, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ScheduleFields::FMUVariableName, false));
  EXPECT_EQ("FMU name", object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ScheduleFields::FMUVariableName, false).get());
  ASSERT_TRUE(object.getDouble(ExternalInterface_FunctionalMockupUnitImport_To_ScheduleFields::InitialValue, false));
  EXPECT_EQ(10.0, object.getDouble(ExternalInterface_FunctionalMockupUnitImport_To_ScheduleFields::InitialValue, false).get());

  model.save(toPath("./ExternalInterfaceFunctionalMockupUnitImportToSchedule.osm"), true);
  workspace.save(toPath("./ExternalInterfaceFunctionalMockupUnitImportToSchedule.idf"), true);
}
TEST_F(EnergyPlusFixture,ForwardTranslator_Surface_Zone)
{
  Model model;

  ThermalZone thermalZone(model);

  Space space(model);
  space.setThermalZone(thermalZone);
  
  Point3dVector points;
  points.push_back(Point3d(0, 1, 0));
  points.push_back(Point3d(0, 0, 0));
  points.push_back(Point3d(1, 0, 0));
  points.push_back(Point3d(1, 1, 0));
  Surface surface(points, model);
  surface.setSpace(space);

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(0u, forwardTranslator.warnings().size());

  ASSERT_EQ(1u, workspace.getObjectsByType(IddObjectType::BuildingSurface_Detailed).size());
  ASSERT_EQ(1u, workspace.getObjectsByType(IddObjectType::Zone).size());

  WorkspaceObject surfaceObject = workspace.getObjectsByType(IddObjectType::BuildingSurface_Detailed)[0];
  WorkspaceObject zoneObject = workspace.getObjectsByType(IddObjectType::Zone)[0];

  ASSERT_TRUE(surfaceObject.getTarget(BuildingSurface_DetailedFields::ZoneName));
  EXPECT_EQ(zoneObject.handle(), surfaceObject.getTarget(BuildingSurface_DetailedFields::ZoneName)->handle());
}
TEST_F(EnergyPlusFixture, ForwardTranslator_ExternalInterfaceFunctionalMockupUnitImportFromVariable) {
  Model model;
  // add FMU
  ExternalInterfaceFunctionalMockupUnitImport eifmui(model, "test name");

  std::string outputVariableIndexKeyName = "outputVariableIndexKeyName";
  std::string outputVariableName = "outputVariableName";
  std::string fMUVariableName = "fMUVariableName";
  std::string fMUInstanceName = "fMUInstanceName";

  ExternalInterfaceFunctionalMockupUnitImportFromVariable variable(model, outputVariableIndexKeyName, outputVariableName, eifmui, fMUInstanceName, fMUVariableName);

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::ExternalInterface_FunctionalMockupUnitImport_From_Variable).size());
  //EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::ScheduleTypeLimits).size());

  WorkspaceObject object = workspace.getObjectsByType(IddObjectType::ExternalInterface_FunctionalMockupUnitImport_From_Variable)[0];
  //WorkspaceObject object2 = workspace.getObjectsByType(IddObjectType::ScheduleTypeLimits)[0];

  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_From_VariableFields::Output_VariableIndexKeyName, false));
  EXPECT_EQ(outputVariableIndexKeyName, object.getString(ExternalInterface_FunctionalMockupUnitImport_From_VariableFields::Output_VariableIndexKeyName, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_From_VariableFields::Output_VariableName, false));
  EXPECT_EQ(outputVariableName, object.getString(ExternalInterface_FunctionalMockupUnitImport_From_VariableFields::Output_VariableName, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_From_VariableFields::FMUFileName, false));
  EXPECT_EQ(eifmui.fMUFileName(), object.getString(ExternalInterface_FunctionalMockupUnitImport_From_VariableFields::FMUFileName, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_From_VariableFields::FMUInstanceName, false));
  EXPECT_EQ(fMUInstanceName, object.getString(ExternalInterface_FunctionalMockupUnitImport_From_VariableFields::FMUInstanceName, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_From_VariableFields::FMUVariableName, false));
  EXPECT_EQ(fMUVariableName, object.getString(ExternalInterface_FunctionalMockupUnitImport_From_VariableFields::FMUVariableName, false).get());

  model.save(toPath("./ExternalInterfaceFunctionalMockupUnitImportFromVariable.osm"), true);
  workspace.save(toPath("./ExternalInterfaceFunctionalMockupUnitImportFromVariable.idf"), true);
}
TEST_F(EnergyPlusFixture, ForwardTranslator_ExternalInterfaceSchedule) {

  Model model;
  ExternalInterfaceSchedule schedule(model, 10);
  EXPECT_EQ(10.0, schedule.initialValue());
  EXPECT_EQ("External Interface Schedule 1", schedule.nameString());

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::ExternalInterface_Schedule).size());
  //EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::ScheduleTypeLimits).size());

  WorkspaceObject object = workspace.getObjectsByType(IddObjectType::ExternalInterface_Schedule)[0];
  //WorkspaceObject object2 = workspace.getObjectsByType(IddObjectType::ScheduleTypeLimits)[0];

  ASSERT_TRUE(object.getString(ExternalInterface_ScheduleFields::Name, false));
  EXPECT_EQ("External Interface Schedule 1", object.getString(ExternalInterface_ScheduleFields::Name, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_ScheduleFields::ScheduleTypeLimitsName, false));
  //EXPECT_EQ(object2.nameString(), object.getString(ExternalInterface_ScheduleFields::ScheduleTypeLimitsName, false).get());
  ASSERT_TRUE(object.getDouble(ExternalInterface_ScheduleFields::InitialValue, false));
  EXPECT_EQ(10.0, object.getDouble(ExternalInterface_ScheduleFields::InitialValue, false).get());

  model.save(toPath("./ExternalInterfaceSchedule.osm"), true);
  workspace.save(toPath("./ExternalInterfaceSchedule.idf"), true);
}
TEST_F(EnergyPlusFixture,ForwardTranslator_SpaceInfiltrationEffectiveLeakageArea)
{
  Model model;
  SpaceInfiltrationEffectiveLeakageArea infiltration(model);

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(0u, forwardTranslator.warnings().size());
}
/*
TEST_F(EnergyPlusFixture,ForwardTranslator_LightShelf)
{
  ASSERT_TRUE(true);
}

TEST_F(EnergyPlusFixture,ForwardTranslator_Building)
{
  openstudio::model::Model model;
  openstudio::model::Building building(model);
  ForwardTranslator forwardTranslator(model);
  OptionalWorkspace outWorkspace = forwardTranslator.convert();
  ASSERT_TRUE(outWorkspace);
  EXPECT_EQ(static_cast<unsigned>(1), outWorkspace->getObjectsByType(IddObjectType::Building).size());
}

TEST_F(EnergyPlusFixture,ForwardTranslator_Zone)
{
  openstudio::model::Model model;
  openstudio::model::Zone zone(model);
  openstudio::model::Lights lights(model);
  lights.addToZone(zone);

  ForwardTranslator forwardTranslator(model);
  OptionalWorkspace outWorkspace = forwardTranslator.convert();
  ASSERT_TRUE(outWorkspace);
  ASSERT_EQ(static_cast<unsigned>(1), outWorkspace->getObjectsByType(IddObjectType::Zone).size());
  Handle zoneHandle = outWorkspace->getObjectsByType(IddObjectType::Zone)[0].handle();
  ASSERT_EQ(static_cast<unsigned>(1), outWorkspace->getObjectsByType(IddObjectType::Lights).size());
  WorkspaceObject lightsObject = outWorkspace->getObjectsByType(IddObjectType::Lights)[0];
  ASSERT_TRUE(lightsObject.getTarget(openstudio::LightsFields::ZoneorZoneListName));
  EXPECT_TRUE(zoneHandle == lightsObject.getTarget(openstudio::LightsFields::ZoneorZoneListName)->handle());
}
*/
TEST_F(EnergyPlusFixture,ForwardTranslator_ExampleModel) {
  Model model = exampleModel();
  EXPECT_TRUE(model.getOptionalUniqueModelObject<Version>()) << "Example model does not include a Version object.";
  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(1u,workspace.getObjectsByType(IddObjectType::Version).size());

  model.save(toPath("./example.osm"), true);
  workspace.save(toPath("./example.idf"), true);
}
Exemple #7
0
TEST_F(EnergyPlusFixture, ForwardTranslatorFuelCell4) {
  //TEST orphaned FC

  Model model;

  Building building = model.getUniqueModelObject<Building>();

  GeneratorFuelCellAirSupply airSupply(model);
  GeneratorFuelCellAuxiliaryHeater auxHeater(model);
  GeneratorFuelCellElectricalStorage elecStorage(model);
  GeneratorFuelCellExhaustGasToWaterHeatExchanger exhaustHX(model);
  GeneratorFuelCellInverter inverter(model);
  GeneratorFuelCellPowerModule powerModule(model);
  //GeneratorFuelCellStackCooler stackCooler(model);
  GeneratorFuelCellWaterSupply waterSupply(model);
  GeneratorFuelSupply fuelSupply(model);
  // create default fuelcell
  GeneratorFuelCell fuelcell(model, powerModule, airSupply, waterSupply, auxHeater, exhaustHX, elecStorage, inverter, fuelSupply);

  // remove the ELCD
  boost::optional<ElectricLoadCenterDistribution> elcd = fuelcell.electricLoadCenterDistribution();
  elcd.get().remove();
  EXPECT_FALSE(fuelcell.electricLoadCenterDistribution());

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(1u, forwardTranslator.warnings().size());

  //NO FC components should FT now since it is orphaned
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::ElectricLoadCenter_Generators).size());
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::ElectricLoadCenter_Distribution).size());
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell).size());
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_AirSupply).size());
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_AuxiliaryHeater).size());
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_ElectricalStorage).size());
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_ExhaustGasToWaterHeatExchanger).size());
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_Inverter).size());
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_PowerModule).size());
  //expect stack cooler
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_StackCooler).size());
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_WaterSupply).size());
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::Generator_FuelSupply).size());
  //no water mains expected
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::Site_WaterMainsTemperature).size());


  model.save(toPath("./fuelcell4.osm"), true);
  workspace.save(toPath("./fuelcell4.idf"), true);
}
Exemple #8
0
TEST_F(EnergyPlusFixture, ForwardTranslatorFuelCell3) {

  Model model;

  Building building = model.getUniqueModelObject<Building>();

  GeneratorFuelCellAirSupply airSupply(model);
  GeneratorFuelCellAuxiliaryHeater auxHeater(model);
  GeneratorFuelCellElectricalStorage elecStorage(model);
  GeneratorFuelCellExhaustGasToWaterHeatExchanger exhaustHX(model);
  GeneratorFuelCellInverter inverter(model);
  GeneratorFuelCellPowerModule powerModule(model);
  GeneratorFuelCellStackCooler stackCooler(model);
  GeneratorFuelCellWaterSupply waterSupply(model);
  GeneratorFuelSupply fuelSupply(model);
  // create default fuelcell
  GeneratorFuelCell fuelcell(model, powerModule, airSupply, waterSupply, auxHeater, exhaustHX, elecStorage, inverter, fuelSupply);

  // Create an ELCD
  ElectricLoadCenterDistribution elcd = ElectricLoadCenterDistribution(model);
  elcd.setName("fuelcell ELCD");
  elcd.setElectricalBussType("AlternatingCurrent");
  elcd.addGenerator(fuelcell);

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);

  EXPECT_EQ(0u, forwardTranslator.errors().size());

  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::ElectricLoadCenter_Generators).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::ElectricLoadCenter_Distribution).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_AirSupply).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_AuxiliaryHeater).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_ElectricalStorage).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_ExhaustGasToWaterHeatExchanger).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_Inverter).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_PowerModule).size());
  //expect stack cooler
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_StackCooler).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_WaterSupply).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelSupply).size());
  //no water mains expected
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::Site_WaterMainsTemperature).size());


  model.save(toPath("./fuelcell3.osm"), true);
  workspace.save(toPath("./fuelcell3.idf"), true);
}
//test orphaning the generator before FT
TEST_F(EnergyPlusFixture, ForwardTranslatorGeneratorMicroTurbine_ELCD_Orphan)
{
  // Create a model, a mchp, a mchpHR, a plantLoop and an electricalLoadCenter
  Model model;

  GeneratorMicroTurbine mchp = GeneratorMicroTurbine(model);
  GeneratorMicroTurbineHeatRecovery mchpHR = GeneratorMicroTurbineHeatRecovery(model, mchp);
  ASSERT_EQ(mchpHR, mchp.generatorMicroTurbineHeatRecovery().get());

  PlantLoop plantLoop(model);
  // Add a supply branch for the mchpHR
  ASSERT_TRUE(plantLoop.addSupplyBranchForComponent(mchpHR));

  // Create a WaterHeater:Mixed
  WaterHeaterMixed waterHeater(model);
  // Add it on the same branch as the chpHR, right after it
  Node mchpHROutletNode = mchpHR.outletModelObject()->cast<Node>();
  ASSERT_TRUE(waterHeater.addToNode(mchpHROutletNode));

  // Create a plantEquipmentOperationHeatingLoad
  PlantEquipmentOperationHeatingLoad operation(model);
  operation.setName(plantLoop.name().get() + " PlantEquipmentOperationHeatingLoad");
  ASSERT_TRUE(plantLoop.setPlantEquipmentOperationHeatingLoad(operation));
  ASSERT_TRUE(operation.addEquipment(mchpHR));
  ASSERT_TRUE(operation.addEquipment(waterHeater));

  // Create an ELCD
  ElectricLoadCenterDistribution elcd = ElectricLoadCenterDistribution(model);
  elcd.setName("Capstone C65 ELCD");
  elcd.setElectricalBussType("AlternatingCurrent");
  elcd.addGenerator(mchp);

  // orphan the generator from the ELCD
  boost::optional<ElectricLoadCenterDistribution> elcd2 = mchp.electricLoadCenterDistribution();
  elcd2.get().remove();
  EXPECT_FALSE(mchp.electricLoadCenterDistribution());

  // Forward Translates
  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);

  EXPECT_EQ(0u, forwardTranslator.errors().size());
  //ASSERT_EQ(1u, workspace.getObjectsByType(IddObjectType::WaterHeater_Mixed).size());
  ASSERT_EQ(0u, workspace.getObjectsByType(IddObjectType::ElectricLoadCenter_Distribution).size());

  //model.save(toPath("./ForwardTranslatorGeneratorMicroTurbine_ELCD_orhpan.osm"), true);
  //workspace.save(toPath("./ForwardTranslatorGeneratorMicroTurbine_ELCD_orphan.idf"), true);

}
TEST_F(EnergyPlusFixture,ForwardTranslator_SpaceInfiltrationEffectiveLeakageArea_NoSpace)
{
  Model model;
  SpaceInfiltrationEffectiveLeakageArea infiltration(model);

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(0u, forwardTranslator.warnings().size());

  ASSERT_EQ(1u, workspace.getObjectsByType(IddObjectType::ZoneInfiltration_EffectiveLeakageArea).size());

  WorkspaceObject object = workspace.getObjectsByType(IddObjectType::ZoneInfiltration_EffectiveLeakageArea)[0];
  EXPECT_TRUE(object.isEmpty(ZoneInfiltration_EffectiveLeakageAreaFields::ZoneName));
}
TEST_F(EnergyPlusFixture,ForwardTranslator_Surface_DefaultConstruction)
{
  Model model;

  Construction construction(model);

  DefaultSurfaceConstructions defaultSurfaceConstructions(model);
  defaultSurfaceConstructions.setRoofCeilingConstruction(construction);

  DefaultConstructionSet defaultConstructionSet(model);
  defaultConstructionSet.setDefaultExteriorSurfaceConstructions(defaultSurfaceConstructions);

  Building building = model.getUniqueModelObject<Building>();
  building.setDefaultConstructionSet(defaultConstructionSet);

  Space space(model);
  ThermalZone zone(model);
  EXPECT_TRUE(space.setThermalZone(zone));  

  Point3dVector points;
  points.push_back(Point3d(0, 1, 0));
  points.push_back(Point3d(0, 0, 0));
  points.push_back(Point3d(1, 0, 0));
  points.push_back(Point3d(1, 1, 0));
  Surface surface(points, model);
  surface.setSpace(space);

  EXPECT_EQ("RoofCeiling", surface.surfaceType());
  EXPECT_EQ("Outdoors", surface.outsideBoundaryCondition());
  EXPECT_FALSE(surface.adjacentSurface());
  ASSERT_TRUE(surface.construction());
  EXPECT_TRUE(surface.isConstructionDefaulted());
  EXPECT_EQ(construction.handle(), surface.construction()->handle());

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(0u, forwardTranslator.warnings().size());

  ASSERT_EQ(1u, workspace.getObjectsByType(IddObjectType::BuildingSurface_Detailed).size());
  ASSERT_EQ(1u, workspace.getObjectsByType(IddObjectType::Construction).size());

  WorkspaceObject surfaceObject = workspace.getObjectsByType(IddObjectType::BuildingSurface_Detailed)[0];
  WorkspaceObject constructionObject = workspace.getObjectsByType(IddObjectType::Construction)[0];

  ASSERT_TRUE(surfaceObject.getTarget(BuildingSurface_DetailedFields::ConstructionName));
  EXPECT_EQ(constructionObject.handle(), surfaceObject.getTarget(BuildingSurface_DetailedFields::ConstructionName)->handle());
}
TEST_F(EnergyPlusFixture,ForwardTranslatorCentralHeatPumpSystem_NoModules) {

  boost::optional<WorkspaceObject> _wo;
  ForwardTranslator ft;

  Model m;

  CentralHeatPumpSystem central_hp(m);

  // DO NOT Add a Module
  EXPECT_EQ(0u, central_hp.modules().size());

  // Connect the CentralHP to three plant loops
  // CoolingLoop: on the supply side
  PlantLoop coolingPlant(m);
  EXPECT_TRUE(coolingPlant.addSupplyBranchForComponent(central_hp));

  // SourceLoop: on the demand side
  PlantLoop sourcePlant(m);
  EXPECT_TRUE(sourcePlant.addDemandBranchForComponent(central_hp));
  // Also add a CT to the sourcePlant
  CoolingTowerSingleSpeed ct(m);
  sourcePlant.addSupplyBranchForComponent(ct);

   // HeatingLoop: on the supply side
  PlantLoop heatingPlant(m);
  // Workaround to be able to use addToTertiaryNode directly
  // (addSupplyBranchForComponent should work directly, but this is tested in model GTest, so here we just make sure we call
  // addToTertiaryNode directly)
  BoilerHotWater temp_b(m);
  EXPECT_TRUE(heatingPlant.addSupplyBranchForComponent(temp_b));

  ASSERT_TRUE(temp_b.inletModelObject());
  auto node = temp_b.inletModelObject().get().cast<Node>();
  EXPECT_TRUE(central_hp.addToTertiaryNode(node));
  temp_b.remove();
  EXPECT_TRUE(central_hp.coolingPlantLoop());
  EXPECT_TRUE(central_hp.sourcePlantLoop());
  EXPECT_TRUE(central_hp.heatingPlantLoop());

  Workspace w = ft.translateModel(m);

  EXPECT_EQ(0u, ft.errors().size());
  EXPECT_EQ(0u, w.getObjectsByType(IddObjectType::CentralHeatPumpSystem).size());

}
/*
 * The Forward Translator should throw if the AVM is missing the required Sensor Node (E+ crash on 8.8.0)
 */
TEST_F(EnergyPlusFixture, ForwardTranslator_AvailabilityManagerLowTemperatureTurnOff_NoSensorNode) {

  Model m;

  AvailabilityManagerLowTemperatureTurnOff avm(m);
  // No Sensor Node
  ASSERT_FALSE(avm.sensorNode());

  // Assign it to a plant loop (otherwise it's purely not translated anyways...)
  PlantLoop p(m);
  p.setAvailabilityManager(avm);

  // ForwardTranslate
  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(m);

  EXPECT_EQ(1u, forwardTranslator.errors().size());
}
TEST_F(EnergyPlusFixture,ForwardTranslator_Surface)
{
  Model model;
  
  Point3dVector points;
  points.push_back(Point3d(0, 1, 0));
  points.push_back(Point3d(0, 0, 0));
  points.push_back(Point3d(1, 0, 0));
  points.push_back(Point3d(1, 1, 0));
  Surface surface(points, model);

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(0u, forwardTranslator.warnings().size());

  ASSERT_EQ(1u, workspace.getObjectsByType(IddObjectType::BuildingSurface_Detailed).size());
}
TEST_F(EnergyPlusFixture, ForwardTranslator_ExternalInterfaceFunctionalMockupUnitImportToActuator) {
  Model model;

  Building building = model.getUniqueModelObject<Building>();

  // add fan
  Schedule s = model.alwaysOnDiscreteSchedule();
  FanConstantVolume fan(model, s);

  // add FMU
  ExternalInterfaceFunctionalMockupUnitImport eifmui(model, "test name");

  // add actuator
  std::string fanControlType = "Fan Pressure Rise";
  std::string ComponentType = "Fan";
  ExternalInterfaceFunctionalMockupUnitImportToActuator fanActuator(fan, ComponentType, fanControlType, eifmui, "FMU", "Fan FMU name", 10);

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::ExternalInterface_FunctionalMockupUnitImport_To_Actuator).size());

  WorkspaceObject object = workspace.getObjectsByType(IddObjectType::ExternalInterface_FunctionalMockupUnitImport_To_Actuator)[0];

  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ActuatorFields::Name, false));
  EXPECT_EQ("External Interface Functional Mockup Unit Import To Actuator 1", object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ActuatorFields::Name, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ActuatorFields::ActuatedComponentUniqueName, false));
  EXPECT_EQ(fan.nameString(), object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ActuatorFields::ActuatedComponentUniqueName, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ActuatorFields::ActuatedComponentType, false));
  EXPECT_EQ(ComponentType, object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ActuatorFields::ActuatedComponentType, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ActuatorFields::ActuatedComponentControlType, false));
  EXPECT_EQ(fanControlType, object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ActuatorFields::ActuatedComponentControlType, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ActuatorFields::FMUFileName, false));
  EXPECT_EQ(eifmui.fMUFileName(), object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ActuatorFields::FMUFileName, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ActuatorFields::FMUVariableName, false));
  EXPECT_EQ("Fan FMU name", object.getString(ExternalInterface_FunctionalMockupUnitImport_To_ActuatorFields::FMUVariableName, false).get());
  ASSERT_TRUE(object.getDouble(ExternalInterface_FunctionalMockupUnitImport_To_ActuatorFields::InitialValue, false));
  EXPECT_EQ(10.0, object.getDouble(ExternalInterface_FunctionalMockupUnitImport_To_ActuatorFields::InitialValue, false).get());

  model.save(toPath("./ExternalInterfaceFunctionalMockupUnitImportToActuator.osm"), true);
  workspace.save(toPath("./ExternalInterfaceFunctionalMockupUnitImportToActuator.idf"), true);
}
TEST_F(EnergyPlusFixture, ForwardTranslator_ExternalInterface) {
  Model model;

  ExternalInterface externalinterface = model.getUniqueModelObject<ExternalInterface>();
  EXPECT_EQ("PtolemyServer", externalinterface.nameofExternalInterface());
  EXPECT_TRUE(externalinterface.setNameofExternalInterface("FunctionalMockupUnitImport"));

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::ExternalInterface).size());

  WorkspaceObject object = workspace.getObjectsByType(IddObjectType::ExternalInterface)[0];

  ASSERT_TRUE(object.getString(ExternalInterfaceFields::NameofExternalInterface, false));
  EXPECT_EQ("FunctionalMockupUnitImport", object.getString(ExternalInterfaceFields::NameofExternalInterface, false).get());

  model.save(toPath("./ExternalInterface.osm"), true);
  workspace.save(toPath("./ExternalInterface.idf"), true);
}
TEST_F(EnergyPlusFixture, ForwardTranslator_ExternalInterfaceVariable) {

  Model model;
  ExternalInterfaceVariable variable(model, "test name", 10);

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::ExternalInterface_Variable).size());

  WorkspaceObject object = workspace.getObjectsByType(IddObjectType::ExternalInterface_Variable)[0];

  ASSERT_TRUE(object.getString(ExternalInterface_VariableFields::Name, false));
  EXPECT_EQ("test name", object.getString(ExternalInterface_VariableFields::Name, false).get());
  ASSERT_TRUE(object.getDouble(ExternalInterface_VariableFields::InitialValue, false));
  EXPECT_EQ(10.0, object.getDouble(ExternalInterface_VariableFields::InitialValue, false).get());

  model.save(toPath("./ExternalInterfaceVariable.osm"), true);
  workspace.save(toPath("./ExternalInterfaceVariable.idf"), true);
}
TEST_F(EnergyPlusFixture, ForwardTranslator_ExternalInterfaceFunctionalMockupUnitImport) {

  Model model;

  ExternalInterfaceFunctionalMockupUnitImport eifmui(model, "c:\\Program Files\\Test\\blah.fmu");

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::ExternalInterface_FunctionalMockupUnitImport).size());

  WorkspaceObject object = workspace.getObjectsByType(IddObjectType::ExternalInterface_FunctionalMockupUnitImport)[0];

  ASSERT_TRUE(object.getString(ExternalInterface_FunctionalMockupUnitImportFields::FMUFileName, false));
  EXPECT_EQ("c:\\Program Files\\Test\\blah.fmu", object.getString(ExternalInterface_FunctionalMockupUnitImportFields::FMUFileName, false).get());
  ASSERT_TRUE(object.getDouble(ExternalInterface_FunctionalMockupUnitImportFields::FMUTimeout, false));
  EXPECT_EQ(0, object.getDouble(ExternalInterface_FunctionalMockupUnitImportFields::FMUTimeout, false).get());
  ASSERT_TRUE(object.getDouble(ExternalInterface_FunctionalMockupUnitImportFields::FMULoggingOn, false));
  EXPECT_EQ(0, object.getDouble(ExternalInterface_FunctionalMockupUnitImportFields::FMULoggingOn, false).get());

  model.save(toPath("./ExternalInterfaceFunctionalMockupUnitImport.osm"), true);
  workspace.save(toPath("./ExternalInterfaceFunctionalMockupUnitImport.idf"), true);
}
TEST_F(EnergyPlusFixture, ForwardTranslator_ExternalInterfaceActuator) {
  Model model;

  Building building = model.getUniqueModelObject<Building>();

  // add fan
  Schedule s = model.alwaysOnDiscreteSchedule();
  FanConstantVolume fan(model, s);

  // add actuator
  std::string fanControlType = "Fan Pressure Rise";
  std::string ComponentType = "Fan";
  ExternalInterfaceActuator fanActuator(fan, ComponentType, fanControlType);

  std::string fanName = fan.name().get() + "Press Actuator";
  fanActuator.setName(fanName);
  fanActuator.setOptionalInitialValue(1);

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);
  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::ExternalInterface_Actuator).size());

  WorkspaceObject object = workspace.getObjectsByType(IddObjectType::ExternalInterface_Actuator)[0];

  ASSERT_TRUE(object.getString(ExternalInterface_ActuatorFields::ActuatedComponentUniqueName, false));
  EXPECT_EQ(fan.nameString(), object.getString(ExternalInterface_ActuatorFields::ActuatedComponentUniqueName, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_ActuatorFields::ActuatedComponentType, false));
  EXPECT_EQ(ComponentType, object.getString(ExternalInterface_ActuatorFields::ActuatedComponentType, false).get());
  ASSERT_TRUE(object.getString(ExternalInterface_ActuatorFields::ActuatedComponentControlType, false));
  EXPECT_EQ(fanControlType, object.getString(ExternalInterface_ActuatorFields::ActuatedComponentControlType, false).get());
  ASSERT_TRUE(object.getDouble(ExternalInterface_ActuatorFields::OptionalInitialValue, false));
  EXPECT_EQ(1.0, object.getDouble(ExternalInterface_ActuatorFields::OptionalInitialValue, false).get());

  model.save(toPath("./ExternalInterfaceActuator.osm"), true);
  workspace.save(toPath("./ExternalInterfaceActuator.idf"), true);
}
/* This tests ensures that the CentralHeatPumpSystem ends up in a PlantEquipmentOperation:HeatingLoad for the heating loop
 * and PlantEquipmentOperation:CoolingLoad for the cooling loop. For the source loop, it's on the demand side so it shouldn't
 * be part of the plant equipment list used
 */
TEST_F(EnergyPlusFixture,ForwardTranslatorCentralHeatPumpSystem_PlantEquipmentOperation) {

  boost::optional<WorkspaceObject> _wo;
  ForwardTranslator ft;

  Model m;

  CentralHeatPumpSystem central_hp(m);

  // Add a Module
  CentralHeatPumpSystemModule central_hp_module(m);
  central_hp.addModule(central_hp_module);
  EXPECT_EQ(1, central_hp_module.numberofChillerHeaterModules());

  // Connect the CentralHP to three plant loops
  // CoolingLoop: on the supply side
  PlantLoop coolingPlant(m);
  EXPECT_TRUE(coolingPlant.addSupplyBranchForComponent(central_hp));

  // SourceLoop: on the demand side
  PlantLoop sourcePlant(m);
  EXPECT_TRUE(sourcePlant.addDemandBranchForComponent(central_hp));
  // Also add a CT to the sourcePlant
  CoolingTowerSingleSpeed ct(m);
  sourcePlant.addSupplyBranchForComponent(ct);

  // HeatingLoop: on the supply side
  PlantLoop heatingPlant(m);
  // Workaround to be able to use addToTertiaryNode directly
  // (addSupplyBranchForComponent should work directly, but this is tested in model GTest, so here we just make sure we call
  // addToTertiaryNode directly)
  BoilerHotWater temp_b(m);
  EXPECT_TRUE(heatingPlant.addSupplyBranchForComponent(temp_b));

  ASSERT_TRUE(temp_b.inletModelObject());
  auto node = temp_b.inletModelObject().get().cast<Node>();
  EXPECT_TRUE(central_hp.addToTertiaryNode(node));
  temp_b.remove();



  Workspace w = ft.translateModel(m);

  EXPECT_EQ(0u, ft.errors().size());
  EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::CentralHeatPumpSystem).size());

  IdfObject i_central_hp = w.getObjectsByType(IddObjectType::CentralHeatPumpSystem)[0];



  // Get the Loops, and find their plant operation scheme

  // supply = Cooling
  {
    _wo = w.getObjectByTypeAndName(IddObjectType::PlantLoop, coolingPlant.name().get());
    ASSERT_TRUE(_wo.is_initialized());
    WorkspaceObject idf_coolingPlant = _wo.get();
    WorkspaceObject idf_plant_op = idf_coolingPlant.getTarget(PlantLoopFields::PlantEquipmentOperationSchemeName).get();

    // Should have created a Cooling Load one only
    ASSERT_EQ(1u, idf_plant_op.extensibleGroups().size());
    WorkspaceExtensibleGroup w_eg = idf_plant_op.extensibleGroups()[0].cast<WorkspaceExtensibleGroup>();
    ASSERT_EQ("PlantEquipmentOperation:CoolingLoad", w_eg.getString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeObjectType).get());

    // Get the Operation Scheme
    _wo = w_eg.getTarget(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeName);
    ASSERT_TRUE(_wo.is_initialized());
    WorkspaceObject idf_op_scheme = _wo.get();

    // Get the Plant Equipment List of this CoolingLoad scheme
    // There should only be one Load Range
    ASSERT_EQ(1u, idf_op_scheme.extensibleGroups().size());
    // Load range 1
    w_eg = idf_op_scheme.extensibleGroups()[0].cast<WorkspaceExtensibleGroup>();
    _wo = w_eg.getTarget(PlantEquipmentOperation_CoolingLoadExtensibleFields::RangeEquipmentListName);
    ASSERT_TRUE(_wo.is_initialized());
    WorkspaceObject idf_peq_list = _wo.get();

    // Should have one equipment on it: CentralHeatPumpSystem
    ASSERT_EQ(1u, idf_peq_list.extensibleGroups().size());
    IdfExtensibleGroup idf_eg(idf_peq_list.extensibleGroups()[0]);
    ASSERT_EQ(central_hp.name().get(), idf_eg.getString(PlantEquipmentListExtensibleFields::EquipmentName).get());

  }


  // tertiary = Heating
  {
    _wo = w.getObjectByTypeAndName(IddObjectType::PlantLoop, heatingPlant.name().get());
    ASSERT_TRUE(_wo.is_initialized());
    WorkspaceObject idf_heatingPlant = _wo.get();
    WorkspaceObject idf_plant_op = idf_heatingPlant.getTarget(PlantLoopFields::PlantEquipmentOperationSchemeName).get();

    // Should have created a Heating Load one only
    ASSERT_EQ(1u, idf_plant_op.extensibleGroups().size());
    WorkspaceExtensibleGroup w_eg = idf_plant_op.extensibleGroups()[0].cast<WorkspaceExtensibleGroup>();
    ASSERT_EQ("PlantEquipmentOperation:HeatingLoad", w_eg.getString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeObjectType).get());

    // Get the Operation Scheme
    _wo = w_eg.getTarget(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeName);
    ASSERT_TRUE(_wo.is_initialized());
    WorkspaceObject idf_op_scheme = _wo.get();

    // Get the Plant Equipment List of this HeatingLoad scheme
    // There should only be one Load Range
    ASSERT_EQ(1u, idf_op_scheme.extensibleGroups().size());
    // Load range 1
    w_eg = idf_op_scheme.extensibleGroups()[0].cast<WorkspaceExtensibleGroup>();
    _wo = w_eg.getTarget(PlantEquipmentOperation_HeatingLoadExtensibleFields::RangeEquipmentListName);
    ASSERT_TRUE(_wo.is_initialized());
    WorkspaceObject idf_peq_list = _wo.get();

    // Should have one equipment on it: CentralHeatPumpSystem
    ASSERT_EQ(1u, idf_peq_list.extensibleGroups().size());
    IdfExtensibleGroup idf_eg(idf_peq_list.extensibleGroups()[0]);
    ASSERT_EQ(central_hp.name().get(), idf_eg.getString(PlantEquipmentListExtensibleFields::EquipmentName).get());

  }



  // SourceLoop: on the demand side. So it shouldn't be on it
  {
    _wo = w.getObjectByTypeAndName(IddObjectType::PlantLoop, sourcePlant.name().get());
    ASSERT_TRUE(_wo.is_initialized());
    WorkspaceObject idf_sourcePlant = _wo.get();
    WorkspaceObject idf_plant_op = idf_sourcePlant.getTarget(PlantLoopFields::PlantEquipmentOperationSchemeName).get();

    // Should have created a Cooling Load one only
    ASSERT_EQ(1u, idf_plant_op.extensibleGroups().size());
    WorkspaceExtensibleGroup w_eg = idf_plant_op.extensibleGroups()[0].cast<WorkspaceExtensibleGroup>();
    ASSERT_EQ("PlantEquipmentOperation:CoolingLoad", w_eg.getString(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeObjectType).get());

    // Get the Operation Scheme
    _wo = w_eg.getTarget(PlantEquipmentOperationSchemesExtensibleFields::ControlSchemeName);
    ASSERT_TRUE(_wo.is_initialized());
    WorkspaceObject idf_op_scheme = _wo.get();

    // Get the Plant Equipment List of this HeatingLoad scheme
    // There should only be one Load Range
    ASSERT_EQ(1u, idf_op_scheme.extensibleGroups().size());
    // Load range 1
    w_eg = idf_op_scheme.extensibleGroups()[0].cast<WorkspaceExtensibleGroup>();
    _wo = w_eg.getTarget(PlantEquipmentOperation_CoolingLoadExtensibleFields::RangeEquipmentListName);
    ASSERT_TRUE(_wo.is_initialized());
    WorkspaceObject idf_peq_list = _wo.get();

    // Should have one equipment on it: Cooling Tower
    ASSERT_EQ(1u, idf_peq_list.extensibleGroups().size());
    IdfExtensibleGroup idf_eg(idf_peq_list.extensibleGroups()[0]);
    ASSERT_EQ(ct.name().get(), idf_eg.getString(PlantEquipmentListExtensibleFields::EquipmentName).get());

  }

  m.save(toPath("./ft_central_hp.osm"), true);
  w.save(toPath("./ft_central_hp.idf"), true);

}
/* Ensures that the nodes that translated correctly
 * that means correct node names in the CentralHeatPumpSystem but also
 * on the Branches
 */
TEST_F(EnergyPlusFixture,ForwardTranslatorCentralHeatPumpSystem_Nodes) {

  boost::optional<WorkspaceObject> _wo;
  ForwardTranslator ft;

  Model m;

  CentralHeatPumpSystem central_hp(m);
  ASSERT_TRUE(central_hp.setAncillaryPower(0.7));
  EXPECT_FALSE(central_hp.ancillaryOperationSchedule());
  Schedule schedule = m.alwaysOnDiscreteSchedule();

  // Return type: bool
  ASSERT_TRUE(central_hp.setAncillaryOperationSchedule(schedule));
  EXPECT_TRUE(central_hp.ancillaryOperationSchedule());

  // First module has one
  CentralHeatPumpSystemModule central_hp_module(m);
  central_hp.addModule(central_hp_module);
  EXPECT_EQ(1, central_hp_module.numberofChillerHeaterModules());

  // Second has 2
  CentralHeatPumpSystemModule central_hp_module2(m);
  central_hp.addModule(central_hp_module2);
  ASSERT_TRUE(central_hp_module2.setNumberofChillerHeaterModules(2));


  ASSERT_EQ( (unsigned)2, central_hp.modules().size() );


  // Connect the CentralHP to three plant loops
  // CoolingLoop: on the supply side
  PlantLoop coolingPlant(m);
  EXPECT_TRUE(coolingPlant.addSupplyBranchForComponent(central_hp));

  // SourceLoop: on the demand side
  PlantLoop sourcePlant(m);
  EXPECT_TRUE(sourcePlant.addDemandBranchForComponent(central_hp));
  // Also add a CT to the sourcePlant
  CoolingTowerSingleSpeed ct(m);
  sourcePlant.addSupplyBranchForComponent(ct);

  // HeatingLoop: on the supply side
  PlantLoop heatingPlant(m);
  // Workaround to be able to use addToTertiaryNode directly
  // (addSupplyBranchForComponent should work directly, but this is tested in model GTest, so here we just make sure we call
  // addToTertiaryNode directly)
  BoilerHotWater temp_b(m);
  EXPECT_TRUE(heatingPlant.addSupplyBranchForComponent(temp_b));

  ASSERT_TRUE(temp_b.inletModelObject());
  auto node = temp_b.inletModelObject().get().cast<Node>();
  EXPECT_TRUE(central_hp.addToTertiaryNode(node));
  temp_b.remove();


  // Translate
  Workspace w = ft.translateModel(m);

  EXPECT_EQ(0u, ft.errors().size());
  EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::CentralHeatPumpSystem).size());

  IdfObject i_central_hp = w.getObjectsByType(IddObjectType::CentralHeatPumpSystem)[0];

  // supply = Cooling
  ASSERT_EQ(i_central_hp.getString(CentralHeatPumpSystemFields::CoolingLoopInletNodeName).get(),
            central_hp.supplyInletModelObject().get().name());

  ASSERT_EQ(i_central_hp.getString(CentralHeatPumpSystemFields::CoolingLoopOutletNodeName).get(),
            central_hp.supplyOutletModelObject().get().name());

  // demand = Source
  ASSERT_EQ(i_central_hp.getString(CentralHeatPumpSystemFields::SourceLoopInletNodeName).get(),
            central_hp.demandInletModelObject().get().name());

  ASSERT_EQ(i_central_hp.getString(CentralHeatPumpSystemFields::SourceLoopOutletNodeName).get(),
            central_hp.demandOutletModelObject().get().name());

  // tertiary = Heating
  ASSERT_EQ(i_central_hp.getString(CentralHeatPumpSystemFields::HeatingLoopInletNodeName).get(),
            central_hp.tertiaryInletModelObject().get().name());

  ASSERT_EQ(i_central_hp.getString(CentralHeatPumpSystemFields::HeatingLoopOutletNodeName).get(),
            central_hp.tertiaryOutletModelObject().get().name());


  // Check node names on supply/demand branches
  // Checks that the special case implemented in ForwardTranslatePlantLoop::populateBranch does the right job

  // supply = Cooling (on supply)
  {
    _wo = w.getObjectByTypeAndName(IddObjectType::PlantLoop, coolingPlant.name().get());
    ASSERT_TRUE(_wo.is_initialized());
    WorkspaceObject idf_plant = _wo.get();
    WorkspaceObject idf_brlist = idf_plant.getTarget(PlantLoopFields::PlantSideBranchListName).get();

    // Should have three branches: supply inlet, the one with the centralHP, supply outlet
    ASSERT_EQ(3u, idf_brlist.extensibleGroups().size());
    // Get the Central HP one
    WorkspaceExtensibleGroup w_eg = idf_brlist.extensibleGroups()[1].cast<WorkspaceExtensibleGroup>();
    WorkspaceObject idf_branch = w_eg.getTarget(BranchListExtensibleFields::BranchName).get();

    // There should be only one equipment on the branch
    ASSERT_EQ(1u, idf_branch.extensibleGroups().size());
    WorkspaceExtensibleGroup w_eg2 = idf_branch.extensibleGroups()[0].cast<WorkspaceExtensibleGroup>();

    ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentName).get(),
        central_hp.name());

    ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentInletNodeName).get(),
        central_hp.supplyInletModelObject().get().name());

    ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentOutletNodeName).get(),
        central_hp.supplyOutletModelObject().get().name());
  }

  // tertiary = Heating (on supply)
  {
    _wo = w.getObjectByTypeAndName(IddObjectType::PlantLoop, heatingPlant.name().get());
    ASSERT_TRUE(_wo.is_initialized());
    WorkspaceObject idf_plant = _wo.get();
    WorkspaceObject idf_brlist = idf_plant.getTarget(PlantLoopFields::PlantSideBranchListName).get();

    // Should have three branches: supply inlet, the one with the centralHP, supply outlet
    ASSERT_EQ(3u, idf_brlist.extensibleGroups().size());
    // Get the Central HP one
    WorkspaceExtensibleGroup w_eg = idf_brlist.extensibleGroups()[1].cast<WorkspaceExtensibleGroup>();
    WorkspaceObject idf_branch = w_eg.getTarget(BranchListExtensibleFields::BranchName).get();

    // There should be only one equipment on the branch
    ASSERT_EQ(1u, idf_branch.extensibleGroups().size());
    WorkspaceExtensibleGroup w_eg2 = idf_branch.extensibleGroups()[0].cast<WorkspaceExtensibleGroup>();

    ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentName).get(),
        central_hp.name());

    ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentInletNodeName).get(),
        central_hp.tertiaryInletModelObject().get().name());

    ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentOutletNodeName).get(),
        central_hp.tertiaryOutletModelObject().get().name());
  }

  // demand = Source (on demand)
  {
    _wo = w.getObjectByTypeAndName(IddObjectType::PlantLoop, sourcePlant.name().get());
    ASSERT_TRUE(_wo.is_initialized());
    WorkspaceObject idf_plant = _wo.get();
    // Demand Side Branch List Name
    WorkspaceObject idf_brlist = idf_plant.getTarget(PlantLoopFields::DemandSideBranchListName).get();

    // Should have four branches: supply inlet, the one with the centralHP, a bypass, supply outlet
    ASSERT_EQ(4u, idf_brlist.extensibleGroups().size());
    // Get the Central HP one, which should be the second one
    WorkspaceExtensibleGroup w_eg = idf_brlist.extensibleGroups()[1].cast<WorkspaceExtensibleGroup>();
    WorkspaceObject idf_branch = w_eg.getTarget(BranchListExtensibleFields::BranchName).get();

    // There should be only one equipment on the branch
    ASSERT_EQ(1u, idf_branch.extensibleGroups().size());
    WorkspaceExtensibleGroup w_eg2 = idf_branch.extensibleGroups()[0].cast<WorkspaceExtensibleGroup>();

    ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentName).get(),
        central_hp.name());

    ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentInletNodeName).get(),
        central_hp.demandInletModelObject().get().name());

    ASSERT_EQ(w_eg2.getString(BranchExtensibleFields::ComponentOutletNodeName).get(),
        central_hp.demandOutletModelObject().get().name());
  }

  // m.save(toPath("./ft_central_hp.osm"), true);
  // w.save(toPath("./ft_central_hp.idf"), true);

}
/**
 * Tests whether the ForwarTranslator will handle the name of the GeneratorMicroTurbine correctly in the PlantEquipmentOperationHeatingLoad
 **/
TEST_F(EnergyPlusFixture,ForwardTranslatorGeneratorMicroTurbine_ELCD_PlantLoop)
{

  // TODO: Temporarily output the Log in the console with the Trace (-3) level
  // for debug
  // openstudio::Logger::instance().standardOutLogger().enable();
  // openstudio::Logger::instance().standardOutLogger().setLogLevel(Trace);


  // Create a model, a mchp, a mchpHR, a plantLoop and an electricalLoadCenter
  Model model;

  GeneratorMicroTurbine mchp = GeneratorMicroTurbine(model);
  GeneratorMicroTurbineHeatRecovery mchpHR = GeneratorMicroTurbineHeatRecovery(model, mchp);
  ASSERT_EQ(mchpHR, mchp.generatorMicroTurbineHeatRecovery().get());

  PlantLoop plantLoop(model);
  // Add a supply branch for the mchpHR
  ASSERT_TRUE(plantLoop.addSupplyBranchForComponent(mchpHR));

  // Create a WaterHeater:Mixed
  WaterHeaterMixed waterHeater(model);
  // Add it on the same branch as the chpHR, right after it
  Node mchpHROutletNode = mchpHR.outletModelObject()->cast<Node>();
  ASSERT_TRUE(waterHeater.addToNode(mchpHROutletNode));

  // Create a plantEquipmentOperationHeatingLoad
  PlantEquipmentOperationHeatingLoad operation(model);
  operation.setName(plantLoop.name().get() + " PlantEquipmentOperationHeatingLoad");
  ASSERT_TRUE(plantLoop.setPlantEquipmentOperationHeatingLoad(operation));
  ASSERT_TRUE(operation.addEquipment(mchpHR));
  ASSERT_TRUE(operation.addEquipment(waterHeater));

  // Create an ELCD
  ElectricLoadCenterDistribution elcd = ElectricLoadCenterDistribution(model);
  elcd.setName("Capstone C65 ELCD");
  elcd.setElectricalBussType("AlternatingCurrent");
  elcd.addGenerator(mchp);

  // Forward Translates
  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);

  EXPECT_EQ(0u, forwardTranslator.errors().size());
  ASSERT_EQ(1u, workspace.getObjectsByType(IddObjectType::WaterHeater_Mixed).size());
  ASSERT_EQ(1u, workspace.getObjectsByType(IddObjectType::ElectricLoadCenter_Distribution).size());
  // The MicroTurbine should have been forward translated since there is an ELCD

  WorkspaceObjectVector microTurbineObjects(workspace.getObjectsByType(IddObjectType::Generator_MicroTurbine));
  EXPECT_EQ(1u, microTurbineObjects.size());
  // Check that the HR nodes have been set
  WorkspaceObject idf_mchp(microTurbineObjects[0]);
  EXPECT_EQ(mchpHR.inletModelObject()->name().get(), idf_mchp.getString(Generator_MicroTurbineFields::HeatRecoveryWaterInletNodeName).get());
  EXPECT_EQ(mchpHR.outletModelObject()->name().get(), idf_mchp.getString(Generator_MicroTurbineFields::HeatRecoveryWaterOutletNodeName).get());

  OptionalWorkspaceObject idf_operation(workspace.getObjectByTypeAndName(IddObjectType::PlantEquipmentOperation_HeatingLoad,*(operation.name())));
  ASSERT_TRUE(idf_operation);
  // Get the extensible
  ASSERT_EQ(1u, idf_operation->numExtensibleGroups());
  // IdfExtensibleGroup eg = idf_operation.getExtensibleGroup(0);
   // idf_operation.targets[0]
  ASSERT_EQ(1u, idf_operation->targets().size());
  WorkspaceObject plantEquipmentList(idf_operation->targets()[0]);
  ASSERT_EQ(2u, plantEquipmentList.extensibleGroups().size());

  IdfExtensibleGroup eg(plantEquipmentList.extensibleGroups()[0]);
  ASSERT_EQ("Generator:MicroTurbine", eg.getString(PlantEquipmentListExtensibleFields::EquipmentObjectType).get());
  // This fails
  EXPECT_EQ(mchp.name().get(), eg.getString(PlantEquipmentListExtensibleFields::EquipmentName).get());

  IdfExtensibleGroup eg2(plantEquipmentList.extensibleGroups()[1]);
  ASSERT_EQ("WaterHeater:Mixed", eg2.getString(PlantEquipmentListExtensibleFields::EquipmentObjectType).get());
  EXPECT_EQ(waterHeater.name().get(), eg2.getString(PlantEquipmentListExtensibleFields::EquipmentName).get());

  model.save(toPath("./ForwardTranslatorGeneratorMicroTurbine_ELCD_PlantLoop.osm"), true);
  workspace.save(toPath("./ForwardTranslatorGeneratorMicroTurbine_ELCD_PlantLoop.idf"), true);

}
Exemple #23
0
TEST_F(EnergyPlusFixture,ForwardTranslatorFuelCell) {

  Model model;

  Building building = model.getUniqueModelObject<Building>();

  //ThermalZone zone1(model);
  //ThermalZone zone2(model);

  // create default fuelcell
  GeneratorFuelCell fuelcell(model);
  // get default power module
  GeneratorFuelCellPowerModule fCPM = fuelcell.powerModule();
  // check default power module curve values
  Curve curve = fCPM.efficiencyCurve();
  CurveQuadratic curveQ = curve.cast<CurveQuadratic>();
  EXPECT_EQ(0.642388, curveQ.coefficient1Constant());
  EXPECT_EQ(-0.0001619, curveQ.coefficient2x());
  EXPECT_EQ(2.26e-008, curveQ.coefficient3xPOW2());
  EXPECT_EQ("Annex42", fCPM.efficiencyCurveMode());


  // check default Airsupply
  GeneratorFuelCellAirSupply fAS = fuelcell.airSupply();
  EXPECT_EQ("AirRatiobyStoics", fAS.airSupplyRateCalculationMode());
  EXPECT_EQ(1.0, fAS.stoichiometricRatio());
  EXPECT_EQ("NoRecovery", fAS.airIntakeHeatRecoveryMode());
  EXPECT_EQ("AmbientAir", fAS.airSupplyConstituentMode());

  // check default fuel supply
  GeneratorFuelSupply fS = fuelcell.fuelSupply();

  // check default water supply
  GeneratorFuelCellWaterSupply fWS = fuelcell.waterSupply();
  fWS.setWaterTemperatureModelingMode("MainsWaterTemperature");

  // check default aux heater
  GeneratorFuelCellAuxiliaryHeater fAX = fuelcell.auxiliaryHeater();

  // check default heat exchanger
  GeneratorFuelCellExhaustGasToWaterHeatExchanger fHX = fuelcell.heatExchanger();

  // check default electric storage
  GeneratorFuelCellElectricalStorage fES = fuelcell.electricalStorage();

  // check default inverter
  GeneratorFuelCellInverter fI = fuelcell.inverter();

  // check default optional stackcooler
  boost::optional<GeneratorFuelCellStackCooler> fSC = fuelcell.stackCooler();
  EXPECT_FALSE(fSC);

  ForwardTranslator forwardTranslator;
  Workspace workspace = forwardTranslator.translateModel(model);

  EXPECT_EQ(0u, forwardTranslator.errors().size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_AirSupply).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_AuxiliaryHeater).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_ElectricalStorage).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_ExhaustGasToWaterHeatExchanger).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_Inverter).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_PowerModule).size());
  // no stack cooler by default
  EXPECT_EQ(0u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_StackCooler).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelCell_WaterSupply).size());
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Generator_FuelSupply).size());
  //expect site water mains
  EXPECT_EQ(1u, workspace.getObjectsByType(IddObjectType::Site_WaterMainsTemperature).size());

  model.save(toPath("./fuelcell.osm"), true);
  workspace.save(toPath("./fuelcell.idf"), true);
}