Cross-platform collection of software tools to support whole building energy modeling using EnergyPlus and advanced daylight analysis using Radiance
—
Translation between OpenStudio models and EnergyPlus IDF format for building energy simulation. This module provides bidirectional conversion capabilities, enabling OpenStudio models to be simulated with EnergyPlus and EnergyPlus IDF files to be imported into OpenStudio.
Converts OpenStudio Model objects to EnergyPlus IDF format for simulation.
/**
* Converts OpenStudio Model to EnergyPlus IDF format
* Handles complete model translation with geometry, HVAC, and controls
*/
class ForwardTranslator {
public:
// Constructor
ForwardTranslator();
// Main translation methods
Workspace translateModel(const Model& model);
boost::optional<IdfObject> translateModelObject(const ModelObject& modelObject);
// Translation options
bool excludeUnusedObjects() const;
void setExcludeUnusedObjects(bool excludeUnusedObjects);
bool excludeLCCObjects() const;
void setExcludeLCCObjects(bool excludeLCCObjects);
bool keepRunControlSpecialDays() const;
void setKeepRunControlSpecialDays(bool keepRunControlSpecialDays);
// Error and warning handling
std::vector<LogMessage> errors() const;
std::vector<LogMessage> warnings() const;
std::vector<LogMessage> untranslatedIdfObjects() const;
// Translation utilities
boost::optional<EnergyPlusData> energyPlusData() const;
void setEnergyPlusData(const EnergyPlusData& energyPlusData);
};Usage Examples:
#include <openstudio/model/Model.hpp>
#include <openstudio/energyplus/ForwardTranslator.hpp>
#include <openstudio/utilities/idf/Workspace.hpp>
using namespace openstudio;
using namespace openstudio::model;
using namespace openstudio::energyplus;
// Create and configure model
Model model;
Building building = model.getUniqueModelObject<Building>();
building.setName("Office Building");
// Create thermal zone with surfaces
ThermalZone zone(model);
Space space(model);
space.setThermalZone(zone);
// Set up forward translator
ForwardTranslator ft;
ft.setExcludeUnusedObjects(true);
// Translate to EnergyPlus
Workspace workspace = ft.translateModel(model);
// Check for translation issues
std::vector<LogMessage> errors = ft.errors();
std::vector<LogMessage> warnings = ft.warnings();
if (!errors.empty()) {
for (const auto& error : errors) {
std::cout << "Error: " << error.logMessage() << std::endl;
}
} else {
// Save IDF file
workspace.save(Path("building.idf"), true);
}Converts EnergyPlus IDF files back to OpenStudio Model format.
/**
* Converts EnergyPlus IDF to OpenStudio Model format
* Reconstructs object relationships and hierarchy from flat IDF structure
*/
class ReverseTranslator {
public:
// Constructor
ReverseTranslator();
// Main translation methods
boost::optional<Model> translateWorkspace(const Workspace& workspace);
boost::optional<ModelObject> translateWorkspaceObject(const WorkspaceObject& workspaceObject,
Model& model);
// Translation options
bool keepRunControlSpecialDays() const;
void setKeepRunControlSpecialDays(bool keepRunControlSpecialDays);
// Error and warning handling
std::vector<LogMessage> errors() const;
std::vector<LogMessage> warnings() const;
std::vector<LogMessage> untranslatedIdfObjects() const;
// Progress tracking
void setProgressBar(ProgressBar* progressBar);
};Usage Examples:
#include <openstudio/utilities/idf/Workspace.hpp>
#include <openstudio/energyplus/ReverseTranslator.hpp>
using namespace openstudio;
using namespace openstudio::energyplus;
// Load EnergyPlus IDF file
boost::optional<Workspace> workspace = Workspace::load(Path("existing_building.idf"));
if (workspace) {
// Set up reverse translator
ReverseTranslator rt;
// Translate to OpenStudio model
boost::optional<Model> model = rt.translateWorkspace(*workspace);
if (model) {
// Check translation results
std::vector<LogMessage> warnings = rt.warnings();
for (const auto& warning : warnings) {
std::cout << "Warning: " << warning.logMessage() << std::endl;
}
// Save as OpenStudio model
model->save(Path("converted_building.osm"), true);
// Access translated objects
std::vector<ThermalZone> zones = model->getConcreteModelObjects<ThermalZone>();
std::cout << "Translated " << zones.size() << " thermal zones" << std::endl;
}
}Specialized handling for geometric data conversion between coordinate systems.
/**
* Handles geometric data translation and coordinate system conversions
*/
class GeometryTranslator {
public:
// Surface coordinate conversion
static std::vector<Point3d> convertVertices(const std::vector<Point3d>& vertices);
// Zone geometry processing
static boost::optional<double> calculateZoneVolume(const std::vector<Surface>& surfaces);
static boost::optional<double> calculateZoneFloorArea(const std::vector<Surface>& surfaces);
// Shading calculations
static std::vector<ShadingSurface> calculateBuildingShading(const Model& model);
// Geometry validation
static bool validateSurfaceGeometry(const Surface& surface);
static bool validateZoneGeometry(const ThermalZone& zone);
// Coordinate system transformations
static Transformation buildingTransformation(const Building& building);
static std::vector<Point3d> applyBuildingTransformation(const std::vector<Point3d>& vertices,
const Building& building);
};Helper functions and data structures for translation operations.
/**
* Translation mapping and utilities
*/
namespace TranslationUtils {
// Object type mappings
std::string mapModelObjectType(IddObjectType modelObjectType);
boost::optional<IddObjectType> mapIdfObjectType(IddObjectType idfObjectType);
// Field mapping utilities
boost::optional<unsigned> mapModelField(IddObjectType modelType,
unsigned modelFieldIndex,
IddObjectType idfType);
// Schedule translation helpers
boost::optional<IdfObject> translateSchedule(const Schedule& schedule);
boost::optional<Schedule> reverseTranslateSchedule(const WorkspaceObject& idfObject,
Model& model);
// Construction translation helpers
boost::optional<IdfObject> translateConstruction(const ConstructionBase& construction);
boost::optional<ConstructionBase> reverseTranslateConstruction(const WorkspaceObject& idfObject,
Model& model);
// Material translation helpers
std::vector<IdfObject> translateMaterials(const Construction& construction);
std::vector<Material> reverseTranslateMaterials(const std::vector<WorkspaceObject>& idfObjects,
Model& model);
}
/**
* EnergyPlus version and data management
*/
class EnergyPlusData {
public:
// Version information
std::string version() const;
void setVersion(const std::string& version);
// IDD access
IddFile iddFile() const;
void setIddFile(const IddFile& iddFile);
// Default objects
std::vector<IdfObject> defaultObjects() const;
void addDefaultObject(const IdfObject& object);
// Translation mappings
std::map<std::string, std::string> objectTypeMap() const;
void addObjectTypeMapping(const std::string& osType, const std::string& epType);
};Specialized translation for HVAC systems and components.
/**
* HVAC system translation utilities
*/
namespace HVACTranslation {
// Air loop translation
std::vector<IdfObject> translateAirLoopHVAC(const AirLoopHVAC& airLoop);
boost::optional<AirLoopHVAC> reverseTranslateAirLoopHVAC(const std::vector<WorkspaceObject>& idfObjects,
Model& model);
// Plant loop translation
std::vector<IdfObject> translatePlantLoop(const PlantLoop& plantLoop);
boost::optional<PlantLoop> reverseTranslatePlantLoop(const std::vector<WorkspaceObject>& idfObjects,
Model& model);
// Zone equipment translation
std::vector<IdfObject> translateZoneHVACEquipment(const ModelObject& zoneEquipment);
std::vector<ModelObject> reverseTranslateZoneHVACEquipment(const std::vector<WorkspaceObject>& idfObjects,
Model& model);
// Component connection utilities
bool connectComponents(ModelObject& sourceComponent,
unsigned sourcePort,
ModelObject& targetComponent,
unsigned targetPort);
// Node management
std::vector<Node> createSystemNodes(const Model& model, unsigned count);
void cleanupUnusedNodes(Model& model);
}Translation of simulation settings and run parameters.
/**
* Simulation control and run parameter translation
*/
namespace SimulationTranslation {
// Simulation control objects
IdfObject translateSimulationControl(const SimulationControl& simControl);
boost::optional<SimulationControl> reverseTranslateSimulationControl(const WorkspaceObject& idfObject,
Model& model);
// Run period translation
std::vector<IdfObject> translateRunPeriods(const Model& model);
std::vector<RunPeriod> reverseTranslateRunPeriods(const std::vector<WorkspaceObject>& idfObjects,
Model& model);
// Sizing parameters
std::vector<IdfObject> translateSizingParameters(const Model& model);
void reverseTranslateSizingParameters(const std::vector<WorkspaceObject>& idfObjects,
Model& model);
// Output requests
std::vector<IdfObject> translateOutputRequests(const Model& model);
void addOutputRequests(Model& model, const std::vector<WorkspaceObject>& idfObjects);
// Weather file handling
boost::optional<IdfObject> translateWeatherFile(const WeatherFile& weatherFile);
boost::optional<WeatherFile> reverseTranslateWeatherFile(const WorkspaceObject& idfObject,
Model& model);
}#include <openstudio/model/Model.hpp>
#include <openstudio/energyplus/ForwardTranslator.hpp>
#include <openstudio/utilities/idf/Workspace.hpp>
using namespace openstudio;
using namespace openstudio::model;
using namespace openstudio::energyplus;
// Load OpenStudio model
boost::optional<Model> model = Model::load(Path("building.osm"));
if (model) {
// Configure forward translator
ForwardTranslator ft;
ft.setExcludeUnusedObjects(true);
ft.setExcludeLCCObjects(false);
// Translate model
Workspace workspace = ft.translateModel(*model);
// Handle translation messages
std::vector<LogMessage> errors = ft.errors();
std::vector<LogMessage> warnings = ft.warnings();
std::cout << "Translation completed with " << warnings.size()
<< " warnings and " << errors.size() << " errors" << std::endl;
if (errors.empty()) {
// Save IDF for simulation
bool success = workspace.save(Path("building.idf"), true);
if (success) {
std::cout << "IDF file saved successfully" << std::endl;
}
} else {
// Log errors for debugging
for (const auto& error : errors) {
std::cout << "Translation Error: " << error.logMessage() << std::endl;
}
}
}#include <openstudio/utilities/idf/Workspace.hpp>
#include <openstudio/energyplus/ReverseTranslator.hpp>
#include <openstudio/energyplus/ForwardTranslator.hpp>
using namespace openstudio;
using namespace openstudio::energyplus;
// Import existing IDF file
boost::optional<Workspace> workspace = Workspace::load(Path("reference_building.idf"));
if (workspace) {
// Convert to OpenStudio model
ReverseTranslator rt;
boost::optional<Model> model = rt.translateWorkspace(*workspace);
if (model) {
// Modify the model
Building building = model->getUniqueModelObject<Building>();
building.setName("Modified Building");
// Change all zone setpoints
std::vector<ThermalZone> zones = model->getConcreteModelObjects<ThermalZone>();
for (auto& zone : zones) {
boost::optional<ThermostatSetpointDualSetpoint> thermostat =
zone.thermostatSetpointDualSetpoint();
if (thermostat) {
// Modify setpoint schedules if needed
}
}
// Translate back to IDF
ForwardTranslator ft;
Workspace modifiedWorkspace = ft.translateModel(*model);
modifiedWorkspace.save(Path("modified_building.idf"), true);
}
}#include <openstudio/energyplus/ForwardTranslator.hpp>
using namespace openstudio;
using namespace openstudio::energyplus;
Model model;
// ... build model ...
ForwardTranslator ft;
Workspace workspace = ft.translateModel(model);
// Comprehensive error checking
std::vector<LogMessage> errors = ft.errors();
std::vector<LogMessage> warnings = ft.warnings();
std::vector<LogMessage> untranslated = ft.untranslatedIdfObjects();
// Log all issues
if (!errors.empty()) {
std::cout << "\nTranslation Errors:" << std::endl;
for (const auto& error : errors) {
std::cout << " " << error.logMessage() << std::endl;
}
}
if (!warnings.empty()) {
std::cout << "\nTranslation Warnings:" << std::endl;
for (const auto& warning : warnings) {
std::cout << " " << warning.logMessage() << std::endl;
}
}
if (!untranslated.empty()) {
std::cout << "\nUntranslated Objects:" << std::endl;
for (const auto& untrans : untranslated) {
std::cout << " " << untrans.logMessage() << std::endl;
}
}
// Only proceed if no critical errors
if (errors.empty()) {
workspace.save(Path("building.idf"), true);
std::cout << "\nTranslation completed successfully!" << std::endl;
}#include <openstudio/model/AirLoopHVAC.hpp>
#include <openstudio/model/PlantLoop.hpp>
#include <openstudio/energyplus/ForwardTranslator.hpp>
using namespace openstudio;
using namespace openstudio::model;
using namespace openstudio::energyplus;
Model model;
// Create air loop system
AirLoopHVAC airLoop(model);
airLoop.setName("VAV System 1");
// Add zones to air loop
ThermalZone zone1(model);
ThermalZone zone2(model);
airLoop.addBranchForZone(zone1);
airLoop.addBranchForZone(zone2);
// Create hot water plant loop
PlantLoop hotWaterLoop(model);
hotWaterLoop.setName("Hot Water Loop");
// Add boiler to plant loop
Schedule alwaysOn = model.alwaysOnDiscreteSchedule();
BoilerHotWater boiler(model);
hotWaterLoop.addSupplyBranchForComponent(boiler);
// Add heating coil to air loop and connect to plant
CoilHeatingWater heatingCoil(model, alwaysOn);
// Note: Connection would be done through the model's connect method
model.connect(hotWaterLoop.supplyOutletNode(), heatingCoil.waterInletModelObject().get(),
heatingCoil.waterOutletModelObject().get(), hotWaterLoop.demandInletNode());
// Translate complete system
ForwardTranslator ft;
Workspace workspace = ft.translateModel(model);
// Check HVAC translation specifically
std::vector<LogMessage> warnings = ft.warnings();
for (const auto& warning : warnings) {
if (warning.logMessage().find("HVAC") != std::string::npos ||
warning.logMessage().find("AirLoop") != std::string::npos) {
std::cout << "HVAC Warning: " << warning.logMessage() << std::endl;
}
}Install with Tessl CLI
npx tessl i tessl/pypi-openstudio