From dfea68adaf35cb0faf4eec61c99d7ff621fe2f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Ha=C3=9Fel?= Date: Wed, 22 May 2024 11:46:52 +0200 Subject: [PATCH] Admittance matrix (Knotenpotentialverfahren) --- pom.xml | 5 + src/main/java/de/ph87/electro/CONFIG.java | 4 +- .../de/ph87/electro/circuit/Calculation.java | 216 ++++++++++++++++++ .../java/de/ph87/electro/circuit/Circuit.java | 23 +- .../de/ph87/electro/circuit/CircuitPanel.java | 23 +- .../java/de/ph87/electro/circuit/Wire.java | 49 +++- .../electro/circuit/part/InnerConnection.java | 14 ++ .../ph87/electro/circuit/part/Junction.java | 31 +-- .../de/ph87/electro/circuit/part/Part.java | 20 +- .../ph87/electro/circuit/part/PartOther.java | 4 +- .../ph87/electro/circuit/part/Position.java | 4 + .../de/ph87/electro/circuit/part/Render.java | 6 +- .../circuit/part/parts/PartBattery.java | 48 ++-- .../part/parts/PartJunctionCorner.java | 14 +- .../circuit/part/parts/PartJunctionEdge.java | 13 +- .../part/parts/PartJunctionMiddle.java | 9 +- .../electro/circuit/part/parts/PartLight.java | 56 ++--- .../circuit/part/parts/PartLightDto.java | 11 +- .../circuit/part/parts/PartSwitch1x1.java | 38 ++- .../circuit/part/parts/PartSwitch1x2.java | 47 ++-- .../circuit/part/parts/PartSwitchCross.java | 65 ++---- .../electro/circuit/BatteryLightTest.java | 18 +- .../circuit/BatterySwitcher1x1Test.java | 22 +- .../circuit/BatterySwitcher1x2Test.java | 34 +-- .../circuit/BatterySwitcher2x2Test.java | 28 +-- .../circuit/BatterySwitcherCrossTest.java | 34 +-- ...ava => CircuitCalculationServiceTest.java} | 6 +- .../circuit/net/CalculationServiceTest.java | 40 ++++ .../electro/circuit/net/CalculationTest.java | 19 ++ 29 files changed, 575 insertions(+), 326 deletions(-) create mode 100644 src/main/java/de/ph87/electro/circuit/Calculation.java create mode 100644 src/main/java/de/ph87/electro/circuit/part/InnerConnection.java rename src/test/java/de/ph87/electro/circuit/{CircuitServiceTest.java => CircuitCalculationServiceTest.java} (95%) create mode 100644 src/test/java/de/ph87/electro/circuit/net/CalculationServiceTest.java create mode 100644 src/test/java/de/ph87/electro/circuit/net/CalculationTest.java diff --git a/pom.xml b/pom.xml index cd697aa..e731b04 100644 --- a/pom.xml +++ b/pom.xml @@ -35,6 +35,11 @@ jackson-databind 2.17.0 + + org.apache.commons + commons-math3 + 3.6.1 + \ No newline at end of file diff --git a/src/main/java/de/ph87/electro/CONFIG.java b/src/main/java/de/ph87/electro/CONFIG.java index aaf6211..a009bb4 100644 --- a/src/main/java/de/ph87/electro/CONFIG.java +++ b/src/main/java/de/ph87/electro/CONFIG.java @@ -6,9 +6,7 @@ import static java.lang.Math.round; public class CONFIG { - public static final double BULB_VOLTAGE_MIN = 0.5; - - public static final double VOLTAGE = 3.0; + public static final double VOLTAGE_HIGH_MIN = 0.1; public static final int RASTER = 200; diff --git a/src/main/java/de/ph87/electro/circuit/Calculation.java b/src/main/java/de/ph87/electro/circuit/Calculation.java new file mode 100644 index 0000000..252131e --- /dev/null +++ b/src/main/java/de/ph87/electro/circuit/Calculation.java @@ -0,0 +1,216 @@ +package de.ph87.electro.circuit; + +import de.ph87.electro.circuit.part.InnerConnection; +import de.ph87.electro.circuit.part.Junction; +import de.ph87.electro.circuit.part.Part; +import de.ph87.electro.circuit.part.parts.PartBattery; +import de.ph87.electro.circuit.part.parts.PartLight; +import lombok.Getter; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.math3.linear.*; + +import java.util.Collections; +import java.util.List; + +import static java.lang.Math.max; + +@Slf4j +@Getter +public class Calculation { + + private static final double NO_RESISTANCE = 1e-12; + + private static final double FULL_ADMITTANCE = 1 / NO_RESISTANCE; + + private final List junctions; + + private final RealMatrix matrix; + + private final RealVector currents; + + private RealVector potentials = null; + + public Calculation(final int numNodes) { + junctions = Collections.emptyList(); + matrix = new Array2DRowRealMatrix(numNodes, numNodes); + currents = new ArrayRealVector(numNodes); + } + + public Calculation(final Circuit circuit) { + final PartBattery pivot = circuit.streamParts().flatMap(PartBattery::filterCast).findFirst().orElseThrow(RuntimeException::new); + junctions = circuit.streamJunctions().filter(junction -> junction != pivot.getMinus()).toList(); // pivot.minus is GND and cannot be part of the matrix (linear dependency) + matrix = new Array2DRowRealMatrix(junctions.size(), junctions.size()); + currents = new ArrayRealVector(junctions.size()); + fromSchematic(circuit); + solve(); + toSchematic(circuit); + } + + private void fromSchematic(final Circuit circuit) { + circuit.streamWires().forEach( + wire -> addResistor(wire.getA(), wire.getB(), NO_RESISTANCE) + ); + circuit.streamParts().forEach(part -> { + for (final InnerConnection innerConnection : part.getInnerConnections()) { + addResistor(innerConnection.a, innerConnection.b, NO_RESISTANCE); + } + if (part instanceof final PartBattery battery) { + addBattery(battery); + } else if (part instanceof final PartLight light) { + addResistor(light.getA(), light.getB(), light.getResistance()); + } + }); + } + + private void toSchematic(final Circuit circuit) { + circuit.streamJunctions().forEach(junction -> junction.setVoltage(getPotential(junction))); + circuit.streamWires().forEach(wire -> wire.setCurrent(getCurrent(wire))); + circuit.streamParts().forEach(Part::postCalculate); + } + + private double getPotential(final @NonNull Junction junction) { + final int index = getJunctionIndex(junction); + if (index < 0) { + return 0; // per definition + } + if (potentials == null) { + return Double.NaN; + } + return potentials.getEntry(index); + } + + private double getCurrent(final Wire wire) { + final int indexA = getJunctionIndex(wire.getA()); + final int indexB = getJunctionIndex(wire.getB()); + final double conductance = indexA >= 0 && indexB >= 0 ? matrix.getEntry(indexA, indexB) : FULL_ADMITTANCE; + final double potentialDifference = getPotential(wire.getB()) - getPotential(wire.getA()); + return conductance * potentialDifference; + } + + private int getJunctionIndex(@NonNull final Junction junction) { + for (int i = 0; i < junctions.size(); i++) { + if (junctions.get(i) == junction) { + return i; + } + } + return -1; + } + + public void addResistor(final Junction a, final Junction b, final double resistance) { + final int indexA = getJunctionIndex(a); + final int indexB = getJunctionIndex(b); + addResistor(indexA, indexB, resistance); + } + + public void addResistor(final int index0, final int index1, double resistance) { + double conductance = 1.0 / resistance; + if (index0 >= 0) { + matrix.setEntry(index0, index0, matrix.getEntry(index0, index0) + conductance); + } + if (index1 >= 0) { + matrix.setEntry(index1, index1, matrix.getEntry(index1, index1) + conductance); + } + if (index0 >= 0 && index1 >= 0) { + matrix.setEntry(index0, index1, matrix.getEntry(index0, index1) - conductance); + matrix.setEntry(index1, index0, matrix.getEntry(index1, index0) - conductance); + } + potentials = null; + } + + public void addBattery(final PartBattery battery) { + final double current = battery.getVoltage() / battery.getResistance(); + final int indexMinus = getJunctionIndex(battery.getMinus()); + final int indexPlus = getJunctionIndex(battery.getPlus()); + addCurrentSource(indexMinus, indexPlus, current, battery.getResistance()); + } + + public void addCurrentSource(final int index0, final int index1, final double current, final double resistance) { + if (index0 >= 0) { + currents.setEntry(index0, currents.getEntry(index0) - current); + } + if (index1 >= 0) { + currents.setEntry(index1, currents.getEntry(index1) + current); + } + addResistor(index0, index1, resistance); + potentials = null; + } + + public void solve() { + final DecompositionSolver solver = new LUDecomposition(matrix).getSolver(); + try { + potentials = solver.solve(currents); + } catch (SingularMatrixException e) { + potentials = null; + log.error("Schaltung fehlerhaft: {}", e.getMessage()); + } + } + + @Override + public String toString() { + final Format matrixFormat = new Format(matrix); + final Format currentsFormat = new Format(currents); + final Format potentialsFormat = new Format(potentials); + + final StringBuilder builder = new StringBuilder(); + for (int row = 0; row < matrix.getRowDimension(); row++) { + builder.append("["); + String prefix = ""; + for (int c = 0; c < matrix.getColumnDimension(); c++) { + builder.append(prefix); + builder.append(matrixFormat.format(matrix.getEntry(row, c))); + prefix = ", "; + } + + final String potentialString = potentialsFormat.format(potentials.getEntry(row)); + final String currentString = currentsFormat.format(currents.getEntry(row)); + builder.append("] x [%s V] = [%s A]\n".formatted(potentialString, currentString)); + } + return builder.toString(); + } + + @Getter + private static final class Format { + + private int integer; + + private int decimal; + + private final String format; + + public Format(final RealMatrix matrix) { + for (int r = 0; r < matrix.getRowDimension(); r++) { + for (int c = 0; c < matrix.getColumnDimension(); c++) { + append(matrix.getEntry(r, c)); + } + } + format = calculateFormat(); + } + + public Format(final RealVector vector) { + for (int r = 0; r < vector.getDimension(); r++) { + append(vector.getEntry(r)); + } + format = calculateFormat(); + } + + private void append(final double value) { + final String string = "%+f".formatted(value); + final String[] parts = string.split("[.,]"); + integer = max(integer, parts[0].length()); + if (parts.length > 1) { + decimal = max(decimal, parts[1].length()); + } + } + + private String calculateFormat() { + return "%%+%d.%df".formatted(integer + decimal + (decimal > 0 ? 1 : 0), decimal); + } + + public String format(final double value) { + return format.formatted(value); + } + + } + +} \ No newline at end of file diff --git a/src/main/java/de/ph87/electro/circuit/Circuit.java b/src/main/java/de/ph87/electro/circuit/Circuit.java index 8bb6394..b3921c3 100644 --- a/src/main/java/de/ph87/electro/circuit/Circuit.java +++ b/src/main/java/de/ph87/electro/circuit/Circuit.java @@ -4,7 +4,6 @@ import de.ph87.electro.circuit.part.Junction; import de.ph87.electro.circuit.part.Part; import de.ph87.electro.circuit.part.PartDto; import de.ph87.electro.circuit.part.Position; -import de.ph87.electro.circuit.part.parts.PartBattery; import lombok.NoArgsConstructor; import lombok.NonNull; @@ -18,6 +17,8 @@ public class Circuit { private final List parts = new ArrayList<>(); + private final List junctions = new ArrayList<>(); + private final List wires = new ArrayList<>(); public Circuit(final CircuitDto dto) { @@ -41,25 +42,17 @@ public class Circuit { } public void evaluateAndRender() { - parts.forEach(Part::reset); - streamBatteries().forEach(PartBattery::startPropagation); + new Calculation(this); parts.forEach(Part::render); } - private Stream streamBatteries() { - return parts.stream().filter(part -> part instanceof PartBattery).map(part -> (PartBattery) part); - } - - public Stream streamWires() { - return wires.stream(); - } - public T addPart(final T part) { if (parts.contains(part)) { throw new RuntimeException(); } if (isFree(part.getPosition())) { parts.add(part); + junctions.addAll(part.getJunctions()); part.render(); } return part; @@ -82,6 +75,14 @@ public class Circuit { return parts.stream(); } + public Stream streamJunctions() { + return junctions.stream(); + } + + public Stream streamWires() { + return wires.stream(); + } + public int getPartCount() { return parts.size(); } diff --git a/src/main/java/de/ph87/electro/circuit/CircuitPanel.java b/src/main/java/de/ph87/electro/circuit/CircuitPanel.java index b68fc0f..2e27cdf 100644 --- a/src/main/java/de/ph87/electro/circuit/CircuitPanel.java +++ b/src/main/java/de/ph87/electro/circuit/CircuitPanel.java @@ -1,6 +1,8 @@ package de.ph87.electro.circuit; import de.ph87.electro.circuit.part.Position; +import de.ph87.electro.circuit.part.parts.PartBattery; +import de.ph87.electro.circuit.part.parts.PartLight; import javax.swing.*; import java.awt.*; @@ -15,6 +17,19 @@ public class CircuitPanel extends JPanel { public CircuitPanel() { new CircuitPanelDropTarget(this, circuit); + final PartBattery battery = circuit.addPart(new PartBattery(Position.ofRaster(1, 0))); + + final PartLight light0 = circuit.addPart(new PartLight(Position.ofRaster(0, 2))); + light0.clockwise(); + + final PartLight light1 = circuit.addPart(new PartLight(Position.ofRaster(1, 2))); + light1.clockwise(); + light1.clockwise(); + light1.clockwise(); + + circuit.connect(battery.getMinus(), light0.getA()); + circuit.connect(light0.getB(), light1.getA()); + circuit.connect(light1.getB(), battery.getPlus()); } @Override @@ -51,13 +66,7 @@ public class CircuitPanel extends JPanel { } private void drawWires(final Graphics2D g) { - circuit.streamWires().forEach(wire -> { - final Position a = wire.getA().getPosition(); - final Position b = wire.getB().getPosition(); - g.setColor(wire.getA().getColor()); - g.setStroke(WIRE_STROKE); - g.drawLine(a.absolute.x, a.absolute.y, b.absolute.x, b.absolute.y); - }); + circuit.streamWires().forEach(wire -> wire.draw(g)); } } diff --git a/src/main/java/de/ph87/electro/circuit/Wire.java b/src/main/java/de/ph87/electro/circuit/Wire.java index d88b2e3..f100417 100644 --- a/src/main/java/de/ph87/electro/circuit/Wire.java +++ b/src/main/java/de/ph87/electro/circuit/Wire.java @@ -2,18 +2,33 @@ package de.ph87.electro.circuit; import de.ph87.electro.circuit.part.Junction; import de.ph87.electro.circuit.part.Position; -import lombok.Data; +import lombok.Getter; import lombok.NonNull; +import lombok.Setter; +import lombok.ToString; -@Data +import java.awt.*; +import java.awt.geom.Rectangle2D; + +import static de.ph87.electro.CONFIG.LABEL_FONT; +import static de.ph87.electro.CONFIG.WIRE_STROKE; +import static java.lang.Math.abs; +import static java.lang.Math.round; + +@ToString public class Wire { + @Getter @NonNull private final Junction a; + @Getter @NonNull private final Junction b; + @Setter + private double current = Double.NaN; + public Wire(@NonNull final Junction a, @NonNull final Junction b) { this.a = a; this.b = b; @@ -34,4 +49,34 @@ public class Wire { throw new RuntimeException(); } + public double getCurrent(final Junction junction) { + return junction == a ? current : -current; + } + + public void draw(final Graphics2D g) { + g.setColor(a.getColor()); + g.setStroke(WIRE_STROKE); + g.drawLine(a.getPosition().absolute.x, a.getPosition().absolute.y, b.getPosition().absolute.x, b.getPosition().absolute.y); + + drawValues(g, "%.2f A".formatted(abs(current)), -0.5); + drawValues(g, "%.2f V".formatted(a.getVoltage()), +0.5); + } + + private void drawValues(final Graphics2D g, final String string, final double offset) { + g.setFont(LABEL_FONT); + final Rectangle2D bounds = g.getFontMetrics().getStringBounds(string, g); + final int mx = (a.getPosition().absolute.x + b.getPosition().absolute.x) / 2; + final int my = (a.getPosition().absolute.y + b.getPosition().absolute.y) / 2; + + final int bx = (int) round((mx - bounds.getWidth() / 2)) - 2; + final int by = (int) round((my - bounds.getHeight() / 2) + offset * bounds.getHeight()) - 2; + g.setColor(new Color(255, 255, 255, 200)); + g.fillRect(bx, by, (int) round(bounds.getWidth()) + 4, (int) round(bounds.getHeight()) + 4); + + final int sx = (int) round((mx - bounds.getWidth() / 2)); + final int sy = (int) round(my + bounds.getHeight() / 3 + offset * bounds.getHeight()); + g.setColor(a.getColor()); + g.drawString(string, sx, sy); + } + } diff --git a/src/main/java/de/ph87/electro/circuit/part/InnerConnection.java b/src/main/java/de/ph87/electro/circuit/part/InnerConnection.java new file mode 100644 index 0000000..b678a1d --- /dev/null +++ b/src/main/java/de/ph87/electro/circuit/part/InnerConnection.java @@ -0,0 +1,14 @@ +package de.ph87.electro.circuit.part; + +public class InnerConnection { + + public final Junction a; + + public final Junction b; + + public InnerConnection(final Junction a, final Junction b) { + this.a = a; + this.b = b; + } + +} diff --git a/src/main/java/de/ph87/electro/circuit/part/Junction.java b/src/main/java/de/ph87/electro/circuit/part/Junction.java index d81c7b3..b9cf002 100644 --- a/src/main/java/de/ph87/electro/circuit/part/Junction.java +++ b/src/main/java/de/ph87/electro/circuit/part/Junction.java @@ -1,9 +1,7 @@ package de.ph87.electro.circuit.part; -import de.ph87.electro.circuit.ShortCircuit; import de.ph87.electro.circuit.Wire; import lombok.Getter; -import lombok.Setter; import lombok.ToString; import java.awt.*; @@ -32,7 +30,6 @@ public class Junction { private final Set wires = new HashSet<>(); - @Setter @ToString.Include private double voltage = Double.NaN; @@ -60,31 +57,9 @@ public class Junction { updatePosition(); } - public void reset() { - voltage = Double.NaN; - color = VOLTAGE_UNKNOWN_COLOR; - } - - public void propagate(final double newVoltage) throws ShortCircuit { - if (voltage == newVoltage) { - return; - } - if (Double.isNaN(voltage)) { - voltage = newVoltage; - if (Double.isNaN(voltage)) { - color = Color.GRAY; - } else if (voltage > 0) { - color = VOLTAGE_HIGH_COLOR; - } else { - color = VOLTAGE_LOW_COLOR; - } - owner.propagate(this); - for (Wire wire : wires) { - wire.getOpposite(this).propagate(newVoltage); - } - return; - } - throw new ShortCircuit(); + public void setVoltage(final double voltage) { + this.voltage = voltage; + this.color = Double.isNaN(voltage) ? VOLTAGE_UNKNOWN_COLOR : ((voltage >= VOLTAGE_HIGH_MIN) ? VOLTAGE_HIGH_COLOR : VOLTAGE_LOW_COLOR); } public void render(final Render g) { diff --git a/src/main/java/de/ph87/electro/circuit/part/Part.java b/src/main/java/de/ph87/electro/circuit/part/Part.java index 69f408a..b875772 100644 --- a/src/main/java/de/ph87/electro/circuit/part/Part.java +++ b/src/main/java/de/ph87/electro/circuit/part/Part.java @@ -1,16 +1,13 @@ package de.ph87.electro.circuit.part; -import de.ph87.electro.circuit.ShortCircuit; import de.ph87.electro.circuit.part.parts.*; import lombok.Getter; import lombok.Setter; import lombok.ToString; import java.awt.*; -import java.util.ArrayList; import java.util.List; -import java.util.Optional; -import java.util.UUID; +import java.util.*; import static de.ph87.electro.CONFIG.PART_BACKGROUND; import static de.ph87.electro.CONFIG.RASTER; @@ -29,17 +26,16 @@ public abstract class Part { private Position position; - private Orientation orientation; + private Orientation orientation = Orientation.R0; private final List junctions = new ArrayList<>(); protected final Render render = new Render(); - protected Part(final String name, final Position position, final Orientation orientation) { + protected Part(final String name, final Position position) { this.uuid = UUID.randomUUID().toString(); this.name = name; setPosition(position); - this.orientation = orientation; } protected Part(final PartDto dto) { @@ -73,10 +69,6 @@ public abstract class Part { render(); } - public void reset() { - junctions.forEach(Junction::reset); - } - public void render() { render.rect(ZERO, RASTER, RASTER, null, null, PART_BACKGROUND); @@ -106,7 +98,7 @@ public abstract class Part { // may be overwritten } - public void propagate(final Junction source) throws ShortCircuit { + public void postCalculate() { // may be overwritten } @@ -132,4 +124,8 @@ public abstract class Part { }; } + public List getInnerConnections() { + return Collections.emptyList(); + } + } diff --git a/src/main/java/de/ph87/electro/circuit/part/PartOther.java b/src/main/java/de/ph87/electro/circuit/part/PartOther.java index e8cc319..1af6d26 100644 --- a/src/main/java/de/ph87/electro/circuit/part/PartOther.java +++ b/src/main/java/de/ph87/electro/circuit/part/PartOther.java @@ -2,8 +2,8 @@ package de.ph87.electro.circuit.part; public abstract class PartOther extends Part { - protected PartOther(final String name, final Position position, final Orientation orientation) { - super(name, position, orientation); + protected PartOther(final String name, final Position position) { + super(name, position); } protected PartOther(final PartDto dto) { diff --git a/src/main/java/de/ph87/electro/circuit/part/Position.java b/src/main/java/de/ph87/electro/circuit/part/Position.java index a95b7ed..a04e8f5 100644 --- a/src/main/java/de/ph87/electro/circuit/part/Position.java +++ b/src/main/java/de/ph87/electro/circuit/part/Position.java @@ -28,6 +28,10 @@ public final class Position { this.inside = new Point(x % RASTER, y % RASTER); } + public static Position ofRaster(final int x, final int y) { + return new Position(x * RASTER, y * RASTER); + } + @Override public int hashCode() { return absolute.hashCode(); diff --git a/src/main/java/de/ph87/electro/circuit/part/Render.java b/src/main/java/de/ph87/electro/circuit/part/Render.java index 02e3cb5..d392102 100644 --- a/src/main/java/de/ph87/electro/circuit/part/Render.java +++ b/src/main/java/de/ph87/electro/circuit/part/Render.java @@ -61,11 +61,13 @@ public class Render { } } - public void textCenter(final Font font, final String string, final int y, final Color color) { + public void textCenter(final Font font, final String string, final int innerX, final int innerY, final Color color) { g.setFont(font); g.setColor(color); final Rectangle2D bounds = g.getFontMetrics().getStringBounds(string, g); - g.drawString(string, (int) round(RASTER - bounds.getWidth()) / 2, y + g.getFont().getSize()); + final int x = innerX - (int) round(bounds.getWidth()) / 2; + final int y = innerY + (int) round(bounds.getHeight()) / 2; + g.drawString(string, x, y); } public void clockwise(final Orientation orientation) { diff --git a/src/main/java/de/ph87/electro/circuit/part/parts/PartBattery.java b/src/main/java/de/ph87/electro/circuit/part/parts/PartBattery.java index 3ab076d..f2f4e58 100644 --- a/src/main/java/de/ph87/electro/circuit/part/parts/PartBattery.java +++ b/src/main/java/de/ph87/electro/circuit/part/parts/PartBattery.java @@ -1,6 +1,5 @@ package de.ph87.electro.circuit.part.parts; -import de.ph87.electro.circuit.ShortCircuit; import de.ph87.electro.circuit.part.Junction; import de.ph87.electro.circuit.part.Orientation; import de.ph87.electro.circuit.part.Part; @@ -10,11 +9,12 @@ import lombok.Setter; import lombok.ToString; import java.awt.*; +import java.util.stream.Stream; import static de.ph87.electro.CONFIG.*; @Getter -@ToString(callSuper = true) +@ToString(callSuper = true, onlyExplicitlyIncluded = true) public class PartBattery extends Part { private static final double MINUS_W = 0.1 * RASTER; @@ -32,24 +32,21 @@ public class PartBattery extends Part { private final Junction plus; @Setter - private double voltage; + @ToString.Include + private double voltage = 3; - private ShortCircuit shortCircuit = null; + @Setter + @ToString.Include + private double resistance = 0.05; public PartBattery() { this(Position.ZERO); } public PartBattery(final Position position) { - this("Batterie", position, Orientation.R0, VOLTAGE); - } - - public PartBattery(final String name, final Position position, final Orientation orientation, final double initialVoltage) { - super(name, position, orientation); - minus = newJunction(this, "-", P10, P50); - plus = newJunction(this, "+", P90, P50); - voltage = initialVoltage; - startPropagation(); + super("Batterie", position); + minus = newJunction(this, "PLUS", P10, P50); + plus = newJunction(this, "MINUS", P90, P50); } public PartBattery(final PartBatteryDto dto) { @@ -57,17 +54,6 @@ public class PartBattery extends Part { minus = newJunction(this, dto.getMinus(), P10, P50); plus = newJunction(this, dto.getPlus(), P90, P50); voltage = dto.getVoltage(); - startPropagation(); - } - - public void startPropagation() { - try { - shortCircuit = null; - minus.propagate(0); - plus.propagate(voltage); - } catch (ShortCircuit e) { - shortCircuit = e; - } } @Override @@ -81,20 +67,22 @@ public class PartBattery extends Part { @Override protected void _labels() { + final int x = RASTER / 2; final int y0; - final int y1; if (getOrientation() == Orientation.R180) { y0 = P95 - LABEL_FONT.getSize(); - y1 = P05; } else { render.clockwise(getOrientation()); y0 = P05; - y1 = P95 - LABEL_FONT.getSize(); } - render.textCenter(LABEL_FONT, "%.1fV".formatted(voltage), y0, Color.BLACK); - if (shortCircuit != null) { - render.textCenter(LABEL_FONT, "KURZSCHLUSS", y1, Color.RED); + render.textCenter(LABEL_FONT, "%.1fV".formatted(voltage), x, y0, Color.BLACK); + } + + public static Stream filterCast(final Part part) { + if (part instanceof final PartBattery battery) { + return Stream.of(battery); } + return Stream.empty(); } } diff --git a/src/main/java/de/ph87/electro/circuit/part/parts/PartJunctionCorner.java b/src/main/java/de/ph87/electro/circuit/part/parts/PartJunctionCorner.java index 182d2a2..9042d78 100644 --- a/src/main/java/de/ph87/electro/circuit/part/parts/PartJunctionCorner.java +++ b/src/main/java/de/ph87/electro/circuit/part/parts/PartJunctionCorner.java @@ -1,13 +1,13 @@ package de.ph87.electro.circuit.part.parts; import de.ph87.electro.circuit.part.Junction; -import de.ph87.electro.circuit.part.Orientation; import de.ph87.electro.circuit.part.PartOther; import de.ph87.electro.circuit.part.Position; import lombok.Getter; import lombok.ToString; -import static de.ph87.electro.CONFIG.*; +import static de.ph87.electro.CONFIG.P10; +import static de.ph87.electro.CONFIG.P90; @Getter @ToString(callSuper = true) @@ -22,13 +22,9 @@ public class PartJunctionCorner extends PartOther { } public PartJunctionCorner(final Position position) { - this("", position, Orientation.R0); - } - - public PartJunctionCorner(final String name, final Position position, final Orientation orientation) { - super(name, position, orientation); - j0 = newJunction(this, "", P10, P10); - j1 = newJunction(this, "", P90, P90); + super("", position); + j0 = newJunction(this, "J0", P10, P10); + j1 = newJunction(this, "J1", P90, P90); } public PartJunctionCorner(final PartJunctionCornerDto dto) { diff --git a/src/main/java/de/ph87/electro/circuit/part/parts/PartJunctionEdge.java b/src/main/java/de/ph87/electro/circuit/part/parts/PartJunctionEdge.java index 1a42612..bed17e6 100644 --- a/src/main/java/de/ph87/electro/circuit/part/parts/PartJunctionEdge.java +++ b/src/main/java/de/ph87/electro/circuit/part/parts/PartJunctionEdge.java @@ -1,14 +1,13 @@ package de.ph87.electro.circuit.part.parts; import de.ph87.electro.circuit.part.Junction; -import de.ph87.electro.circuit.part.Orientation; import de.ph87.electro.circuit.part.PartOther; import de.ph87.electro.circuit.part.Position; import lombok.Getter; import lombok.ToString; -import static de.ph87.electro.CONFIG.P50; import static de.ph87.electro.CONFIG.P10; +import static de.ph87.electro.CONFIG.P50; @Getter @ToString(callSuper = true) @@ -23,13 +22,9 @@ public class PartJunctionEdge extends PartOther { } public PartJunctionEdge(final Position position) { - this("", position, Orientation.R0); - } - - public PartJunctionEdge(final String name, final Position position, final Orientation orientation) { - super(name, position, orientation); - j0 = newJunction(this, "", P10, P50); - j1 = newJunction(this, "", P50, P10); + super("", position); + j0 = newJunction(this, "J0", P10, P50); + j1 = newJunction(this, "J1", P50, P10); } public PartJunctionEdge(final PartJunctionEdgeDto dto) { diff --git a/src/main/java/de/ph87/electro/circuit/part/parts/PartJunctionMiddle.java b/src/main/java/de/ph87/electro/circuit/part/parts/PartJunctionMiddle.java index 0e33035..156ce9b 100644 --- a/src/main/java/de/ph87/electro/circuit/part/parts/PartJunctionMiddle.java +++ b/src/main/java/de/ph87/electro/circuit/part/parts/PartJunctionMiddle.java @@ -1,7 +1,6 @@ package de.ph87.electro.circuit.part.parts; import de.ph87.electro.circuit.part.Junction; -import de.ph87.electro.circuit.part.Orientation; import de.ph87.electro.circuit.part.PartOther; import de.ph87.electro.circuit.part.Position; import lombok.Getter; @@ -20,12 +19,8 @@ public class PartJunctionMiddle extends PartOther { } public PartJunctionMiddle(final Position position) { - this("", position, Orientation.R0); - } - - public PartJunctionMiddle(final String name, final Position position, final Orientation orientation) { - super(name, position, orientation); - junction = newJunction(this, "", P50, P50); + super("", position); + junction = newJunction(this, "J", P50, P50); } public PartJunctionMiddle(final PartJunctionMiddleDto dto) { diff --git a/src/main/java/de/ph87/electro/circuit/part/parts/PartLight.java b/src/main/java/de/ph87/electro/circuit/part/parts/PartLight.java index 047e734..83ca3b4 100644 --- a/src/main/java/de/ph87/electro/circuit/part/parts/PartLight.java +++ b/src/main/java/de/ph87/electro/circuit/part/parts/PartLight.java @@ -33,17 +33,19 @@ public class PartLight extends PartOther { private static final Color BULB_OFF_COLOR = Color.DARK_GRAY; - private final Junction pin0; + private final Junction a; - private final Junction pin1; + private final Junction b; - private final double minVoltage; + private double resistance = 15; - private final double maxVoltage; + private double minVoltage = 1; + + private double maxVoltage = 3; private boolean defect = false; - private double voltage = 0; + private double potentialDifference = Double.NaN; private Color color = BULB_OFF_COLOR; @@ -52,21 +54,16 @@ public class PartLight extends PartOther { } public PartLight(final Position position) { - this("Licht", position, Orientation.R0, BULB_VOLTAGE_MIN, VOLTAGE); - } - - public PartLight(final String name, final Position position, final Orientation orientation, final double minVoltage, final double maxVoltage) { - super(name, position, orientation); - this.minVoltage = minVoltage; - this.maxVoltage = maxVoltage; - pin0 = newJunction(this, "", P10, P50); - pin1 = newJunction(this, "", P90, P50); + super("Licht", position); + a = newJunction(this, "A", P10, P50); + b = newJunction(this, "B", P90, P50); } public PartLight(final PartLightDto dto) { super(dto); - pin0 = newJunction(this, dto.getMinus(), P10, P50); - pin1 = newJunction(this, dto.getPlus(), P90, P50); + a = newJunction(this, dto.getB(), P10, P50); + b = newJunction(this, dto.getA(), P90, P50); + resistance = dto.getResistance(); minVoltage = dto.getMinVoltage(); maxVoltage = dto.getMaxVoltage(); defect = dto.isDefect(); @@ -78,26 +75,20 @@ public class PartLight extends PartOther { } @Override - public void propagate(final Junction source) { - voltage = abs(pin1.getVoltage() - pin0.getVoltage()); - if (voltage > maxVoltage) { - defect = true; - } - if (defect) { - color = COLOR_DEFECT; + public void postCalculate() { + potentialDifference = abs(b.getVoltage() - a.getVoltage()); + defect |= potentialDifference > maxVoltage; + if (defect || potentialDifference < minVoltage) { + color = BULB_OFF_COLOR; } else { - final int v = (int) round(voltage / maxVoltage * 255); - if (v < 10) { - color = BULB_OFF_COLOR; - } else { - color = new Color(v, v, 0); - } + final int c = (int) round(255 * potentialDifference / maxVoltage); + color = new Color(c, c, 0); } } @Override protected void _render() { - render.line(pin0, pin1, Color.BLACK, SYMBOL_STROKE); + render.line(a, b, Color.BLACK, SYMBOL_STROKE); render.circle(new Position(P50, P50), BULB_RADIUS, Color.BLACK, SYMBOL_STROKE, color); final double diag = 0.33 * RASTER; @@ -107,6 +98,7 @@ public class PartLight extends PartOther { @Override protected void _labels() { + final int x = RASTER / 2; final int y0; final int y1; if (getOrientation() == Orientation.R180) { @@ -117,9 +109,9 @@ public class PartLight extends PartOther { y0 = P05; y1 = P95 - LABEL_FONT.getSize(); } - render.textCenter(LABEL_FONT, "%.1fV (max)".formatted(maxVoltage), y0, Color.BLACK); + render.textCenter(LABEL_FONT, "%.1fV (max)".formatted(maxVoltage), x, y0, Color.BLACK); if (defect) { - render.textCenter(LABEL_FONT, "DEFEKT", y1, Color.RED); + render.textCenter(LABEL_FONT, "DEFEKT", x, y1, Color.RED); } } diff --git a/src/main/java/de/ph87/electro/circuit/part/parts/PartLightDto.java b/src/main/java/de/ph87/electro/circuit/part/parts/PartLightDto.java index 347acd9..ef87e48 100644 --- a/src/main/java/de/ph87/electro/circuit/part/parts/PartLightDto.java +++ b/src/main/java/de/ph87/electro/circuit/part/parts/PartLightDto.java @@ -11,9 +11,11 @@ import lombok.ToString; @NoArgsConstructor public class PartLightDto extends PartDto { - private JunctionDto plus; + private JunctionDto a; - private JunctionDto minus; + private JunctionDto b; + + private double resistance; private double minVoltage; @@ -23,9 +25,10 @@ public class PartLightDto extends PartDto { public PartLightDto(final PartLight partLight) { super(partLight); - this.plus = new JunctionDto(partLight.getPin1()); - this.minus = new JunctionDto(partLight.getPin0()); + this.a = new JunctionDto(partLight.getB()); + this.b = new JunctionDto(partLight.getA()); this.defect = partLight.isDefect(); + this.resistance = partLight.getResistance(); this.minVoltage = partLight.getMinVoltage(); this.maxVoltage = partLight.getMaxVoltage(); } diff --git a/src/main/java/de/ph87/electro/circuit/part/parts/PartSwitch1x1.java b/src/main/java/de/ph87/electro/circuit/part/parts/PartSwitch1x1.java index a46b2f7..9868f2b 100644 --- a/src/main/java/de/ph87/electro/circuit/part/parts/PartSwitch1x1.java +++ b/src/main/java/de/ph87/electro/circuit/part/parts/PartSwitch1x1.java @@ -1,8 +1,7 @@ package de.ph87.electro.circuit.part.parts; -import de.ph87.electro.circuit.ShortCircuit; +import de.ph87.electro.circuit.part.InnerConnection; import de.ph87.electro.circuit.part.Junction; -import de.ph87.electro.circuit.part.Orientation; import de.ph87.electro.circuit.part.PartOther; import de.ph87.electro.circuit.part.Position; import lombok.Getter; @@ -10,6 +9,7 @@ import lombok.Setter; import lombok.ToString; import java.awt.*; +import java.util.List; import static de.ph87.electro.CONFIG.*; @@ -22,21 +22,16 @@ public class PartSwitch1x1 extends PartOther { private final Junction output; @Setter - private boolean state; + private boolean state = false; public PartSwitch1x1() { this(Position.ZERO); } public PartSwitch1x1(final Position position) { - this("Ausschalter", position, Orientation.R0, false); - } - - public PartSwitch1x1(final String name, final Position position, final Orientation orientation, final boolean state) { - super(name, position, orientation); - common = newJunction(this, "", P10, P50); - output = newJunction(this, "", P90, P50); - this.state = state; + super("Ausschalter", position); + common = newJunction(this, "C", P10, P50); + output = newJunction(this, "O", P90, P50); } public PartSwitch1x1(final PartSwitch1x1Dto dto) { @@ -51,19 +46,6 @@ public class PartSwitch1x1 extends PartOther { state = !state; } - @Override - public void propagate(final Junction source) throws ShortCircuit { - if (source == common) { - if (state) { - output.propagate(source.getVoltage()); - } - } else if (source == output) { - if (state) { - common.propagate(source.getVoltage()); - } - } - } - @Override protected void _render() { if (!state) { @@ -74,4 +56,12 @@ public class PartSwitch1x1 extends PartOther { } } + @Override + public List getInnerConnections() { + if (state) { + return List.of(new InnerConnection(common, output)); + } + return super.getInnerConnections(); + } + } diff --git a/src/main/java/de/ph87/electro/circuit/part/parts/PartSwitch1x2.java b/src/main/java/de/ph87/electro/circuit/part/parts/PartSwitch1x2.java index 73d1a84..fbbff21 100644 --- a/src/main/java/de/ph87/electro/circuit/part/parts/PartSwitch1x2.java +++ b/src/main/java/de/ph87/electro/circuit/part/parts/PartSwitch1x2.java @@ -1,14 +1,15 @@ package de.ph87.electro.circuit.part.parts; -import de.ph87.electro.circuit.ShortCircuit; +import de.ph87.electro.circuit.part.InnerConnection; import de.ph87.electro.circuit.part.Junction; -import de.ph87.electro.circuit.part.Orientation; import de.ph87.electro.circuit.part.PartOther; import de.ph87.electro.circuit.part.Position; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import java.util.List; + import static de.ph87.electro.CONFIG.*; @Getter @@ -22,22 +23,17 @@ public class PartSwitch1x2 extends PartOther { private final Junction output1; @Setter - private boolean state; + private boolean state = false; public PartSwitch1x2() { this(Position.ZERO); } public PartSwitch1x2(final Position position) { - this("Wechselschalter", position, Orientation.R0, false); - } - - public PartSwitch1x2(final String name, final Position position, final Orientation orientation, final boolean state) { - super(name, position, orientation); - common = newJunction(this, "", P10, P50); - output0 = newJunction(this, "", P90, P25); - output1 = newJunction(this, "", P90, P75); - this.state = state; + super("Wechselschalter", position); + common = newJunction(this, "C", P10, P50); + output0 = newJunction(this, "O0", P90, P25); + output1 = newJunction(this, "O1", P90, P75); } public PartSwitch1x2(final PartSwitch1x2Dto dto) { @@ -53,25 +49,6 @@ public class PartSwitch1x2 extends PartOther { state = !state; } - @Override - public void propagate(final Junction source) throws ShortCircuit { - if (source == common) { - if (state) { - output1.propagate(source.getVoltage()); - } else { - output0.propagate(source.getVoltage()); - } - } else if (source == output0) { - if (!state) { - common.propagate(source.getVoltage()); - } - } else if (source == output1) { - if (state) { - common.propagate(source.getVoltage()); - } - } - } - @Override protected void _render() { if (!state) { @@ -81,4 +58,12 @@ public class PartSwitch1x2 extends PartOther { } } + @Override + public List getInnerConnections() { + if (state) { + return List.of(new InnerConnection(common, output1)); + } + return List.of(new InnerConnection(common, output0)); + } + } diff --git a/src/main/java/de/ph87/electro/circuit/part/parts/PartSwitchCross.java b/src/main/java/de/ph87/electro/circuit/part/parts/PartSwitchCross.java index 9bff9ea..78fbf76 100644 --- a/src/main/java/de/ph87/electro/circuit/part/parts/PartSwitchCross.java +++ b/src/main/java/de/ph87/electro/circuit/part/parts/PartSwitchCross.java @@ -1,14 +1,15 @@ package de.ph87.electro.circuit.part.parts; -import de.ph87.electro.circuit.ShortCircuit; +import de.ph87.electro.circuit.part.InnerConnection; import de.ph87.electro.circuit.part.Junction; -import de.ph87.electro.circuit.part.Orientation; import de.ph87.electro.circuit.part.PartOther; import de.ph87.electro.circuit.part.Position; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import java.util.List; + import static de.ph87.electro.CONFIG.*; @Getter @@ -24,23 +25,18 @@ public class PartSwitchCross extends PartOther { private final Junction output1; @Setter - private boolean state; + private boolean state = false; public PartSwitchCross() { this(Position.ZERO); } public PartSwitchCross(final Position position) { - this("Kreuzschalter", position, Orientation.R0, false); - } - - public PartSwitchCross(final String name, final Position position, final Orientation orientation, final boolean state) { - super(name, position, orientation); - common0 = newJunction(this, "", P10, P25); - common1 = newJunction(this, "", P10, P75); - output0 = newJunction(this, "", P90, P25); - output1 = newJunction(this, "", P90, P75); - this.state = state; + super("Kreuzschalter", position); + common0 = newJunction(this, "C0", P10, P25); + common1 = newJunction(this, "C1", P10, P75); + output0 = newJunction(this, "O0", P90, P25); + output1 = newJunction(this, "O1", P90, P75); } public PartSwitchCross(final PartSwitchCrossDto dto) { @@ -57,35 +53,6 @@ public class PartSwitchCross extends PartOther { state = !state; } - @Override - public void propagate(final Junction source) throws ShortCircuit { - if (source == common0) { - if (state) { - output1.propagate(source.getVoltage()); - } else { - output0.propagate(source.getVoltage()); - } - } else if (source == common1) { - if (state) { - output0.propagate(source.getVoltage()); - } else { - output1.propagate(source.getVoltage()); - } - } else if (source == output0) { - if (state) { - common1.propagate(source.getVoltage()); - } else { - common0.propagate(source.getVoltage()); - } - } else if (source == output1) { - if (state) { - common0.propagate(source.getVoltage()); - } else { - common1.propagate(source.getVoltage()); - } - } - } - @Override protected void _render() { if (!state) { @@ -97,4 +64,18 @@ public class PartSwitchCross extends PartOther { } } + @Override + public List getInnerConnections() { + if (state) { + return List.of( + new InnerConnection(common0, output1), + new InnerConnection(common1, output0) + ); + } + return List.of( + new InnerConnection(common0, output0), + new InnerConnection(common1, output1) + ); + } + } diff --git a/src/test/java/de/ph87/electro/circuit/BatteryLightTest.java b/src/test/java/de/ph87/electro/circuit/BatteryLightTest.java index 40fb658..1fde19a 100644 --- a/src/test/java/de/ph87/electro/circuit/BatteryLightTest.java +++ b/src/test/java/de/ph87/electro/circuit/BatteryLightTest.java @@ -12,27 +12,27 @@ public class BatteryLightTest { private static final double VOLTAGE = 3; - private static final Circuit circuit = new Circuit(); + private static final Circuit CIRCUIT = new Circuit(); - private static final PartBattery battery = circuit.addPart(new PartBattery()); + private static final PartBattery battery = CIRCUIT.addPart(new PartBattery()); - private static final PartLight light = circuit.addPart(new PartLight()); + private static final PartLight light = CIRCUIT.addPart(new PartLight()); @BeforeAll public static void setUp() { - circuit.connect(battery.getPlus(), light.getPin1()); - circuit.connect(light.getPin0(), battery.getMinus()); + CIRCUIT.connect(battery.getPlus(), light.getB()); + CIRCUIT.connect(light.getA(), battery.getMinus()); } @Test void test() { - circuit.evaluateAndRender(); + CIRCUIT.evaluateAndRender(); assertEquals(VOLTAGE, battery.getPlus().getVoltage()); - assertEquals(VOLTAGE, light.getPin1().getVoltage()); - assertEquals(VOLTAGE, light.getVoltage()); + assertEquals(VOLTAGE, light.getB().getVoltage()); + assertEquals(VOLTAGE, light.getPotentialDifference()); - assertEquals(0, light.getPin0().getVoltage()); + assertEquals(0, light.getA().getVoltage()); assertEquals(0, battery.getMinus().getVoltage()); assertFalse(light.isDefect()); diff --git a/src/test/java/de/ph87/electro/circuit/BatterySwitcher1x1Test.java b/src/test/java/de/ph87/electro/circuit/BatterySwitcher1x1Test.java index 384fca6..10d742b 100644 --- a/src/test/java/de/ph87/electro/circuit/BatterySwitcher1x1Test.java +++ b/src/test/java/de/ph87/electro/circuit/BatterySwitcher1x1Test.java @@ -13,19 +13,19 @@ public class BatterySwitcher1x1Test { private static final double VOLTAGE = 3; - private static final Circuit circuit = new Circuit(); + private static final Circuit CIRCUIT = new Circuit(); - private static final PartBattery battery = circuit.addPart(new PartBattery()); + private static final PartBattery battery = CIRCUIT.addPart(new PartBattery()); - private static final PartSwitch1x1 switcher = circuit.addPart(new PartSwitch1x1()); + private static final PartSwitch1x1 switcher = CIRCUIT.addPart(new PartSwitch1x1()); - private static final PartLight light = circuit.addPart(new PartLight()); + private static final PartLight light = CIRCUIT.addPart(new PartLight()); @BeforeAll public static void setUp() { - circuit.connect(battery.getPlus(), switcher.getCommon()); - circuit.connect(switcher.getOutput(), light.getPin1()); - circuit.connect(light.getPin0(), battery.getMinus()); + CIRCUIT.connect(battery.getPlus(), switcher.getCommon()); + CIRCUIT.connect(switcher.getOutput(), light.getB()); + CIRCUIT.connect(light.getA(), battery.getMinus()); } @Test @@ -43,7 +43,7 @@ public class BatterySwitcher1x1Test { switcher.setState(state); - circuit.evaluateAndRender(); + CIRCUIT.evaluateAndRender(); assertEquals(state, switcher.isState()); @@ -51,10 +51,10 @@ public class BatterySwitcher1x1Test { assertEquals(VOLTAGE, switcher.getCommon().getVoltage()); assertEquals(voltage, switcher.getOutput().getVoltage()); - assertEquals(voltage, light.getPin1().getVoltage()); - assertEquals(voltage, light.getVoltage()); + assertEquals(voltage, light.getB().getVoltage()); + assertEquals(voltage, light.getPotentialDifference()); - assertEquals(0, light.getPin0().getVoltage()); + assertEquals(0, light.getA().getVoltage()); assertEquals(0, battery.getMinus().getVoltage()); assertFalse(light.isDefect()); diff --git a/src/test/java/de/ph87/electro/circuit/BatterySwitcher1x2Test.java b/src/test/java/de/ph87/electro/circuit/BatterySwitcher1x2Test.java index ea58162..893fadf 100644 --- a/src/test/java/de/ph87/electro/circuit/BatterySwitcher1x2Test.java +++ b/src/test/java/de/ph87/electro/circuit/BatterySwitcher1x2Test.java @@ -13,23 +13,23 @@ public class BatterySwitcher1x2Test { private static final double VOLTAGE = 3; - private static final Circuit circuit = new Circuit(); + private static final Circuit CIRCUIT = new Circuit(); - private static final PartBattery battery = circuit.addPart(new PartBattery()); + private static final PartBattery battery = CIRCUIT.addPart(new PartBattery()); - private static final PartSwitch1x2 switcher = circuit.addPart(new PartSwitch1x2()); + private static final PartSwitch1x2 switcher = CIRCUIT.addPart(new PartSwitch1x2()); - private static final PartLight light0 = circuit.addPart(new PartLight()); + private static final PartLight light0 = CIRCUIT.addPart(new PartLight()); - private static final PartLight light1 = circuit.addPart(new PartLight()); + private static final PartLight light1 = CIRCUIT.addPart(new PartLight()); @BeforeAll public static void setUp() { - circuit.connect(battery.getPlus(), switcher.getCommon()); - circuit.connect(switcher.getOutput0(), light0.getPin1()); - circuit.connect(light0.getPin0(), battery.getMinus()); - circuit.connect(switcher.getOutput1(), light1.getPin1()); - circuit.connect(light1.getPin0(), battery.getMinus()); + CIRCUIT.connect(battery.getPlus(), switcher.getCommon()); + CIRCUIT.connect(switcher.getOutput0(), light0.getB()); + CIRCUIT.connect(light0.getA(), battery.getMinus()); + CIRCUIT.connect(switcher.getOutput1(), light1.getB()); + CIRCUIT.connect(light1.getA(), battery.getMinus()); } @Test @@ -48,7 +48,7 @@ public class BatterySwitcher1x2Test { switcher.setState(state); - circuit.evaluateAndRender(); + CIRCUIT.evaluateAndRender(); assertEquals(state, switcher.isState()); @@ -56,15 +56,15 @@ public class BatterySwitcher1x2Test { assertEquals(VOLTAGE, switcher.getCommon().getVoltage()); assertEquals(voltage0, switcher.getOutput0().getVoltage()); - assertEquals(voltage0, light0.getPin1().getVoltage()); - assertEquals(voltage0, light0.getVoltage()); + assertEquals(voltage0, light0.getB().getVoltage()); + assertEquals(voltage0, light0.getPotentialDifference()); assertEquals(voltage1, switcher.getOutput1().getVoltage()); - assertEquals(voltage1, light1.getPin1().getVoltage()); - assertEquals(voltage1, light1.getVoltage()); + assertEquals(voltage1, light1.getB().getVoltage()); + assertEquals(voltage1, light1.getPotentialDifference()); - assertEquals(0, light0.getPin0().getVoltage()); - assertEquals(0, light1.getPin0().getVoltage()); + assertEquals(0, light0.getA().getVoltage()); + assertEquals(0, light1.getA().getVoltage()); assertEquals(0, battery.getMinus().getVoltage()); assertFalse(light0.isDefect()); diff --git a/src/test/java/de/ph87/electro/circuit/BatterySwitcher2x2Test.java b/src/test/java/de/ph87/electro/circuit/BatterySwitcher2x2Test.java index 0880340..9f69f9f 100644 --- a/src/test/java/de/ph87/electro/circuit/BatterySwitcher2x2Test.java +++ b/src/test/java/de/ph87/electro/circuit/BatterySwitcher2x2Test.java @@ -13,23 +13,23 @@ public class BatterySwitcher2x2Test { private static final double VOLTAGE = 3; - private static final Circuit circuit = new Circuit(); + private static final Circuit CIRCUIT = new Circuit(); - private static final PartBattery battery = circuit.addPart(new PartBattery()); + private static final PartBattery battery = CIRCUIT.addPart(new PartBattery()); - private static final PartSwitch1x2 switcher0 = circuit.addPart(new PartSwitch1x2()); + private static final PartSwitch1x2 switcher0 = CIRCUIT.addPart(new PartSwitch1x2()); - private static final PartSwitch1x2 switcher1 = circuit.addPart(new PartSwitch1x2()); + private static final PartSwitch1x2 switcher1 = CIRCUIT.addPart(new PartSwitch1x2()); - private static final PartLight light = circuit.addPart(new PartLight()); + private static final PartLight light = CIRCUIT.addPart(new PartLight()); @BeforeAll public static void setUp() { - circuit.connect(battery.getPlus(), switcher0.getCommon()); - circuit.connect(switcher0.getOutput0(), switcher1.getOutput0()); - circuit.connect(switcher0.getOutput1(), switcher1.getOutput1()); - circuit.connect(switcher1.getCommon(), light.getPin1()); - circuit.connect(light.getPin0(), battery.getMinus()); + CIRCUIT.connect(battery.getPlus(), switcher0.getCommon()); + CIRCUIT.connect(switcher0.getOutput0(), switcher1.getOutput0()); + CIRCUIT.connect(switcher0.getOutput1(), switcher1.getOutput1()); + CIRCUIT.connect(switcher1.getCommon(), light.getB()); + CIRCUIT.connect(light.getA(), battery.getMinus()); } @Test @@ -60,7 +60,7 @@ public class BatterySwitcher2x2Test { switcher0.setState(state0); switcher1.setState(state1); - circuit.evaluateAndRender(); + CIRCUIT.evaluateAndRender(); assertEquals(state0, switcher0.isState()); assertEquals(state1, switcher1.isState()); @@ -75,10 +75,10 @@ public class BatterySwitcher2x2Test { assertEquals(voltage1, switcher1.getOutput1().getVoltage()); assertEquals(voltage, switcher1.getCommon().getVoltage()); - assertEquals(voltage, light.getPin1().getVoltage()); - assertEquals(voltage, light.getVoltage()); + assertEquals(voltage, light.getB().getVoltage()); + assertEquals(voltage, light.getPotentialDifference()); - assertEquals(0, light.getPin0().getVoltage()); + assertEquals(0, light.getA().getVoltage()); assertEquals(0, battery.getMinus().getVoltage()); assertFalse(light.isDefect()); diff --git a/src/test/java/de/ph87/electro/circuit/BatterySwitcherCrossTest.java b/src/test/java/de/ph87/electro/circuit/BatterySwitcherCrossTest.java index 278cd52..2d88461 100644 --- a/src/test/java/de/ph87/electro/circuit/BatterySwitcherCrossTest.java +++ b/src/test/java/de/ph87/electro/circuit/BatterySwitcherCrossTest.java @@ -14,27 +14,27 @@ public class BatterySwitcherCrossTest { private static final double VOLTAGE = 3; - private static final Circuit circuit = new Circuit(); + private static final Circuit CIRCUIT = new Circuit(); - private static final PartBattery battery = circuit.addPart(new PartBattery()); + private static final PartBattery battery = CIRCUIT.addPart(new PartBattery()); - private static final PartSwitch1x2 switcher0 = circuit.addPart(new PartSwitch1x2()); + private static final PartSwitch1x2 switcher0 = CIRCUIT.addPart(new PartSwitch1x2()); - private static final PartSwitchCross switcherX = circuit.addPart(new PartSwitchCross()); + private static final PartSwitchCross switcherX = CIRCUIT.addPart(new PartSwitchCross()); - private static final PartSwitch1x2 switcher1 = circuit.addPart(new PartSwitch1x2()); + private static final PartSwitch1x2 switcher1 = CIRCUIT.addPart(new PartSwitch1x2()); - private static final PartLight light = circuit.addPart(new PartLight()); + private static final PartLight light = CIRCUIT.addPart(new PartLight()); @BeforeAll public static void setUp() { - circuit.connect(battery.getPlus(), switcher0.getCommon()); - circuit.connect(switcher0.getOutput0(), switcherX.getCommon0()); - circuit.connect(switcher0.getOutput1(), switcherX.getCommon1()); - circuit.connect(switcherX.getOutput0(), switcher1.getOutput0()); - circuit.connect(switcherX.getOutput1(), switcher1.getOutput1()); - circuit.connect(switcher1.getCommon(), light.getPin1()); - circuit.connect(light.getPin0(), battery.getMinus()); + CIRCUIT.connect(battery.getPlus(), switcher0.getCommon()); + CIRCUIT.connect(switcher0.getOutput0(), switcherX.getCommon0()); + CIRCUIT.connect(switcher0.getOutput1(), switcherX.getCommon1()); + CIRCUIT.connect(switcherX.getOutput0(), switcher1.getOutput0()); + CIRCUIT.connect(switcherX.getOutput1(), switcher1.getOutput1()); + CIRCUIT.connect(switcher1.getCommon(), light.getB()); + CIRCUIT.connect(light.getA(), battery.getMinus()); } @Test @@ -88,7 +88,7 @@ public class BatterySwitcherCrossTest { switcherX.setState(stateX); switcher1.setState(state1); - circuit.evaluateAndRender(); + CIRCUIT.evaluateAndRender(); assertEquals(state0, switcher0.isState()); assertEquals(stateX, switcherX.isState()); @@ -110,10 +110,10 @@ public class BatterySwitcherCrossTest { assertEquals(voltageX1, switcher1.getOutput1().getVoltage()); assertEquals(voltage, switcher1.getCommon().getVoltage()); - assertEquals(voltage, light.getPin1().getVoltage()); - assertEquals(voltage, light.getVoltage()); + assertEquals(voltage, light.getB().getVoltage()); + assertEquals(voltage, light.getPotentialDifference()); - assertEquals(0, light.getPin0().getVoltage()); + assertEquals(0, light.getA().getVoltage()); assertEquals(0, battery.getMinus().getVoltage()); assertFalse(light.isDefect()); diff --git a/src/test/java/de/ph87/electro/circuit/CircuitServiceTest.java b/src/test/java/de/ph87/electro/circuit/CircuitCalculationServiceTest.java similarity index 95% rename from src/test/java/de/ph87/electro/circuit/CircuitServiceTest.java rename to src/test/java/de/ph87/electro/circuit/CircuitCalculationServiceTest.java index 08236ef..cabd0ea 100644 --- a/src/test/java/de/ph87/electro/circuit/CircuitServiceTest.java +++ b/src/test/java/de/ph87/electro/circuit/CircuitCalculationServiceTest.java @@ -13,15 +13,15 @@ import java.nio.charset.StandardCharsets; import static org.junit.jupiter.api.Assertions.assertEquals; -class CircuitServiceTest { +class CircuitCalculationServiceTest { @Test void serialization() throws IOException { final Circuit circuit = new Circuit(); final PartBattery battery = circuit.addPart(new PartBattery()); final PartLight light = circuit.addPart(new PartLight()); - circuit.connect(battery.getPlus(), light.getPin1()); - circuit.connect(light.getPin0(), battery.getMinus()); + circuit.connect(battery.getPlus(), light.getB()); + circuit.connect(light.getA(), battery.getMinus()); check(circuit); } diff --git a/src/test/java/de/ph87/electro/circuit/net/CalculationServiceTest.java b/src/test/java/de/ph87/electro/circuit/net/CalculationServiceTest.java new file mode 100644 index 0000000..1b1e0bc --- /dev/null +++ b/src/test/java/de/ph87/electro/circuit/net/CalculationServiceTest.java @@ -0,0 +1,40 @@ +package de.ph87.electro.circuit.net; + +import de.ph87.electro.circuit.Calculation; +import de.ph87.electro.circuit.Circuit; +import de.ph87.electro.circuit.Wire; +import de.ph87.electro.circuit.part.Junction; +import de.ph87.electro.circuit.part.parts.PartBattery; +import de.ph87.electro.circuit.part.parts.PartLight; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; + +@Slf4j +class CalculationServiceTest { + + @Test + void test() { + final Circuit circuit = new Circuit(); + final PartBattery battery = circuit.addPart(new PartBattery()); + final PartLight light = circuit.addPart(new PartLight()); + circuit.connect(battery.getMinus(), light.getA()); + circuit.connect(battery.getPlus(), light.getB()); + + final Calculation calculation = new Calculation(circuit); + + calculation.toString().lines().forEach(log::info); + circuit.streamParts().forEach(part -> { + log.info(""); + log.info(part.toString()); + for (final Junction junction : part.getJunctions()) { + log.info(" \"%s\" = %.2f V".formatted(junction.getName(), junction.getVoltage())); + for (final Wire wire : junction.getWires()) { + final Junction opposite = wire.getOpposite(junction); + log.info(" -> %s.%s = %.2f A".formatted(opposite.getOwner().getName(), opposite.getName(), wire.getCurrent(junction))); + } + } + }); + log.info(""); + } + +} diff --git a/src/test/java/de/ph87/electro/circuit/net/CalculationTest.java b/src/test/java/de/ph87/electro/circuit/net/CalculationTest.java new file mode 100644 index 0000000..93c40dd --- /dev/null +++ b/src/test/java/de/ph87/electro/circuit/net/CalculationTest.java @@ -0,0 +1,19 @@ +package de.ph87.electro.circuit.net; + +import de.ph87.electro.circuit.Calculation; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; + +@Slf4j +class CalculationTest { + + @Test + void test() { + final Calculation calculation = new Calculation(1); + calculation.addResistor(-1, 0, 15); + calculation.addCurrentSource(-1, 0, 4, 5); + calculation.solve(); + calculation.toString().lines().forEach(log::info); + } + +}