Search in sources :

Example 31 with Window

use of org.concord.energy3d.model.Window in project energy3d by concord-consortium.

the class Scene method cleanup.

private void cleanup() {
    // fix if roof and wall are not linked from each other
    for (final HousePart p : parts) {
        if (p instanceof Roof) {
            final Roof r = (Roof) p;
            final HousePart c = r.getContainer();
            if (c != null && !c.getChildren().contains(r)) {
                c.getChildren().add(r);
            }
        }
    }
    final ArrayList<HousePart> toBeRemoved = new ArrayList<HousePart>();
    for (final HousePart p : parts) {
        if (!p.isValid()) {
            // remove invalid parts
            toBeRemoved.add(p);
        } else if (p.getContainer() == null) {
            // remove orphan parts without a container
            if (p instanceof Wall || p instanceof Roof || p instanceof Window || p instanceof Door || p instanceof SolarCollector || p instanceof Floor) {
                toBeRemoved.add(p);
            }
        } else if (!parts.contains(p.getContainer())) {
            // remove parts whose container doesn't exist in the scene
            toBeRemoved.add(p);
        }
    }
    for (final HousePart p : toBeRemoved) {
        remove(p, false);
    }
    // remove walls that are at the same position
    toBeRemoved.clear();
    for (final HousePart p : parts) {
        if (p instanceof Wall) {
            // remove walls that are at the same position
            if (((Wall) p).isAtSamePlaceAsAnotherPart()) {
                toBeRemoved.add(p);
            }
        }
    }
    for (final HousePart p : toBeRemoved) {
        remove(p, false);
    }
    // remove children with multiple parents
    toBeRemoved.clear();
    for (final HousePart p : parts) {
        for (final HousePart child : p.getChildren()) {
            if (child.getContainer() != p && !toBeRemoved.contains(child)) {
                toBeRemoved.add(child);
            }
        }
    }
    for (final HousePart p : toBeRemoved) {
        remove(p, false);
    }
    // remove from remaining parents
    for (final HousePart p : parts) {
        for (final HousePart r : toBeRemoved) {
            p.getChildren().remove(r);
        }
    }
    // remove all the children that are not in parts
    toBeRemoved.clear();
    for (final HousePart p : parts) {
        for (final HousePart child : p.getChildren()) {
            if (!parts.contains(child) && !toBeRemoved.contains(child)) {
                toBeRemoved.add(child);
            }
        }
    }
    for (final HousePart p : toBeRemoved) {
        remove(p, false);
    }
    // complete all non-completed parts
    for (final HousePart p : parts) {
        if (!p.isDrawCompleted()) {
            p.complete();
        }
    }
}
Also used : Window(org.concord.energy3d.model.Window) Floor(org.concord.energy3d.model.Floor) Roof(org.concord.energy3d.model.Roof) Wall(org.concord.energy3d.model.Wall) SolarCollector(org.concord.energy3d.model.SolarCollector) ArrayList(java.util.ArrayList) HousePart(org.concord.energy3d.model.HousePart) Door(org.concord.energy3d.model.Door)

Example 32 with Window

use of org.concord.energy3d.model.Window in project energy3d by concord-consortium.

the class SceneManager method mousePressed.

private void mousePressed(final MouseState mouseState, final KeyboardState keyboardState) {
    refresh = true;
    taskManager.update(new Callable<Object>() {

        @Override
        public Object call() {
            if (zoomLock) {
                return null;
            }
            System.out.println("OPERATION: " + operation);
            try {
                if (operation == Operation.SELECT || operation == Operation.RESIZE || operation == Operation.ROTATE || operation == Operation.DRAW_ROOF_GABLE) {
                    if (selectedPart == null || selectedPart.isDrawCompleted()) {
                        final HousePart previousSelectedPart = selectedPart;
                        final PickedHousePart pickedPart = SelectUtil.selectHousePart(mouseState.getX(), mouseState.getY(), true);
                        final UserData pick = pickedPart == null ? null : pickedPart.getUserData();
                        if (pick == null) {
                            selectedPart = null;
                        } else {
                            selectedPart = pick.getHousePart();
                        }
                        if (selectedPart != null) {
                            // }
                            if (keyboardState.isDown(Key.LMENU) || keyboardState.isDown(Key.RMENU)) {
                                if (selectedPart instanceof SolarPanel && selectedPart.getContainer() instanceof Rack) {
                                    // special case
                                    selectedPart = selectedPart.getContainer();
                                }
                            }
                        }
                        System.out.println("Clicked on: " + pick);
                        if (pick != null && pick.isEditPoint()) {
                            cameraControl.setLeftMouseButtonEnabled(false);
                        }
                        if (operation == Operation.RESIZE) {
                            for (final HousePart p : Scene.getInstance().getParts()) {
                                if (p instanceof Foundation) {
                                    if (p != selectedPart) {
                                        ((Foundation) p).setResizeHouseMode(false);
                                    }
                                }
                            }
                            if (selectedPart != null) {
                                if (selectedPart instanceof Foundation) {
                                    final Foundation foundation = (Foundation) selectedPart;
                                    foundation.setResizeHouseMode(true);
                                } else {
                                    final Foundation foundation = selectedPart.getTopContainer();
                                    if (foundation != null) {
                                        foundation.setResizeHouseMode(true);
                                        setSelectedPart(foundation);
                                    }
                                }
                            }
                        }
                        if (operation == Operation.SELECT || operation == Operation.ROTATE) {
                            if (previousSelectedPart instanceof Foundation) {
                                final Foundation foundation = (Foundation) previousSelectedPart;
                                foundation.updateAzimuthArrowVisibility(false);
                            }
                            if (selectedPart instanceof Foundation) {
                                final Foundation foundation = (Foundation) selectedPart;
                                foundation.drawAzimuthArrow();
                                foundation.pickMesh(mouseState.getX(), mouseState.getY());
                            }
                            if (selectedPart != null) {
                                final Foundation foundationOfSelectedPart = selectedPart instanceof Foundation ? (Foundation) selectedPart : selectedPart.getTopContainer();
                                if (foundationOfSelectedPart != null) {
                                    foundationOfSelectedPart.setMovePointsVisible(true);
                                }
                            }
                        }
                        if (operation == Operation.RESIZE && selectedPart != null) {
                            if (!(selectedPart instanceof Foundation)) {
                                selectedPart.setEditPointsVisible(false);
                                selectedPart = selectedPart.getTopContainer();
                            }
                        }
                        if (selectedPart instanceof Window || selectedPart instanceof Tree || (selectedPart instanceof Foundation && pick.getEditPointIndex() != -1)) {
                            cameraControl.setLeftMouseButtonEnabled(false);
                            objectMoveStartPoint = pickedPart.getPoint().clone();
                            collisionLand.setTranslation(0, 0, objectMoveStartPoint.getZ());
                            final ArrayList<Vector3> points = selectedPart.getPoints();
                            if (objectMovePoints == null) {
                                objectMovePoints = new ArrayList<Vector3>();
                            } else {
                                objectMovePoints.clear();
                            }
                            for (final Vector3 p : points) {
                                objectMovePoints.add(p.clone());
                            }
                            if (selectedPart instanceof Foundation) {
                                final Foundation f = (Foundation) selectedPart;
                                if (f.isGroupMaster()) {
                                    final List<Foundation> g = Scene.getInstance().getFoundationGroup(f);
                                    if (!g.isEmpty()) {
                                        if (objectGroupMovePoints == null) {
                                            objectGroupMovePoints = new HashMap<Foundation, ArrayList<Vector3>>();
                                        } else {
                                            objectGroupMovePoints.clear();
                                        }
                                        for (final Foundation a : g) {
                                            final ArrayList<Vector3> b = new ArrayList<Vector3>();
                                            objectGroupMovePoints.put(a, b);
                                            for (final Vector3 p : a.getPoints()) {
                                                b.add(p.clone());
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (previousSelectedPart != null && previousSelectedPart != selectedPart && operation != Operation.RESIZE) {
                            previousSelectedPart.setEditPointsVisible(false);
                            previousSelectedPart.setGridsVisible(false);
                            previousSelectedPart.setLinePatternVisible(false);
                            final Foundation foundationOfPreviousSelectedPart = previousSelectedPart instanceof Foundation ? (Foundation) previousSelectedPart : previousSelectedPart.getTopContainer();
                            if (foundationOfPreviousSelectedPart != null) {
                                if (selectedPart == null) {
                                    foundationOfPreviousSelectedPart.setMovePointsVisible(false);
                                } else if (foundationOfPreviousSelectedPart != (selectedPart instanceof Foundation ? (Foundation) selectedPart : selectedPart.getTopContainer())) {
                                    foundationOfPreviousSelectedPart.setMovePointsVisible(false);
                                }
                                foundationOfPreviousSelectedPart.clearSelectedMesh();
                                foundationOfPreviousSelectedPart.setResizeHouseMode(false);
                            }
                        }
                        if (selectedPart != null && !PrintController.getInstance().isPrintPreview()) {
                            selectedPart.setEditPointsVisible(true);
                            if (pick.isEditPoint() && pick.getEditPointIndex() != -1 || operation == Operation.RESIZE || selectedPart instanceof Window || selectedPart instanceof Tree) {
                                if (Scene.getInstance().isSnapToGrids()) {
                                    selectedPart.setGridsVisible(true);
                                } else {
                                    selectedPart.setLinePatternVisible(true);
                                }
                                if (selectedPart instanceof Foundation) {
                                    editPartCommand = new EditFoundationCommand((Foundation) selectedPart, !pick.isEditPoint());
                                } else if (selectedPart instanceof Rack) {
                                    editPartCommand = new EditRackCommand((Rack) selectedPart);
                                } else if (selectedPart instanceof ParabolicTrough) {
                                    editPartCommand = new EditParabolicTroughCommand((ParabolicTrough) selectedPart);
                                } else {
                                    editPartCommand = new EditPartCommand(selectedPart);
                                }
                            }
                        }
                        SelectUtil.nextPickLayer();
                        if (operation == Operation.DRAW_ROOF_GABLE && selectedPart instanceof Roof) {
                            System.out.println("deleting roof #" + pick.getEditPointIndex());
                            final int roofPartIndex = pick.getEditPointIndex();
                            final Roof roof = (Roof) selectedPart;
                            roof.setGable(roofPartIndex, true, undoManager);
                        }
                    }
                } else {
                    if (selectedPart != null) {
                        // selected part can be null in modes other than specified in the if clause
                        selectedPart.addPoint(mouseState.getX(), mouseState.getY());
                    }
                }
            } catch (final Throwable t) {
                t.printStackTrace();
                BugReporter.report(t);
            }
            return null;
        }
    });
}
Also used : Window(org.concord.energy3d.model.Window) EditPartCommand(org.concord.energy3d.undo.EditPartCommand) EditRackCommand(org.concord.energy3d.undo.EditRackCommand) ParabolicTrough(org.concord.energy3d.model.ParabolicTrough) UserData(org.concord.energy3d.model.UserData) HashMap(java.util.HashMap) EditParabolicTroughCommand(org.concord.energy3d.undo.EditParabolicTroughCommand) ArrayList(java.util.ArrayList) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) Rack(org.concord.energy3d.model.Rack) EditFoundationCommand(org.concord.energy3d.undo.EditFoundationCommand) Roof(org.concord.energy3d.model.Roof) GambrelRoof(org.concord.energy3d.model.GambrelRoof) ShedRoof(org.concord.energy3d.model.ShedRoof) PyramidRoof(org.concord.energy3d.model.PyramidRoof) HipRoof(org.concord.energy3d.model.HipRoof) CustomRoof(org.concord.energy3d.model.CustomRoof) SolarPanel(org.concord.energy3d.model.SolarPanel) Tree(org.concord.energy3d.model.Tree) Foundation(org.concord.energy3d.model.Foundation) ArrayList(java.util.ArrayList) List(java.util.List) PickedHousePart(org.concord.energy3d.model.PickedHousePart) HousePart(org.concord.energy3d.model.HousePart) PickedHousePart(org.concord.energy3d.model.PickedHousePart)

Example 33 with Window

use of org.concord.energy3d.model.Window in project energy3d by concord-consortium.

the class SolarRadiation method computeToday.

private void computeToday() {
    // save current calendar for restoring at the end of this calculation
    final Calendar today = (Calendar) Heliodon.getInstance().getCalendar().clone();
    hourOfDay = today.get(Calendar.HOUR_OF_DAY);
    minuteOfHour = today.get(Calendar.MINUTE);
    today.set(Calendar.SECOND, 0);
    today.set(Calendar.MINUTE, 0);
    today.set(Calendar.HOUR_OF_DAY, 0);
    final String city = (String) EnergyPanel.getInstance().getCityComboBox().getSelectedItem();
    dailyAirTemperatures = Weather.computeOutsideTemperature(today, city);
    final int timeStep = Scene.getInstance().getTimeStep();
    final ReadOnlyVector3[] sunLocations = new ReadOnlyVector3[SolarRadiation.MINUTES_OF_DAY / timeStep];
    int totalSteps = 0;
    for (int minute = 0; minute < SolarRadiation.MINUTES_OF_DAY; minute += timeStep) {
        final ReadOnlyVector3 sunLocation = Heliodon.getInstance().computeSunLocation(today).normalizeLocal();
        sunLocations[minute / timeStep] = sunLocation;
        if (sunLocation.getZ() > 0) {
            totalSteps++;
        }
        today.add(Calendar.MINUTE, timeStep);
    }
    totalSteps -= 2;
    final double dayLength = totalSteps * timeStep / 60.0;
    int step = 1;
    setupImportedMeshes();
    // for (int minute = MINUTES_OF_DAY / 2; minute < MINUTES_OF_DAY / 2 + timeStep; minute += timeStep) { // test for 12 pm for comparison with shadow
    for (int minute = 0; minute < MINUTES_OF_DAY; minute += timeStep) {
        final ReadOnlyVector3 sunLocation = sunLocations[minute / timeStep];
        if (sunLocation.getZ() > 0) {
            final ReadOnlyVector3 directionTowardSun = sunLocation.normalize(null);
            calculatePeakRadiation(directionTowardSun, dayLength);
            for (final HousePart part : Scene.getInstance().getParts()) {
                if (part.isDrawCompleted()) {
                    if (part instanceof Window) {
                        computeOnMesh(minute, directionTowardSun, part, part.getRadiationMesh(), (Mesh) part.getRadiationCollisionSpatial(), part.getNormal());
                    } else if (part instanceof Wall) {
                        if (((Wall) part).getType() == Wall.SOLID_WALL) {
                            computeOnMesh(minute, directionTowardSun, part, part.getRadiationMesh(), (Mesh) part.getRadiationCollisionSpatial(), part.getNormal());
                        }
                    } else if (part instanceof Door || part instanceof Floor) {
                        computeOnMesh(minute, directionTowardSun, part, part.getRadiationMesh(), (Mesh) part.getRadiationCollisionSpatial(), part.getNormal());
                    } else if (part instanceof Foundation) {
                        final Foundation foundation = (Foundation) part;
                        for (int i = 0; i < 5; i++) {
                            final Mesh radiationMesh = foundation.getRadiationMesh(i);
                            final ReadOnlyVector3 normal = i == 0 ? part.getNormal() : ((UserData) radiationMesh.getUserData()).getNormal();
                            computeOnMesh(minute, directionTowardSun, part, radiationMesh, foundation.getRadiationCollisionSpatial(i), normal);
                        }
                        if (!Scene.getInstance().getOnlySolarComponentsInSolarMap()) {
                            final List<Node> importedNodes = foundation.getImportedNodes();
                            if (importedNodes != null) {
                                for (final Node node : importedNodes) {
                                    for (final Spatial s : node.getChildren()) {
                                        final Mesh m = (Mesh) s;
                                        computeOnImportedMesh(minute, directionTowardSun, foundation, m);
                                    }
                                }
                            }
                        }
                    } else if (part instanceof Roof) {
                        for (final Spatial roofPart : ((Roof) part).getRoofPartsRoot().getChildren()) {
                            if (roofPart.getSceneHints().getCullHint() != CullHint.Always) {
                                final ReadOnlyVector3 faceDirection = (ReadOnlyVector3) roofPart.getUserData();
                                final Mesh mesh = (Mesh) ((Node) roofPart).getChild(6);
                                computeOnMesh(minute, directionTowardSun, part, mesh, mesh, faceDirection);
                            }
                        }
                    } else if (part instanceof SolarPanel) {
                        computeOnSolarPanel(minute, directionTowardSun, (SolarPanel) part);
                    } else if (part instanceof Rack) {
                        computeOnRack(minute, directionTowardSun, (Rack) part);
                    } else if (part instanceof Mirror) {
                        computeOnMirror(minute, directionTowardSun, (Mirror) part);
                    } else if (part instanceof FresnelReflector) {
                        computeOnFresnelReflector(minute, directionTowardSun, (FresnelReflector) part);
                    } else if (part instanceof ParabolicTrough) {
                        computeOnParabolicTrough(minute, directionTowardSun, (ParabolicTrough) part);
                    } else if (part instanceof ParabolicDish) {
                        computeOnParabolicDish(minute, directionTowardSun, (ParabolicDish) part);
                    } else if (part instanceof Sensor) {
                        computeOnSensor(minute, directionTowardSun, (Sensor) part);
                    }
                }
            }
            computeOnLand(directionTowardSun);
            EnergyPanel.getInstance().progress((int) Math.round(100.0 * step / totalSteps));
            step++;
        }
    }
    maxValue = Math.round((MINUTES_OF_DAY / timeStep + 1.0) * (1 - 0.01 * Scene.getInstance().getSolarHeatMapColorContrast()));
    // If tracking the sun, the heliodon's calendar has been changed. Restore the time now.
    resetTrackables();
}
Also used : ParabolicTrough(org.concord.energy3d.model.ParabolicTrough) Wall(org.concord.energy3d.model.Wall) UserData(org.concord.energy3d.model.UserData) Node(com.ardor3d.scenegraph.Node) Rack(org.concord.energy3d.model.Rack) Roof(org.concord.energy3d.model.Roof) Foundation(org.concord.energy3d.model.Foundation) List(java.util.List) ArrayList(java.util.ArrayList) HousePart(org.concord.energy3d.model.HousePart) Window(org.concord.energy3d.model.Window) Floor(org.concord.energy3d.model.Floor) FresnelReflector(org.concord.energy3d.model.FresnelReflector) Calendar(java.util.Calendar) Mesh(com.ardor3d.scenegraph.Mesh) CullHint(com.ardor3d.scenegraph.hint.CullHint) TPoint(org.poly2tri.triangulation.point.TPoint) Point(org.poly2tri.geometry.primitives.Point) Door(org.concord.energy3d.model.Door) ParabolicDish(org.concord.energy3d.model.ParabolicDish) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Spatial(com.ardor3d.scenegraph.Spatial) SolarPanel(org.concord.energy3d.model.SolarPanel) Mirror(org.concord.energy3d.model.Mirror) Sensor(org.concord.energy3d.model.Sensor)

Example 34 with Window

use of org.concord.energy3d.model.Window in project energy3d by concord-consortium.

the class SolarRadiation method computeOnMesh.

// Formula from http://en.wikipedia.org/wiki/Air_mass_(solar_energy)#Solar_intensity
private void computeOnMesh(final int minute, final ReadOnlyVector3 directionTowardSun, final HousePart housePart, final Mesh drawMesh, final Mesh collisionMesh, final ReadOnlyVector3 normal) {
    if (normal == null) {
        // FIXME: normal can be null sometimes, fix it
        return;
    }
    if (Scene.getInstance().getOnlySolarComponentsInSolarMap()) {
        return;
    }
    MeshDataStore data = onMesh.get(drawMesh);
    if (data == null) {
        data = initMeshTextureData(drawMesh, collisionMesh, normal, !(housePart instanceof Window));
    }
    /* needed in order to prevent picking collision with neighboring wall at wall edge (seem 0.1 is too small, 0.5 is about right) */
    final ReadOnlyVector3 offset = directionTowardSun.multiply(0.5, null);
    final double dot = normal.dot(directionTowardSun);
    final double directRadiation = dot > 0 ? calculateDirectRadiation(directionTowardSun, normal) : 0;
    final double indirectRadiation = calculateDiffuseAndReflectedRadiation(directionTowardSun, normal);
    final int timeStep = Scene.getInstance().getTimeStep();
    final double solarStep = Scene.getInstance().getSolarStep();
    final double annotationScale = Scene.getInstance().getAnnotationScale();
    final double scaleFactor = annotationScale * annotationScale / 60 * timeStep;
    // a window itself doesn't really absorb solar energy, but it passes the energy into the house to be absorbed
    final float absorption = housePart instanceof Window ? 1 : 1 - housePart.getAlbedo();
    if (housePart instanceof Roof) {
        // for now, only store this for roofs that have different meshes
        if (data.solarPotential == null) {
            data.solarPotential = new double[MINUTES_OF_DAY / timeStep];
        }
        if (data.heatLoss == null) {
            data.heatLoss = new double[MINUTES_OF_DAY / timeStep];
        }
    }
    for (int col = 0; col < data.cols; col++) {
        final double w = col == data.cols - 1 ? data.p2.distance(data.u.multiply(col * solarStep, null).addLocal(data.p0)) : solarStep;
        final ReadOnlyVector3 pU = data.u.multiply(col * solarStep + 0.5 * w, null).addLocal(data.p0);
        for (int row = 0; row < data.rows; row++) {
            if (EnergyPanel.getInstance().isCancelled()) {
                throw new CancellationException();
            }
            if (data.dailySolarIntensity[row][col] == -1) {
                continue;
            }
            final double h = row == data.rows - 1 ? data.p1.distance(data.p0) - row * solarStep : solarStep;
            final ReadOnlyVector3 p = data.v.multiply(row * solarStep + 0.5 * h, null).addLocal(pU).add(offset, null);
            final Ray3 pickRay = new Ray3(p, directionTowardSun);
            final PickResults pickResults = new PrimitivePickResults();
            // assuming that indirect (ambient or diffuse) radiation can always reach a grid point
            double radiation = indirectRadiation;
            final double scaledArea = w * h * scaleFactor;
            if (dot > 0) {
                for (final Spatial spatial : collidables) {
                    if (EnergyPanel.getInstance().isCancelled()) {
                        throw new CancellationException();
                    }
                    if (spatial != collisionMesh) {
                        PickingUtil.findPick(spatial, pickRay, pickResults, false);
                        if (pickResults.getNumber() != 0) {
                            if (housePart instanceof Foundation) {
                                // at this point, we only show radiation heat map on the first floor
                                final HousePart collidableOwner = collidablesToParts.get(spatial);
                                if (collidableOwner instanceof Window) {
                                    radiation += directRadiation * ((Window) collidableOwner).getSolarHeatGainCoefficient();
                                }
                            }
                            break;
                        }
                    }
                }
                if (pickResults.getNumber() == 0) {
                    radiation += directRadiation;
                }
            }
            data.dailySolarIntensity[row][col] += Scene.getInstance().getOnlyAbsorptionInSolarMap() ? absorption * radiation : radiation;
            if (data.solarPotential != null) {
                data.solarPotential[minute / timeStep] += radiation * scaledArea;
            }
            if (!(housePart instanceof Foundation)) {
                // exclude radiation on foundation
                housePart.getSolarPotential()[minute / timeStep] += radiation * scaledArea;
            }
        }
    }
}
Also used : Window(org.concord.energy3d.model.Window) CullHint(com.ardor3d.scenegraph.hint.CullHint) TPoint(org.poly2tri.triangulation.point.TPoint) Point(org.poly2tri.geometry.primitives.Point) Ray3(com.ardor3d.math.Ray3) PrimitivePickResults(com.ardor3d.intersection.PrimitivePickResults) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Roof(org.concord.energy3d.model.Roof) CancellationException(java.util.concurrent.CancellationException) Spatial(com.ardor3d.scenegraph.Spatial) PrimitivePickResults(com.ardor3d.intersection.PrimitivePickResults) PickResults(com.ardor3d.intersection.PickResults) Foundation(org.concord.energy3d.model.Foundation) HousePart(org.concord.energy3d.model.HousePart)

Example 35 with Window

use of org.concord.energy3d.model.Window in project energy3d by concord-consortium.

the class SolarRadiation method computeEnergyAtHour.

public void computeEnergyAtHour(final int hour) {
    final Calendar today = Heliodon.getInstance().getCalendar();
    final String city = (String) EnergyPanel.getInstance().getCityComboBox().getSelectedItem();
    final double[] outsideAirTemperatureRange = Weather.computeOutsideTemperature(today, city);
    final double outsideAirTemperature = Weather.getInstance().getOutsideTemperatureAtMinute(outsideAirTemperatureRange[1], outsideAirTemperatureRange[0], hour * 60);
    for (final HousePart part : Scene.getInstance().getParts()) {
        if (part instanceof Foundation) {
            final Foundation foundation = (Foundation) part;
            if (foundation.getHeatLoss() == null) {
                continue;
            }
            final int n = (int) Math.round(60.0 / Scene.getInstance().getTimeStep());
            final double[] heatLoss = new double[n];
            final double[] passiveSolar = new double[n];
            final double[] photovoltaic = new double[n];
            final double[] csp = new double[n];
            final int t0 = n * hour;
            for (int i = 0; i < n; i++) {
                final double groundHeatLoss = foundation.getHeatLoss()[t0 + i];
                if (groundHeatLoss > 0) {
                    final double thermostat = foundation.getThermostat().getTemperature(today.get(Calendar.MONTH), today.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY, today.get(Calendar.HOUR_OF_DAY));
                    if (outsideAirTemperature >= thermostat) {
                        heatLoss[i] -= groundHeatLoss;
                    }
                } else {
                    heatLoss[i] += groundHeatLoss;
                }
            }
            double solarPotentialTotal = 0.0;
            for (final HousePart child : Scene.getInstance().getParts()) {
                if (child.getTopContainer() == foundation) {
                    child.setSolarPotentialNow(0);
                    if (child instanceof SolarCollector) {
                        ((SolarCollector) child).setYieldNow(0);
                    }
                    for (int i = 0; i < n; i++) {
                        solarPotentialTotal += child.getSolarPotential()[t0 + i];
                        child.setSolarPotentialNow(child.getSolarPotentialNow() + child.getSolarPotential()[t0 + i]);
                        if (child instanceof Wall || child instanceof Door || child instanceof Window || child instanceof Roof) {
                            heatLoss[i] += child.getHeatLoss()[t0 + i];
                        }
                        if (child instanceof Window) {
                            final Window window = (Window) child;
                            passiveSolar[i] += window.getSolarPotential()[t0 + i] * window.getSolarHeatGainCoefficient();
                        } else if (child instanceof Mirror) {
                            final Mirror mirror = (Mirror) child;
                            final double yield = mirror.getSolarPotential()[t0 + i] * mirror.getSystemEfficiency();
                            csp[i] += yield;
                            mirror.setYieldNow(mirror.getYieldNow() + yield);
                        } else if (child instanceof ParabolicTrough) {
                            final ParabolicTrough trough = (ParabolicTrough) child;
                            final double yield = trough.getSolarPotential()[t0 + i] * trough.getSystemEfficiency();
                            csp[i] += yield;
                            trough.setYieldNow(trough.getYieldNow() + yield);
                        } else if (child instanceof ParabolicDish) {
                            final ParabolicDish dish = (ParabolicDish) child;
                            final double yield = dish.getSolarPotential()[t0 + i] * dish.getSystemEfficiency();
                            csp[i] += yield;
                            dish.setYieldNow(dish.getYieldNow() + yield);
                        } else if (child instanceof FresnelReflector) {
                            final FresnelReflector reflector = (FresnelReflector) child;
                            final double yield = reflector.getSolarPotential()[t0 + i] * reflector.getSystemEfficiency();
                            csp[i] += yield;
                            reflector.setYieldNow(reflector.getYieldNow() + yield);
                        } else if (child instanceof SolarPanel) {
                            final SolarPanel sp = (SolarPanel) child;
                            // distributed efficiency must be handled for each individual cell
                            final double yield = sp.getSolarPotential()[t0 + i];
                            photovoltaic[i] += yield;
                            sp.setYieldNow(sp.getYieldNow() + yield);
                        } else if (child instanceof Rack) {
                            final Rack rack = (Rack) child;
                            if (rack.isMonolithic()) {
                                // distributed efficiency must be handled for each individual cell
                                final double yield = rack.getSolarPotential()[t0 + i];
                                photovoltaic[i] += yield;
                                rack.setYieldNow(rack.getYieldNow() + yield);
                            }
                        }
                    }
                }
            }
            double heatingTotal = 0.0;
            double coolingTotal = 0.0;
            double passiveSolarTotal = 0.0;
            double photovoltaicTotal = 0.0;
            double cspTotal = 0.0;
            for (int i = 0; i < n; i++) {
                if (heatLoss[i] < 0) {
                    heatLoss[i] -= passiveSolar[i];
                } else {
                    heatLoss[i] = Math.max(0, heatLoss[i] - passiveSolar[i]);
                }
                if (heatLoss[i] > 0) {
                    heatingTotal += heatLoss[i];
                } else {
                    coolingTotal -= heatLoss[i];
                }
                passiveSolarTotal += passiveSolar[i];
                photovoltaicTotal += photovoltaic[i];
                cspTotal += csp[i];
            }
            foundation.setSolarPotentialNow(solarPotentialTotal);
            foundation.setPassiveSolarNow(passiveSolarTotal);
            foundation.setPhotovoltaicNow(photovoltaicTotal);
            foundation.setCspNow(cspTotal);
            foundation.setHeatingNow(heatingTotal);
            foundation.setCoolingNow(coolingTotal);
            foundation.setTotalEnergyNow(heatingTotal + coolingTotal - photovoltaicTotal);
        }
    }
}
Also used : Window(org.concord.energy3d.model.Window) ParabolicTrough(org.concord.energy3d.model.ParabolicTrough) FresnelReflector(org.concord.energy3d.model.FresnelReflector) Wall(org.concord.energy3d.model.Wall) Calendar(java.util.Calendar) CullHint(com.ardor3d.scenegraph.hint.CullHint) TPoint(org.poly2tri.triangulation.point.TPoint) Point(org.poly2tri.geometry.primitives.Point) Door(org.concord.energy3d.model.Door) ParabolicDish(org.concord.energy3d.model.ParabolicDish) Rack(org.concord.energy3d.model.Rack) Roof(org.concord.energy3d.model.Roof) SolarCollector(org.concord.energy3d.model.SolarCollector) SolarPanel(org.concord.energy3d.model.SolarPanel) Foundation(org.concord.energy3d.model.Foundation) Mirror(org.concord.energy3d.model.Mirror) HousePart(org.concord.energy3d.model.HousePart)

Aggregations

Window (org.concord.energy3d.model.Window)57 HousePart (org.concord.energy3d.model.HousePart)43 Foundation (org.concord.energy3d.model.Foundation)39 Roof (org.concord.energy3d.model.Roof)28 Wall (org.concord.energy3d.model.Wall)28 Rack (org.concord.energy3d.model.Rack)27 Door (org.concord.energy3d.model.Door)25 SolarPanel (org.concord.energy3d.model.SolarPanel)25 Mirror (org.concord.energy3d.model.Mirror)16 ArrayList (java.util.ArrayList)15 FresnelReflector (org.concord.energy3d.model.FresnelReflector)14 ParabolicTrough (org.concord.energy3d.model.ParabolicTrough)14 ParabolicDish (org.concord.energy3d.model.ParabolicDish)13 Tree (org.concord.energy3d.model.Tree)12 List (java.util.List)10 Floor (org.concord.energy3d.model.Floor)10 ReadOnlyVector3 (com.ardor3d.math.type.ReadOnlyVector3)9 SolarCollector (org.concord.energy3d.model.SolarCollector)9 Human (org.concord.energy3d.model.Human)8 Vector3 (com.ardor3d.math.Vector3)7