Пример #1
0
        /// <summary>
        /// Converts every state to a waveform. Waveforms built have <paramref name="pointsCount"/> points and time increment of
        /// <paramref name="timeStep"/>.
        /// </summary>
        /// <returns></returns>
        /// <param name="pointsCount"></param>
        /// <param name="timeStep"></param>
        public WaveformPartialState ToWaveform(int pointsCount, double timeStep)
        {
            // Create state for result
            var result = new WaveformPartialState(_NodeIndices, _ActiveComponentsIndices, States.Keys);

            // For each state
            foreach (var state in States)
            {
                // Use its method to convert to a waveform
                result.States[state.Key] = States[state.Key].ToWaveform(pointsCount, timeStep);
            }

            return(result);
        }
Пример #2
0
        /// <summary>
        /// Topmost logic behind AC Full Cycle - calling it will result in simulation being performed and saved to
        /// <see cref="ISimulationResultsProvider"/>. This version adjusts <see cref="IOpAmp"/> operation for every calculated point so that neither
        /// <see cref="IOpAmp"/> exceeds its supply voltages.
        /// </summary>
        /// <param name="factory"></param>
        /// <param name="includeDCBias">If true DC bias will be performed and added to results, if false only saturated <see cref="IOpAmp"/>s
        /// will be considered for DC part of simulation</param>
        private void FullCycleLogicWithOpAmpAdjustment(AdmittanceMatrixFactory factory, bool includeDCBias)
        {
            // TODO: Try to make it so that saturated op amp bias is not considered to be pure DC but rather an extension of all sources
            // contributing to the circuit

            // TODO: number of points should be given by caller
            int pointsCount = 600;

            // Time step between two subsequent points in time vector
            double timeStep = GetTimeStep(pointsCount, factory.LowestFrequency);

            // Create an enumeration of used sources - take AC sources and op-amp saturation source. If DC bias is requested, add the DC sources too.
            var usedSources = (includeDCBias ? factory.AllSources : factory.ACSources).Concat(factory.OpAmpSaturationSource);

            // Get node indices constructed on the basis of the circuit
            var nodeIndices = factory.Nodes.ToList();

            // Create a state which will be filled with adjusted simulation points
            var adjustedState = new WaveformPartialState(factory.NodesCount, factory.ActiveComponentsCount, usedSources);

            // Go through each simulation point separately - it is necessary in order to correctly determine op-amp operation at each specific point
            for (int i = 0; i < pointsCount; ++i)
            {
                // Use the helper to obtain instantenous potentials
                var instantenousValues = FullCycleInstantenousValuesHelper(factory, i, timeStep, includeDCBias);

                // Loop until correct op-amp operation is found
                while (!factory.CheckOpAmpOperationWithSelfAdjustment(instantenousValues.Combine().Potentials))
                {
                    // If the op-amp operation was adjusted, recalculate the instantenous values
                    instantenousValues = FullCycleInstantenousValuesHelper(factory, i, timeStep, includeDCBias);
                }

                // For each state
                foreach (var state in instantenousValues.States.Values)
                {
                    // And for each node
                    foreach (var index in nodeIndices)
                    {
                        // Add the calculated potential for state at node 'index' to the adjusted result waveform.
                        // Lists are empty - points should just be added to them to form a full waveform.
                        adjustedState.States[state.SourceDescription].Potentials[index].Add(
                            instantenousValues.States[state.SourceDescription].Potentials[index]);
                    }

                    // Add the instantenous values of active components currents to the waveforms - just like currents
                    foreach (var index in factory.ActiveComponents)
                    {
                        adjustedState.States[state.SourceDescription].Currents[index].Add(
                            instantenousValues.States[state.SourceDescription].Currents[index]);
                    }
                }

                // Finally reset the op-amp operation for next iteration
                factory.ResetOpAmpOperation();
            }

            // Create simulation results
            IoC.Resolve <SimulationResultsProvider>().Value = new SimulationResultsTime(
                // Convert the adjusted state to potentials - specify that reference node should be added
                adjustedState.PotentialsToTimeDomainSignals(timeStep, true),
                adjustedState.CurrentsToTimeDomainSignals(timeStep),
                timeStep,
                0);
        }