/// <summary>
        /// Initializes a new instance of the <see cref="FrequencyBehavior"/> class.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="context"/> is <c>null</c>.</exception>
        public FrequencyBehavior(BehavioralBindingContext context)
            : base(context)
        {
            var bp = context.GetParameterSet<Parameters>();
            var state = context.GetState<IComplexSimulationState>();
            _variables = new OnePort<Complex>(
                state.GetSharedVariable(context.Nodes[0]),
                state.GetSharedVariable(context.Nodes[1]));

            // Build the functions
            var derivatives = new List<Func<Complex>>(Derivatives.Count);
            var builder = new ComplexFunctionBuilder();
            builder.VariableFound += (sender, args) =>
            {
                if (args.Variable == null && DerivativeVariables.TryGetValue(args.Node, out var variable))
                    args.Variable = new FuncVariable<Complex>(variable.Name, () => variable.Value, variable.Unit);
            };
            bp.RegisterBuilder(context, builder);
            var rhsLocs = _variables.GetRhsIndices(state.Map);
            var matLocs = new List<MatrixLocation>(Derivatives.Count * 2);
            foreach (var pair in Derivatives)
            {
                var variable = context.MapNode(state, pair.Key);
                if (state.Map.Contains(variable))
                {
                    derivatives.Add(builder.Build(pair.Value));
                    matLocs.Add(new MatrixLocation(rhsLocs[0], state.Map[variable]));
                    matLocs.Add(new MatrixLocation(rhsLocs[1], state.Map[variable]));
                }
            }

            // Get the matrix elements
            _derivatives = derivatives.ToArray();
            _elements = new ElementSet<Complex>(state.Solver, matLocs.ToArray());
        }
        public void When_BuildNode_Expect_Reference(Node node, double expected)
        {
            var builder = new ComplexFunctionBuilder();
            var act     = builder.Build(node).Invoke();

            Assert.AreEqual(expected, act.Real, 1e-20);
            Assert.AreEqual(0.0, act.Imaginary, 1e-20);
        }
        public void When_BuildConstant_Expect_Reference()
        {
            var builder = new ComplexFunctionBuilder();
            var act     = builder.Build(Node.Constant(1.0)).Invoke();

            Assert.AreEqual(1.0, act.Real, 1e-20);
            Assert.AreEqual(0.0, act.Imaginary, 1e-20);
        }
示例#4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Frequency"/> class.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="context"/> is <c>null</c>.</exception>
        public Frequency(BehavioralBindingContext context)
            : base(context)
        {
            var bp    = context.GetParameterSet <Parameters>();
            var state = context.GetState <IComplexSimulationState>();

            _variables = new OnePort <Complex>(
                state.GetSharedVariable(context.Nodes[0]),
                state.GetSharedVariable(context.Nodes[1]));
            _branch = state.CreatePrivateVariable(Name.Combine("branch"), Units.Ampere);

            // Build the functions
            var nVariables = new Dictionary <VariableNode, IVariable <Complex> >(Derivatives.Comparer);

            foreach (var variable in Derivatives.Keys)
            {
                var orig = DerivativeVariables[variable];
                nVariables.Add(variable, new FuncVariable <Complex>(orig.Name, () => orig.Value, orig.Unit));
            }
            var builder = new ComplexFunctionBuilder();

            builder.VariableFound += (sender, args) =>
            {
                if (args.Variable == null && DerivativeVariables.TryGetValue(args.Node, out var variable))
                {
                    args.Variable = new FuncVariable <Complex>(variable.Name, () => variable.Value, variable.Unit);
                }
            };
            bp.RegisterBuilder(context, builder);
            var derivatives = new List <Func <Complex> >(Derivatives.Count);
            var rhsLocs     = state.Map[_branch];
            var matLocs     = new List <MatrixLocation>(Derivatives.Count);

            foreach (var pair in Derivatives)
            {
                var variable = context.MapNode(state, pair.Key, _branch);
                if (state.Map.Contains(variable))
                {
                    derivatives.Add(builder.Build(pair.Value));
                    matLocs.Add(new MatrixLocation(rhsLocs, state.Map[variable]));
                }
            }

            // Get the matrix elements
            _derivatives = derivatives.ToArray();
            _values      = new Complex[_derivatives.Length];
            _elements    = new ElementSet <Complex>(state.Solver, matLocs.ToArray());
            int br  = state.Map[_branch];
            int pos = state.Map[_variables.Positive];
            int neg = state.Map[_variables.Negative];

            _coreElements = new ElementSet <Complex>(state.Solver, new[] {
                new MatrixLocation(br, pos),
                new MatrixLocation(br, neg),
                new MatrixLocation(pos, br),
                new MatrixLocation(neg, br)
            });
        }
        public void When_BuildNodeFunctions_Expect_Reference(Node node, Complex expected)
        {
            var builder = new ComplexFunctionBuilder();

            builder.RegisterDefaultFunctions();
            var act = builder.Build(node).Invoke();

            Assert.AreEqual(expected.Real, act.Real, 1e-20);
            Assert.AreEqual(act.Imaginary, act.Imaginary, 1e-20);
        }
        public void When_BuildVariable_Expect_Reference()
        {
            var builder  = new ComplexFunctionBuilder();
            var variable = new GetSetVariable <Complex>("a", Units.Volt);

            builder.VariableFound += (sender, args) =>
            {
                if (args.Variable == null && args.Node.Name == "a")
                {
                    args.Variable = variable;
                }
            };
            variable.Value = new Complex(1.0, 2.0);
            var act = builder.Build(Node.Variable("a") + 3.0).Invoke();

            Assert.AreEqual(4.0, act.Real, 1e-20);
            Assert.AreEqual(2.0, act.Imaginary, 1e-20);
        }