LiveSPICE icon indicating copy to clipboard operation
LiveSPICE copied to clipboard

System.ArgumentException Incorrect number of arguments supplied for call to method

Open mdouchement opened this issue 2 years ago • 7 comments

Based on https://github.com/dsharlet/LiveSPICE/commit/a0f0a8e4e75e2c81cc78d70f38aa67df48f1f0d8 build. I'm getting an error when I simulate the following shema: image

Building circuit...
Build: 0 errors, 0 warnings
Building solution for h=2,6041666666666666E-06
Performing steady state analysis...
Performing transient analysis...
System solved, 2 solution sets for 31 unknowns.
Exception: System.ArgumentException: Incorrect number of arguments supplied for call to method 'Double lambda_method67(System.Runtime.CompilerServices.Closure, Double, Double)' (Parameter 'method')
   at System.Dynamic.Utils.ExpressionUtils.ValidateArgumentCount(MethodBase method, ExpressionType nodeKind, Int32 count, ParameterInfo[] pis)
   at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression arg0, Expression arg1)
   at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
   at ComputerAlgebra.LinqCompiler.CompileExpression.VisitCall(Call C)
   at ComputerAlgebra.ExpressionVisitor`1.Visit(Expression E)
   at ComputerAlgebra.LinqCompiler.CompileExpression.Visit(Expression E)
   at ComputerAlgebra.LinqCompiler.CompileExpression.VisitProduct(Product M)
   at ComputerAlgebra.ExpressionVisitor`1.Visit(Expression E)

By removing C4 or C5 the circuit is stable.

Shape2.schx
<?xml version="1.0" encoding="utf-8"?>
<Schematic Name="X1" PartNumber="">
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="0" Flip="false" Position="120,80">
    <Component _Type="Circuit.Speaker, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" V0dBFS="1 V" Impedance="∞ Ω" Name="S1" Description="Ideal speaker." />
  </Element>
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="0" Flip="false" Position="120,120">
    <Component _Type="Circuit.Ground, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" WireName="GND" Name="GND3" Description="Nodes with the same name are connected as if they were connected by a continuous wire." />
  </Element>
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="120,100" B="120,120" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="70,40" B="120,40" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="120,40" B="120,60" />
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="0" Flip="false" Position="-400,150">
    <Component _Type="Circuit.Ground, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" WireName="GND" Name="GND1" Description="Nodes with the same name are connected as if they were connected by a continuous wire." />
  </Element>
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="0" Flip="false" Position="-400,100">
    <Component _Type="Circuit.Input, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" V0dBFS="1 V" Name="V1" Description="Ideal voltage source representing an input port." />
  </Element>
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-400,120" B="-400,150" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-400,50" B="-400,80" />
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="-1" Flip="false" Position="50,40">
    <Component _Type="Circuit.Capacitor, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Capacitance="1 μF" Name="C2" Description="Standard capacitor component" />
  </Element>
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="1" Flip="false" Position="-150,50">
    <Component _Type="Circuit.Capacitor, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Capacitance="10 nF" Name="C1" Description="Standard capacitor component" />
  </Element>
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="1" Flip="false" Position="-250,50">
    <Component _Type="Circuit.Capacitor, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Capacitance="10 nF" Name="C3" Description="Standard capacitor component" />
  </Element>
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="1" Flip="false" Position="-150,170">
    <Component _Type="Circuit.Resistor, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Resistance="47 kΩ" Name="R2" Description="Standard resistor." />
  </Element>
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-230,50" B="-170,50" />
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="2" Flip="false" Position="-200,100">
    <Component _Type="Circuit.Resistor, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Resistance="10 kΩ" Name="R3" Description="Standard resistor." />
  </Element>
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="0" Flip="false" Position="-200,150">
    <Component _Type="Circuit.Ground, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" WireName="GND" Name="GND2" Description="Nodes with the same name are connected as if they were connected by a continuous wire." />
  </Element>
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-200,120" B="-200,150" />
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="2" Flip="false" Position="-200,320">
    <Component _Type="Circuit.Capacitor, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Capacitance="22 nF" Name="C4" Description="Standard capacitor component" />
  </Element>
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="2" Flip="false" Position="-100,220">
    <Component _Type="Circuit.Capacitor, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Capacitance="4.7 nF" Name="C5" Description="Standard capacitor component" />
  </Element>
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="0" Flip="false" Position="-100,270">
    <Component _Type="Circuit.Ground, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" WireName="GND" Name="GND4" Description="Nodes with the same name are connected as if they were connected by a continuous wire." />
  </Element>
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-100,240" B="-100,270" />
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="0" Flip="false" Position="-200,370">
    <Component _Type="Circuit.Ground, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" WireName="GND" Name="GND5" Description="Nodes with the same name are connected as if they were connected by a continuous wire." />
  </Element>
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-400,50" B="-300,50" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-300,50" B="-270,50" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-130,170" B="-100,170" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-100,170" B="-100,200" />
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="1" Flip="false" Position="-250,170">
    <Component _Type="Circuit.Capacitor, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Capacitance="100 nF" Name="C6" Description="Standard capacitor component" />
  </Element>
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-300,170" B="-270,170" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-230,170" B="-170,170" />
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="1" Flip="false" Position="-250,270">
    <Component _Type="Circuit.Resistor, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Resistance="1 MΩ" Name="R4" Description="Standard resistor." />
  </Element>
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-200,50" B="-200,80" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-300,50" B="-300,170" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-100,50" B="-100,170" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-300,170" B="-300,270" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-300,270" B="-270,270" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-230,270" B="-200,270" />
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="2" Flip="false" Position="70,90">
    <Component _Type="Circuit.Resistor, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Resistance="10 kΩ" Name="R1" Description="Standard resistor." />
  </Element>
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="0" Flip="false" Position="70,140">
    <Component _Type="Circuit.Ground, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" WireName="GND" Name="GND6" Description="Nodes with the same name are connected as if they were connected by a continuous wire." />
  </Element>
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="70,110" B="70,140" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="70,40" B="70,70" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-130,50" B="-100,50" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-100,-40" B="-100,30" />
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="0" Flip="false" Position="-50,40">
    <Component _Type="Circuit.OpAmp, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rin="1 TΩ" Rout="50 Ω" Aol="200 k" GBP="5.25 MHz" Name="X1" PartNumber="TL07x" Description="Generic op-amp model. Model includes a single pole frequency response and saturation." />
  </Element>
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="0" Flip="false" Position="-50,10">
    <Component _Type="Circuit.Rail, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Voltage="15 V" Name="V2" Description="Single terminal voltage source with the cathode implicitly connected to ground." />
  </Element>
  <Element Type="Circuit.Symbol, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Rotation="2" Flip="false" Position="-50,70">
    <Component _Type="Circuit.Rail, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Voltage="-15 V" Name="V3" Description="Single terminal voltage source with the cathode implicitly connected to ground." />
  </Element>
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-50,10" B="-50,20" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-50,60" B="-50,70" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-100,30" B="-70,30" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="0,-40" B="0,40" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-30,40" B="0,40" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="0,40" B="30,40" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-100,-40" B="0,-40" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-100,50" B="-70,50" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-200,170" B="-200,270" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-200,270" B="-200,300" />
  <Element Type="Circuit.Wire, Circuit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" A="-200,340" B="-200,370" />
</Schematic>

mdouchement avatar Nov 27 '22 21:11 mdouchement

This example is uncovering an interesting bug that I think is a failure of the computer algebra simplification (or perhaps some higher level simplification first). The problem can be reproduced with just two capacitors in parallel. If the computer algebra system doesn't recognize this is equivalent to just one capacitor, then we end up with a system of equations with two differential unknowns and only one differential equation. The solver then does a dumb thing and lets differential unknowns propagate all the way to the end of the process, and the compiler tries to actually generate a call to D, which isn't a real callable function.

Here's the funny part: if you rotate one of the two capacitors 180 degrees, swapping the anode and the cathode, the computer algebra system solves it just fine :)

With two parallel capacitors with flipped orientation:

System of 5 equations and 5 unknowns = { _v1[t], GND[t], i_1[t], VC5[t], VC2[t] }
  -GND[t] + _v1[t]==V1[t]
  GND[t]==0
  VC5[t]==-GND[t] + _v1[t]
  VC2[t]==GND[t] - _v1[t]
  D[VC2[t], t]*-1E-08 + D[VC5[t], t]*1E-08 + i_1[t]==0

With the same orientation:

System of 4 equations and 4 unknowns = { _v1[t], GND[t], i_1[t], VC5[t] }
  -GND[t] + _v1[t]==V1[t]
  GND[t]==0
  VC5[t]==-GND[t] + _v1[t]
  D[VC5[t], t]*2E-08 + i_1[t]==0

dsharlet avatar Apr 30 '23 21:04 dsharlet

There's a likely lame workaround for this: capacitors could canonicalize the ordering of their anode/cathode by sorting the nodes by name...

dsharlet avatar Apr 30 '23 21:04 dsharlet

Actually, I found a more real solution by making the computer algebra more robust. This was a nice bug to fix, I can't believe it hasn't been uncovered by anything until now! Thanks for the report and sorry about the delay in fixing it.

dsharlet avatar Apr 30 '23 23:04 dsharlet

Thank you for the fix.

mdouchement avatar May 01 '23 13:05 mdouchement

I still have the issue with Shape2.shx and https://github.com/dsharlet/LiveSPICE/releases/tag/v0.14

mdouchement avatar May 04 '23 08:05 mdouchement

Sorry about that. I reduced this again to a simple case. Before, it was just two capacitors in parallel from the same node. That was easy to fix. This new reproducer is similar, except there are two capacitors in series in one of the parallel branches.

This case is tricky. The problem is that we really need to recognize that this is equivalent to a single capacitor. In the parallel case, this is easy enough, just making the computer algebra system a bit better. However, this case is problematic. Even if I get the CAS to understand this is one capacitor, it means that the node between the two series capacitors wouldn't actually exist. So if you probed it, it wouldn't work.

That by itself isn't so terrible a result. But it seems to indicate a bigger problem with how I'm thinking about the solver.

dsharlet avatar May 05 '23 01:05 dsharlet

I've been working on this issue, it can be reduced to the following simple circuit: image

I think other failures, e.g. #170 are due to this same issue.

The problem is clear:

  D[VC1[t], t]*0.0001 - D[VC3[t], t]*0.0001==0
  D[VC1[t], t]*-0.0001 - D[VC2[t], t]*0.0001 + i_1[t]==0
  D[VC2[t], t]*0.0001 + D[VC3[t], t]*0.0001 - GND[t]*0.01 + _v2[t]*0.01==0

This is a singular system of equations. The solution is easy as a human: observing that VC1 = VC3, and substituting. How to do this in a general way is not so clear. I think in some of the other examples of this problem involve networks of components, not just a single component.

dsharlet avatar May 11 '23 07:05 dsharlet