Пример #1
0
        public void When_RecursiveSubcircuit_Expect_Reference()
        {
            // Define the subcircuit
            var subckt = new SubcircuitDefinition(new Circuit(
                                                      new Resistor("R1", "a", "b", 1e3),
                                                      new Resistor("R2", "b", "c", 1e3)),
                                                  "a", "c");

            // Define the parent subcircuit
            var subckt2 = new SubcircuitDefinition(new Circuit(
                                                       new Subcircuit("X1", subckt).Connect("x", "y"),
                                                       new Subcircuit("X2", subckt).Connect("y", "z")),
                                                   "x", "y", "z");

            // Define the circuit
            var ckt = new Circuit(
                new VoltageSource("V1", "in", "0", 2.0),
                new Subcircuit("X1", subckt2).Connect("in", "out", "0"));

            // Simulate the circuit
            var op = new OP("op");

            IExport <double>[]   exports    = new[] { new RealVoltageExport(op, "out") };
            IEnumerable <double> references = new double[] { 1.0 };

            AnalyzeOp(op, ckt, exports, references);
            DestroyExports(exports);
        }
Пример #2
0
        public void When_LocalSolverSubcircuitOp2_Expect_Reference()
        {
            // One internal node
            var subckt = new SubcircuitDefinition(new Circuit(
                                                      new Resistor("R1", "a", "b", 1e3),
                                                      new Resistor("R2", "b", "c", 1e3),
                                                      new Resistor("R3", "b", "0", 1e3)),
                                                  "a", "c");
            var ckt = new Circuit(
                new VoltageSource("V1", "in", "0", 1.0),
                new Subcircuit("X1", subckt, "in", "out")
                .SetParameter("localsolver", true));

            var op = new OP("op");

            IExport <double>[] exports = new[]
            {
                new RealVoltageExport(op, "out"),
                new RealVoltageExport(op, "X1".Combine("b")),
                new RealVoltageExport(op, "X1".Combine("c"))
            };
            IEnumerable <double> references = new double[] { 0.5, 0.5, 0.5 };

            AnalyzeOp(op, ckt, exports, references);
            DestroyExports(exports);
        }
Пример #3
0
        public void When_LocalSolverSubcircuitOp3_Expect_Reference()
        {
            // Variable that makes an equivalent circuit impossible
            var subckt = new SubcircuitDefinition(new Circuit(
                                                      new VoltageSource("V1", "a", "0", 1.0)), "a");
            var ckt = new Circuit(
                new Resistor("R1", "in", "out", 1e3),
                new Resistor("R2", "out", "0", 1e3),
                new Subcircuit("X1", subckt, "in")
                .SetParameter("localsolver", true));

            var op = new OP("op");

            IExport <double>[] exports = new[] { new RealVoltageExport(op, "out") };
            Assert.Throws <NoEquivalentSubcircuitException>(() => op.Run(ckt));
        }
Пример #4
0
        public void When_LocalSolverSubcircuitAc_Expect_Reference()
        {
            // No internal nodes
            var subckt = new SubcircuitDefinition(new Circuit(
                                                      new Resistor("R1", "a", "b", 1e3),
                                                      new Resistor("R2", "b", "0", 1e3)),
                                                  "a", "b");
            var ckt = new Circuit(
                new VoltageSource("V1", "in", "0", 1.0).SetParameter("acmag", 1.0),
                new Subcircuit("X1", subckt, "in", "out")
                .SetParameter("localsolver", true));

            var ac = new AC("ac", new DecadeSweep(1, 100, 3));

            IExport <Complex>[] exports = new[] { new ComplexVoltageExport(ac, "out") };
            IEnumerable <Func <double, Complex> > references = new Func <double, Complex>[] { f => 0.5 };

            AnalyzeAC(ac, ckt, exports, references);
            DestroyExports(exports);
        }
Пример #5
0
        public void When_SubcircuitAccess_Expect_Reference()
        {
            var subckt = new SubcircuitDefinition(new Circuit(
                                                      new Resistor("R1", "a", "b", 1e3),
                                                      new Resistor("R2", "b", "c", 1e3)), "a", "c");
            var ckt = new Circuit(
                new VoltageSource("V1", "in", "0", 10.0),
                new Subcircuit("X1", subckt, "in", "out"),
                new Subcircuit("X2", subckt, "out", "0"));

            var op = new OP("op");

            op.Run(ckt);
            var behaviors = op.EntityBehaviors["X2"].GetValue <SpiceSharp.Components.Subcircuits.EntitiesBehavior>();

            Assert.AreEqual(10.0 / 4.0, behaviors.LocalBehaviors["R2"].GetProperty <double>("v"), 1e-12);

            var state = behaviors.GetState <IBiasingSimulationState>();

            Assert.AreEqual(10.0 / 4.0, state.Solution[state.Map[state.GetSharedVariable("b")]], 1e-12);
        }
Пример #6
0
        public void When_LocalSolverSubcircuitTransient_Expect_Reference()
        {
            // With internal states
            var subckt = new SubcircuitDefinition(new Circuit(
                                                      new Resistor("R1", "a", "b", 1e3),
                                                      new Capacitor("C1", "b", "0", 1e-6)),
                                                  "a", "b");
            var ckt = new Circuit(
                new VoltageSource("V1", "in", "0", 1.0),
                new Subcircuit("X1", subckt, "in", "out")
                .SetParameter("localsolver", true));

            var tran = new Transient("transient", 1e-6, 1e-3);

            tran.TimeParameters.InitialConditions.Add("out", 0.0);
            IExport <double>[] exports = new[] { new RealVoltageExport(tran, "out") };
            IEnumerable <Func <double, double> > references = new Func <double, double>[] { t => 1.0 - Math.Exp(-t * 1e3) };

            AnalyzeTransient(tran, ckt, exports, references);
            DestroyExports(exports);
        }
Пример #7
0
        public void When_SimpleSubcircuit_Expect_Reference()
        {
            // Define the subcircuit
            var subckt = new SubcircuitDefinition(new Circuit(
                                                      new Resistor("R1", "a", "b", 1e3),
                                                      new Resistor("R2", "b", "0", 1e3)),
                                                  "a", "b");

            // Define the circuit
            var ckt = new Circuit(
                new VoltageSource("V1", "in", "0", 5.0),
                new Subcircuit("X1", subckt).Connect("in", "out"));

            // Simulate the circuit
            var op = new OP("op");

            IExport <double>[]   exports    = new[] { new RealVoltageExport(op, "out") };
            IEnumerable <double> references = new double[] { 2.5 };

            AnalyzeOp(op, ckt, exports, references);
        }
        /// <summary>
        /// Read subcircuit definitions
        /// </summary>
        /// <param name="name">Name</param>
        /// <param name="parameters">Parameters</param>
        /// <param name="netlist">Netlist</param>
        /// <returns></returns>
        public override bool Read(string type, Statement st, Netlist netlist)
        {
            if (st.Parameters.Count < 2)
            {
                throw new ParseException(st.Name, "Subcircuit name expected", false);
            }

            // Create the identifier of the subcircuit definition
            CircuitIdentifier name = new CircuitIdentifier(st.Parameters[0].image);

            if (netlist.Path.DefinitionPath != null)
            {
                name = netlist.Path.DefinitionPath.Grow(name);
            }

            // Extract the subcircuit definition statements
            StatementsToken      body       = (StatementsToken)st.Parameters[st.Parameters.Count - 1];
            SubcircuitDefinition definition = new SubcircuitDefinition(name, body);

            // Parse nodes and parameters
            bool mode = true; // true = nodes, false = parameters

            for (int i = 1; i < st.Parameters.Count - 1; i++)
            {
                if (mode)
                {
                    // After this, only parameters will follow
                    if (st.Parameters[i].image.ToLower() == "params:")
                    {
                        mode = false;
                    }

                    // Parameters have started, so we will keep reading parameters
                    else if (st.Parameters[i].kind == ASSIGNMENT)
                    {
                        mode = false;
                        AssignmentToken at = st.Parameters[i] as AssignmentToken;
                        definition.Defaults.Add(new CircuitIdentifier(at.Name.image), at.Value);
                    }

                    // Still reading nodes
                    else if (ReaderExtension.IsNode(st.Parameters[i]))
                    {
                        definition.Pins.Add(new CircuitIdentifier(st.Parameters[i].image));
                    }
                }
                else if (st.Parameters[i].kind == ASSIGNMENT)
                {
                    AssignmentToken at = st.Parameters[i] as AssignmentToken;
                    definition.Defaults.Add(new CircuitIdentifier(at.Name.image), at.Value);
                }
            }

            // Create a new subcircuit path
            SubcircuitPath orig = netlist.Path;

            netlist.Path = new SubcircuitPath(orig, definition);
            foreach (var s in definition.Body.Statements(StatementType.Subcircuit))
            {
                netlist.Readers.Read(s, netlist);
            }

            // Restore
            netlist.Path = orig;

            // Return values
            netlist.Definitions.Add(definition.Name, definition);
            Generated = definition;
            return(true);
        }
Пример #9
0
        /// <summary>
        /// Read
        /// </summary>
        /// <param name="type">Type</param>
        /// <param name="st">Statement</param>
        /// <param name="netlist">Netlist</param>
        /// <returns></returns>
        public override bool Read(string type, Statement st, Netlist netlist)
        {
            // Initialize
            List <CircuitIdentifier> instancepins = new List <CircuitIdentifier>();
            Dictionary <CircuitIdentifier, Token> instanceparameters = new Dictionary <CircuitIdentifier, Token>();
            CircuitIdentifier definition = null;

            // Get the name
            CircuitIdentifier name;

            if (netlist.Path.InstancePath != null)
            {
                name = netlist.Path.InstancePath.Grow(st.Name.image);
            }
            else
            {
                name = new CircuitIdentifier(st.Name.image);
            }

            // Format: <NAME> <NODES>* <SUBCKT> <PAR1>=<VAL1> ...
            // Or: <NAME> <NODES>* <SUBCKT> params: <PAR1>=<VAL1> ...
            bool mode = true; // true = nodes, false = parameters

            for (int i = 0; i < st.Parameters.Count; i++)
            {
                // Reading nodes
                if (mode)
                {
                    if (ReaderExtension.IsNode(st.Parameters[i]))
                    {
                        instancepins.Add(definition = new CircuitIdentifier(st.Parameters[i].image));
                    }
                    else
                    {
                        instancepins.RemoveAt(instancepins.Count - 1);
                        mode = false;
                    }
                }

                // Reading parameters
                // Don't use ELSE! We still need to read the last parameter
                if (!mode)
                {
                    if (st.Parameters[i].kind == ASSIGNMENT)
                    {
                        AssignmentToken at = st.Parameters[i] as AssignmentToken;
                        switch (at.Name.kind)
                        {
                        case WORD:
                        case IDENTIFIER:
                            instanceparameters.Add(new CircuitIdentifier(at.Name.image), at.Value);
                            break;

                        default:
                            throw new ParseException(at.Name, "Parameter name expected");
                        }
                    }
                }
            }

            // If there are only node-like tokens, then the last one is the definition by default
            if (mode)
            {
                instancepins.RemoveAt(instancepins.Count - 1);
            }

            // Modify the instancepins to be local or use the nodemap
            for (int i = 0; i < instancepins.Count; i++)
            {
                if (netlist.Path.NodeMap.TryGetValue(instancepins[i], out CircuitIdentifier node))
                {
                    instancepins[i] = node;
                }
                else if (netlist.Path.InstancePath != null)
                {
                    instancepins[i] = netlist.Path.InstancePath.Grow(instancepins[i].Name);
                }
            }

            // Find the subcircuit definition
            if (netlist.Path.DefinitionPath != null)
            {
                definition = netlist.Path.DefinitionPath.Grow(definition);
            }
            SubcircuitDefinition subcktdef = netlist.Path.FindDefinition(netlist.Definitions, definition) ??
                                             throw new ParseException(st.Parameters[st.Parameters.Count - 1], "Cannot find subcircuit definition");
            Subcircuit subckt = new Subcircuit(subcktdef, name, instancepins, instanceparameters);

            SubcircuitPath orig = netlist.Path;

            netlist.Path = new SubcircuitPath(netlist, orig, subckt);

            // Read all control statements
            foreach (var s in subcktdef.Body.Statements(StatementType.Control))
            {
                netlist.Readers.Read(s, netlist);
            }

            // Read all model statements
            foreach (var s in subcktdef.Body.Statements(StatementType.Model))
            {
                netlist.Readers.Read(s, netlist);
            }

            // Read all component statements
            foreach (var s in subcktdef.Body.Statements(StatementType.Component))
            {
                netlist.Readers.Read(s, netlist);
            }

            // Restore
            netlist.Path = orig;
            Generated    = subckt;
            return(true);
        }