use of org.concord.energy3d.model.Human in project energy3d by concord-consortium.
the class HeatLoad method computeEnergyToday.
public void computeEnergyToday(final Calendar today) {
today.set(Calendar.SECOND, 0);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.HOUR_OF_DAY, 0);
if (EnergyPanel.getInstance().getCityComboBox().getSelectedItem().equals("")) {
return;
}
final int timeStep = Scene.getInstance().getTimeStep();
final double[] outsideTemperatureRange = Weather.computeOutsideTemperature(today, (String) EnergyPanel.getInstance().getCityComboBox().getSelectedItem());
// System.out.println(today.get(Calendar.DAY_OF_YEAR) + ", " + outsideTemperatureRange[0] + ", " + outsideTemperatureRange[1]);
int iMinute = 0;
for (int minute = 0; minute < SolarRadiation.MINUTES_OF_DAY; minute += timeStep) {
iMinute = minute / timeStep;
final double outsideTemperature = Weather.getInstance().getOutsideTemperatureAtMinute(outsideTemperatureRange[1], outsideTemperatureRange[0], minute);
final double groundTemperature = Scene.getInstance().getGround().getTemperatureMinuteOfDay(today.get(Calendar.DAY_OF_YEAR), minute, 0.5 * (outsideTemperatureRange[1] - outsideTemperatureRange[0]));
for (final HousePart part : Scene.getInstance().getParts()) {
if (part instanceof Human || part instanceof Tree || part instanceof Floor || (part instanceof SolarCollector && !(part instanceof Sensor))) {
continue;
}
final double insideTemperature = (part instanceof Foundation ? (Foundation) part : part.getTopContainer()).getThermostat().getTemperature(today.get(Calendar.MONTH), today.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY, minute / 60);
final float absorption = part instanceof Window ? 0 : 1 - part.getAlbedo();
if (part instanceof Roof) {
// need to compute piece by piece for a roof because sun affects outside temperature of roof part
final Roof roof = (Roof) part;
for (final Spatial child : roof.getRoofPartsRoot().getChildren()) {
if (child.getSceneHints().getCullHint() != CullHint.Always) {
final Mesh mesh = (Mesh) ((Node) child).getChild(6);
final double[] solarPotential = SolarRadiation.getInstance().getSolarPotential(mesh);
final double solarHeat = solarPotential != null ? solarPotential[iMinute] * absorption / roof.getVolumetricHeatCapacity() : 0;
final double deltaT = insideTemperature - (outsideTemperature + solarHeat);
if (part.isDrawCompleted()) {
final double uValue = getUValue(part);
if (Util.isZero(uValue)) {
continue;
}
double heatloss = roof.getAreaWithoutOverhang(mesh) * uValue * deltaT / 1000.0 / 60 * timeStep;
// if the lowest outside temperature is high enough, there is no need to turn on the heater hence no heat loss
if (heatloss > 0 && outsideTemperatureRange[0] >= LOWEST_TEMPERATURE_OF_WARM_DAY) {
heatloss = 0;
}
roof.getHeatLoss()[iMinute] += heatloss;
final double[] heatLossArray = SolarRadiation.getInstance().getHeatLoss(mesh);
if (heatLossArray != null) {
heatLossArray[iMinute] += heatloss;
}
}
}
}
} else if (part instanceof Foundation) {
final Foundation foundation = (Foundation) part;
final double deltaT = insideTemperature - groundTemperature;
if (foundation.isDrawCompleted()) {
final double uValue = getUValue(part);
if (Util.isZero(uValue)) {
continue;
}
final Building building = new Building(foundation);
double area;
if (building.isWallComplete()) {
building.calculate();
area = building.getArea();
} else {
area = foundation.getArea();
}
final double heatloss = area * uValue * deltaT / 1000.0 / 60 * timeStep;
// if (iMinute % 4 == 0) System.out.println((int) (iMinute / 4) + "=" + outsideTemperature + ", " + groundTemperature + ", " + deltaT + ", " + heatloss);
foundation.getHeatLoss()[iMinute] += heatloss;
}
} else {
double deltaT = insideTemperature - outsideTemperature;
if (part instanceof Thermal) {
// direct solar heating raises the outside temperature
deltaT -= part.getSolarPotential()[iMinute] * absorption / ((Thermal) part).getVolumetricHeatCapacity();
}
if (part.isDrawCompleted()) {
final double uValue = getUValue(part);
if (Util.isZero(uValue)) {
continue;
}
double heatloss = part.getArea() * uValue * deltaT / 1000.0 / 60 * timeStep;
// if outside is warm enough, there is no need to turn on the heater hence no heat loss
if (heatloss > 0 && outsideTemperatureRange[0] >= LOWEST_TEMPERATURE_OF_WARM_DAY) {
heatloss = 0;
}
part.getHeatLoss()[iMinute] += heatloss;
}
}
}
}
}
use of org.concord.energy3d.model.Human in project energy3d by concord-consortium.
the class BuildingCost method showPieChart.
@Override
void showPieChart() {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
final Foundation selectedBuilding;
if (selectedPart == null || selectedPart instanceof Tree || selectedPart instanceof Human) {
selectedBuilding = null;
} else if (selectedPart instanceof Foundation) {
selectedBuilding = (Foundation) selectedPart;
} else {
selectedBuilding = selectedPart.getTopContainer();
selectedPart.setEditPointsVisible(false);
SceneManager.getInstance().setSelectedPart(selectedBuilding);
}
String details = "";
int count = 0;
for (final HousePart p : Scene.getInstance().getParts()) {
if (p instanceof Foundation) {
count++;
if (selectedBuilding == null) {
final Foundation foundation = (Foundation) p;
details += "$" + (int) getCostByFoundation(foundation) + " (" + foundation.getId() + ") | ";
}
}
}
if (selectedBuilding == null) {
if (count > 0) {
details = details.substring(0, details.length() - 2);
}
}
double wallSum = 0;
double floorSum = 0;
double windowSum = 0;
double roofSum = 0;
double foundationSum = 0;
double doorSum = 0;
double solarPanelSum = 0;
double treeSum = 0;
String info;
if (selectedBuilding != null) {
info = "Building #" + selectedBuilding.getId();
foundationSum = getPartCost(selectedBuilding);
for (final HousePart p : Scene.getInstance().getParts()) {
if (p.getTopContainer() == selectedBuilding) {
if (p instanceof Wall) {
wallSum += getPartCost(p);
} else if (p instanceof Floor) {
floorSum += getPartCost(p);
} else if (p instanceof Window) {
windowSum += getPartCost(p);
} else if (p instanceof Roof) {
roofSum += getPartCost(p);
} else if (p instanceof Door) {
doorSum += getPartCost(p);
} else if (p instanceof SolarPanel || p instanceof Rack) {
solarPanelSum += getPartCost(p);
}
}
if (count <= 1) {
if (p instanceof Tree && !p.getLockEdit()) {
treeSum += getPartCost(p);
}
}
}
} else {
info = count + " buildings";
for (final HousePart p : Scene.getInstance().getParts()) {
if (p instanceof Wall) {
wallSum += getPartCost(p);
} else if (p instanceof Floor) {
floorSum += getPartCost(p);
} else if (p instanceof Window) {
windowSum += getPartCost(p);
} else if (p instanceof Roof) {
roofSum += getPartCost(p);
} else if (p instanceof Foundation) {
foundationSum += getPartCost(p);
} else if (p instanceof Door) {
doorSum += getPartCost(p);
} else if (p instanceof SolarPanel || p instanceof Rack) {
solarPanelSum += getPartCost(p);
} else if (p instanceof Tree && !p.getLockEdit()) {
treeSum += getPartCost(p);
}
}
}
final double[] data = new double[] { wallSum, windowSum, roofSum, foundationSum, floorSum, doorSum, solarPanelSum, treeSum };
// show them in a popup window
final PieChart pie = new PieChart(data, BuildingCostGraph.colors, BuildingCostGraph.legends, "$", info, count > 1 ? details : null, true);
pie.setBackground(Color.WHITE);
pie.setBorder(BorderFactory.createEtchedBorder());
final JDialog dialog = new JDialog(MainFrame.getInstance(), "Project Costs by Category", true);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.getContentPane().add(pie, BorderLayout.CENTER);
final JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
final JButton buttonItemize = new JButton("Itemize");
buttonItemize.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
showItemizedCost();
}
});
buttonPanel.add(buttonItemize);
final JButton buttonClose = new JButton("Close");
buttonClose.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
dialog.dispose();
}
});
buttonPanel.add(buttonClose);
dialog.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
dialog.pack();
dialog.setLocationRelativeTo(MainFrame.getInstance());
dialog.setVisible(true);
}
use of org.concord.energy3d.model.Human in project energy3d by concord-consortium.
the class BuildingCost method showItemizedCost.
@SuppressWarnings("serial")
public void showItemizedCost() {
final JDialog dialog = new JDialog(MainFrame.getInstance(), "Itemized Construction Cost", true);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
final JPanel contentPane = new JPanel(new BorderLayout());
dialog.setContentPane(contentPane);
final JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEtchedBorder());
contentPane.add(panel, BorderLayout.CENTER);
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
Foundation foundation = null;
if (selectedPart instanceof Foundation) {
foundation = (Foundation) selectedPart;
}
final String[] header = new String[] { "ID", "Type", "Cost" };
final int m = header.length;
final List<HousePart> parts = Scene.getInstance().getParts();
int n = 0;
int foundationCount = 0;
for (final HousePart p : parts) {
if (p instanceof Foundation) {
foundationCount++;
}
}
for (final HousePart p : parts) {
if ((p instanceof Human) || (foundationCount > 1 && p instanceof Tree)) {
continue;
}
if (p == foundation || p.getTopContainer() == foundation) {
n++;
}
}
final Object[][] column = new Object[n][m];
int i = 0;
for (final HousePart p : parts) {
if ((p instanceof Human) || (foundationCount > 1 && p instanceof Tree)) {
continue;
}
if (p == foundation || p.getTopContainer() == foundation) {
column[i][0] = p.getId();
String partName = p.toString().substring(0, p.toString().indexOf(')') + 1);
final int beg = partName.indexOf("(");
if (beg != -1) {
partName = partName.substring(0, beg);
}
column[i][1] = partName;
column[i][2] = "$" + getPartCost(p);
i++;
}
}
final JTable table = new JTable(column, header);
table.setModel(new DefaultTableModel(column, header) {
@Override
public boolean isCellEditable(final int row, final int col) {
return false;
}
});
panel.add(new JScrollPane(table), BorderLayout.CENTER);
final JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
contentPane.add(buttonPanel, BorderLayout.SOUTH);
final JButton button = new JButton("Close");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
windowLocation.setLocation(dialog.getLocationOnScreen());
dialog.dispose();
}
});
buttonPanel.add(button);
dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(final WindowEvent e) {
windowLocation.setLocation(dialog.getLocationOnScreen());
dialog.dispose();
}
});
dialog.pack();
if (windowLocation.x > 0 && windowLocation.y > 0) {
dialog.setLocation(windowLocation);
} else {
dialog.setLocationRelativeTo(MainFrame.getInstance());
}
dialog.setVisible(true);
}
use of org.concord.energy3d.model.Human in project energy3d by concord-consortium.
the class CspProjectCost method showPieChart.
@Override
void showPieChart() {
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
final Foundation selectedFoundation;
if (selectedPart == null || selectedPart instanceof Tree || selectedPart instanceof Human) {
selectedFoundation = null;
} else if (selectedPart instanceof Foundation) {
selectedFoundation = (Foundation) selectedPart;
} else {
selectedFoundation = selectedPart.getTopContainer();
selectedPart.setEditPointsVisible(false);
SceneManager.getInstance().setSelectedPart(selectedFoundation);
}
String details = "";
int count = 0;
for (final HousePart p : Scene.getInstance().getParts()) {
if (p instanceof Foundation) {
final Foundation foundation = (Foundation) p;
if (!foundation.hasSolarReceiver()) {
count++;
if (selectedFoundation == null) {
double receiverSum = 0;
final List<Mirror> mirrors = foundation.getHeliostats();
if (!mirrors.isEmpty()) {
final ArrayList<Foundation> towers = new ArrayList<Foundation>();
for (final Mirror m : mirrors) {
if (m.getReceiver() != null) {
if (!towers.contains(m.getReceiver())) {
towers.add(m.getReceiver());
}
}
}
if (!towers.isEmpty()) {
for (final Foundation tower : towers) {
receiverSum += getPartCost(tower);
}
}
} else {
final List<FresnelReflector> reflectors = foundation.getFresnelReflectors();
if (!reflectors.isEmpty()) {
final ArrayList<Foundation> absorbers = new ArrayList<Foundation>();
for (final FresnelReflector r : reflectors) {
if (r.getReceiver() != null) {
if (!absorbers.contains(r.getReceiver())) {
absorbers.add(r.getReceiver());
}
}
}
if (!absorbers.isEmpty()) {
for (final Foundation absorber : absorbers) {
receiverSum += getPartCost(absorber);
}
}
}
}
details += "$" + (int) (getCostByFoundation(foundation) + receiverSum) + " (" + foundation.getId() + ") | ";
}
}
}
}
if (selectedFoundation == null) {
if (count > 0) {
details = details.substring(0, details.length() - 2);
}
}
double landSum = 0;
double collectorSum = 0;
double receiverSum = 0;
String info;
if (selectedFoundation != null) {
info = "Zone #" + selectedFoundation.getId();
if (selectedFoundation.hasSolarReceiver()) {
receiverSum = getPartCost(selectedFoundation);
} else {
landSum = getPartCost(selectedFoundation);
final List<Mirror> mirrors = selectedFoundation.getHeliostats();
if (!mirrors.isEmpty()) {
final ArrayList<Foundation> towers = new ArrayList<Foundation>();
for (final Mirror m : mirrors) {
if (m.getReceiver() != null) {
if (!towers.contains(m.getReceiver())) {
towers.add(m.getReceiver());
}
}
}
if (!towers.isEmpty()) {
for (final Foundation tower : towers) {
receiverSum += getPartCost(tower);
}
}
} else {
final List<FresnelReflector> reflectors = selectedFoundation.getFresnelReflectors();
if (!reflectors.isEmpty()) {
final ArrayList<Foundation> absorbers = new ArrayList<Foundation>();
for (final FresnelReflector r : reflectors) {
if (r.getReceiver() != null) {
if (!absorbers.contains(r.getReceiver())) {
absorbers.add(r.getReceiver());
}
}
}
if (!absorbers.isEmpty()) {
for (final Foundation absorber : absorbers) {
receiverSum += getPartCost(absorber);
}
}
}
}
}
for (final HousePart p : Scene.getInstance().getParts()) {
if (p.getTopContainer() == selectedFoundation) {
if (p instanceof SolarCollector) {
// assuming that sensor doesn't cost anything
collectorSum += getPartCost(p);
}
}
}
} else {
info = count + " zones";
for (final HousePart p : Scene.getInstance().getParts()) {
if (p instanceof Foundation) {
final Foundation f = (Foundation) p;
if (f.hasSolarReceiver()) {
receiverSum += getPartCost(p);
} else {
landSum += getPartCost(p);
}
} else if (p instanceof SolarCollector) {
collectorSum += getPartCost(p);
}
}
}
double[] data;
String[] legends;
if (Util.isZero(receiverSum)) {
data = new double[] { landSum, collectorSum };
legends = new String[] { "Land (" + Scene.getInstance().getCspCustomPrice().getLifespan() + " years)", "Collectors" };
} else {
data = new double[] { landSum, collectorSum, receiverSum };
legends = new String[] { "Land (" + Scene.getInstance().getCspCustomPrice().getLifespan() + " years)", "Collectors", "Receivers" };
}
// show them in a popup window
final PieChart pie = new PieChart(data, CspProjectCostGraph.colors, legends, "$", info, count > 1 ? details : null, true);
pie.setBackground(Color.WHITE);
pie.setBorder(BorderFactory.createEtchedBorder());
final JDialog dialog = new JDialog(MainFrame.getInstance(), "Project Costs by Category", true);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.getContentPane().add(pie, BorderLayout.CENTER);
final JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
final JButton buttonClose = new JButton("Close");
buttonClose.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
dialog.dispose();
}
});
buttonPanel.add(buttonClose);
dialog.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
dialog.pack();
dialog.setLocationRelativeTo(MainFrame.getInstance());
dialog.setVisible(true);
}
use of org.concord.energy3d.model.Human in project energy3d by concord-consortium.
the class MainPanel method getRotateButton.
public JButton getRotateButton() {
if (rotateButton == null) {
rotateButton = new JButton();
if (Config.isMac()) {
// for some reason, the newer version of Mac draws border for JButton (but not JToggleButton)
rotateButton.setBorderPainted(false);
}
rotateButton.addMouseListener(refreshUponMouseExit);
rotateButton.setIcon(new ImageIcon(getClass().getResource("icons/rotate_cw.png")));
rotateButton.setToolTipText("<html>Rotate in the clockwise direction (change azimuth).<br>Hold down the Ctrl key and press this button for counter-clockwise rotation.<br>Hold down the Shift key while pressing this button to rotate more slowly.<br>If a component is selected, rotate around its center. Otherwise rotate everything around the origin.</html>");
rotateButton.setFocusable(false);
addMouseOverEffect(rotateButton);
rotateButton.addMouseListener(new MouseAdapter() {
private volatile boolean mousePressed = false;
@Override
public void mousePressed(final MouseEvent e) {
energyButton.setSelected(false);
mousePressed = true;
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
if (selectedPart == null || selectedPart instanceof Tree || selectedPart instanceof Human) {
int count = 0;
HousePart hp = null;
for (final HousePart x : Scene.getInstance().getParts()) {
if (x instanceof Foundation) {
count++;
hp = x;
}
}
if (count == 1) {
// if there is only one building, automatically select it to ensure that we always rotate around its center
SceneManager.getInstance().setSelectedPart(hp);
SceneManager.getInstance().refresh();
EnergyPanel.getInstance().updateProperties();
}
}
new Thread("Energy3D Continuous Rotation") {
private int count;
private ChangeAzimuthCommand c;
@Override
public void run() {
final HousePart part = SceneManager.getInstance().getSelectedPart();
if (part != null) {
c = new ChangeAzimuthCommand(part);
}
while (mousePressed) {
SceneManager.getTaskManager().update(new Callable<Object>() {
@Override
public Object call() throws Exception {
if (part == null) {
SceneManager.getInstance().rotateAllFoundations(rotationAngle);
} else {
if (part instanceof Foundation) {
SceneManager.getInstance().rotateFoundation(rotationAngle, true);
} else if (part instanceof SolarPanel) {
final SolarPanel solarPanel = (SolarPanel) part;
solarPanel.setRelativeAzimuth(solarPanel.getRelativeAzimuth() + Math.toDegrees(rotationAngle));
solarPanel.draw();
} else if (part instanceof Rack) {
final Rack rack = (Rack) part;
rack.setRelativeAzimuth(rack.getRelativeAzimuth() + Math.toDegrees(rotationAngle));
rack.draw();
} else if (part instanceof Mirror) {
final Mirror mirror = (Mirror) part;
mirror.setRelativeAzimuth(mirror.getRelativeAzimuth() + Math.toDegrees(rotationAngle));
mirror.draw();
}
}
count++;
Scene.getInstance().setEdited(true);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
EnergyPanel.getInstance().updateProperties();
}
});
return null;
}
});
final int partCount = Scene.getInstance().getParts().size();
try {
// give it enough time for the above call to complete (the more parts it has, the more time it needs)
Thread.sleep(200 + partCount * 5);
} catch (final InterruptedException e) {
}
}
// undo only after the thread ends
if (part == null) {
SceneManager.getInstance().getUndoManager().addEdit(new RotateBuildingCommand(null, rotationAngle * count));
} else {
if (part instanceof Foundation) {
SceneManager.getInstance().getUndoManager().addEdit(new RotateBuildingCommand((Foundation) part, rotationAngle * count));
} else if (part instanceof SolarPanel || part instanceof Rack || part instanceof Mirror) {
if (c != null) {
SceneManager.getInstance().getUndoManager().addEdit(c);
}
}
}
}
}.start();
}
@Override
public void mouseReleased(final MouseEvent e) {
mousePressed = false;
}
});
}
return rotateButton;
}
Aggregations