MNA + Companion MNA + Adapter for CCK + Automated tests

 

java

1765 (35 pages), or 67,157 characters

 

scala

696 (14 pages), or 28,865 characters

 

This means that in the 35 pages of java code, 21 of those pages are "boilerplate" code; they have nothing to do with the concepts or physics in the simulation and are there merely to compensate for deficiencies in the Java language.  This boilerplate code entails 2 costs: (1) the initial time it takes to write and (2) the recurring cost of having to wade through boilerplate code during maintenance/bugfixes/new feature addition.

___

mna

java 739 lines (24414 characters)

scala 279 lines (9859 characters)

___

mna-companion

java 596 lines

scala 190 lines

___

adapter

java 154 lines

scala 67 lines

___

automated tests:

java 276

scala 160

 

______

Some examples code comparisons:

 

Indicating desired node voltages:

 

Scala

      val voltageMap=Map(0 -> 0.0, 1 -> 4.0)

 

Java

      HashMap<Integer, Double> voltageMap = new HashMap<Integer, Double>();

      voltageMap.put(0, 0.0);

      voltageMap.put(1, 4.0);

 

______________

Unit Test for a simple circuit:

 

Scala

  test("battery resistor circuit should have correct voltages and currents for a simple circuit") {

    val battery = Battery(0, 1, 4.0)

    val circuit = new Circuit(battery :: Nil, Resistor(1, 0, 4.0) :: Nil)

    val desiredSolution = new Solution(Map(0 -> 0.0, 1 -> 4.0), Map(battery -> 1.0))

    assert(circuit.solve.approxEquals(desiredSolution))

  }

 

Java

  public void test_battery_resistor_circuit_should_have_correct_voltages_and_currents_for_a_simple_circuit() {

    MNA.Battery battery = new MNA.Battery(0, 1, 4.0);

    MNA.Circuit circuit = new MNA.Circuit(Arrays.asList(battery), Arrays.asList(new MNA.Resistor(1, 0, 4)));

    HashMap<Integer, Double> voltageMap = new HashMap<Integer, Double>();

    voltageMap.put(0, 0.0);

    voltageMap.put(1, 4.0);

 

    HashMap<MNA.Element, Double> currentMap = new HashMap<MNA.Element, Double>();

    currentMap.put(battery, 1.0);

    MNA.Solution desiredSolution = new MNA.Solution(voltageMap, currentMap);

    assertTrue(circuit.solve().approxEquals(desiredSolution));

  }

 

___

Definition of a Resistor

Scala

   case class Resistor(node0: Int, node1: Int, resistance: Double) extends Element

 

Java

   public static class Resistor extends Element {

        double resistance;

 

        Resistor(int node0, int node1, double resistance) {

            super(node0, node1);

            this.resistance = resistance;

        }

 

        @Override

        public boolean equals(Object o) {

            if (this == o) return true;

            if (o == null || getClass() != o.getClass()) return false;

            if (!super.equals(o)) return false;

 

            Resistor resistor = (Resistor) o;

 

            if (Double.compare(resistor.resistance, resistance) != 0) return false;

 

            return true;

        }

 

        @Override

        public int hashCode() {

            int result = super.hashCode();

            long temp;

            temp = resistance != +0.0d ? Double.doubleToLongBits(resistance) : 0L;

            result = 31 * result + (int) (temp ^ (temp >>> 32));

            return result;

        }

 

        @Override

        public String toString() {

            return "Resistor{" +

                    "resistance=" + resistance +

                    '}';

        }

    }

______________

Adapter for working with CCK:

 

Scala:

  def apply(circuit: CCKCircuit, dt: Double) = {

    val batteries = new ArrayBuffer[ResistiveBatteryAdapter]

    val resistors = new ArrayBuffer[ResistorAdapter]

    val capacitors = new ArrayBuffer[CapacitorAdapter]

    val inductors = new ArrayBuffer[InductorAdapter]

    for (i <- 0 until circuit.numBranches) {

      circuit.getBranches.apply(i) match {

        case battery: CCKBattery => batteries += new ResistiveBatteryAdapter(circuit, battery)

        case resistor: CCKResistor => resistors += new ResistorAdapter(circuit, resistor)

        case resistor: Wire => resistors += new ResistorAdapter(circuit, resistor)

        case resistor: Filament => resistors += new ResistorAdapter(circuit, resistor)

        case resistor: Switch => resistors += new ResistorAdapter(circuit, resistor)

        case resistor: Bulb => resistors += new ResistorAdapter(circuit, resistor)

        case resistor: SeriesAmmeter => resistors += new ResistorAdapter(circuit, resistor)

        case capacitor: CCKCapacitor => capacitors += new CapacitorAdapter(circuit, capacitor)

        case inductor: CCKInductor => inductors += new InductorAdapter(circuit, inductor)

      }

    }

    val circ = new FullCircuit(batteries, resistors, capacitors, inductors)

    val solution = circ.solve(dt)

    batteries.foreach(_.applySolution(solution))

    resistors.foreach(_.applySolution(solution))

    capacitors.foreach(_.applySolution(solution))

    inductors.foreach(_.applySolution(solution))

    fireCircuitSolved()

  }

 

Java:

    public void apply(Circuit circuit, double dt) {

        ArrayList<ResistiveBatteryAdapter> batteries = new ArrayList<ResistiveBatteryAdapter>();

        ArrayList<ResistorAdapter> resistors = new ArrayList<ResistorAdapter>();

        ArrayList<CapacitorAdapter> capacitors = new ArrayList<CapacitorAdapter>();

        ArrayList<InductorAdapter> inductors = new ArrayList<InductorAdapter>();

        for (int i = 0; i < circuit.numBranches(); i++) {

            if (circuit.getBranches()[i] instanceof Battery)

                batteries.add(new ResistiveBatteryAdapter(circuit, (Battery) circuit.getBranches()[i]));

            if (circuit.getBranches()[i] instanceof Resistor)

                resistors.add(new ResistorAdapter(circuit, circuit.getBranches()[i]));

            if (circuit.getBranches()[i] instanceof Wire)

                resistors.add(new ResistorAdapter(circuit, circuit.getBranches()[i]));

            if (circuit.getBranches()[i] instanceof Filament)

                resistors.add(new ResistorAdapter(circuit, circuit.getBranches()[i]));

            if (circuit.getBranches()[i] instanceof Switch)

                resistors.add(new ResistorAdapter(circuit, circuit.getBranches()[i]));

            if (circuit.getBranches()[i] instanceof Bulb)

                resistors.add(new ResistorAdapter(circuit, circuit.getBranches()[i]));

            if (circuit.getBranches()[i] instanceof SeriesAmmeter)

                resistors.add(new ResistorAdapter(circuit, circuit.getBranches()[i]));

            if (circuit.getBranches()[i] instanceof Capacitor)

                capacitors.add(new CapacitorAdapter(circuit, (Capacitor) circuit.getBranches()[i]));

            if (circuit.getBranches()[i] instanceof Inductor)

                inductors.add(new InductorAdapter(circuit, (Inductor) circuit.getBranches()[i]));

        }

        CompanionMNA.FullCircuit circ = new CompanionMNA.FullCircuit(batteries, resistors, capacitors, inductors);

        CompanionMNA.CompanionSolution solution = circ.solve(dt);

        for (ResistiveBatteryAdapter batteryAdapter : batteries)

            batteryAdapter.applySolution(solution);

        for (ResistorAdapter resistorAdapter : resistors)

            resistorAdapter.applySolution(solution);

        for (CapacitorAdapter capacitorAdapter : capacitors)

            capacitorAdapter.applySolution(solution);

        for (InductorAdapter inductorAdapter : inductors)

            inductorAdapter.applySolution(solution);

        fireCircuitSolved();

    }