Ejemplo n.º 1
0
    def solve(self, refnode=gnd, period=1e-3, x0=None, timestep=1e-6, maxiterations=20):
        self.period = period
        toolkit = self.toolkit

        irefnode = self.cir.get_node_index(refnode)
        n = self.cir.n
        dt = timestep
        if x0 is None:
            x = toolkit.zeros(n - 1)  # currently without reference node !
        else:
            x = x0  # reference node not included !

        # create vector with timepoints and a more fitting dt
        times, dt = toolkit.linspace(0, period, num=int(period / dt), endpoint=True, retstep=True)
        alpha = 1

        def func(x):
            x = self.solve_timestep(x, times[0], dt)
            x0 = copy(x)
            Jshoot = np.mat(toolkit.eye(n - 1))
            C = copy(np.mat(self._C))

            ## Save C and transient jacobian for PAC analysis
            self.Cvec = [copy(self._C)]
            self.Jtvec = [copy(self._Jf)]
            self.times = times
            for t in times[1:]:
                x = copy(self.solve_timestep(x, t, dt))
                self.Cvec.append(copy(self._C))
                self.Jtvec.append(copy(self._Jf))
                Jshoot = np.mat(self._Jf).I * C * Jshoot
                C = copy(np.mat(self._C))

            residual = x0 - x

            D = np.mat(toolkit.eye(n - 1))
            return residual, D - alpha * Jshoot

        ## Find periodic steady state x-vector
        x0_ss = analysis.fsolve(func, x, maxiter=maxiterations, toolkit=self.toolkit)

        X = [x0_ss]
        for t in times:
            x = self.solve_timestep(X[-1], t, dt)
            X.append(copy(x))

        X = toolkit.array(X[1:]).T

        # Insert reference node voltage
        X = toolkit.concatenate((X[:irefnode], toolkit.zeros((1, len(times))), X[irefnode:]))

        tpss = analysis.CircuitResult(self.cir, x=X, xdot=None, sweep_values=times, sweep_label="time", sweep_unit="s")

        freqs, FX = freq_analysis(X[:, :-1], times[:-1])

        fpss = analysis.CircuitResult(
            self.cir, x=FX, xdot=None, sweep_values=freqs, sweep_label="freq", sweep_unit="Hz"
        )

        return InternalResultDict({"tpss": tpss, "fpss": fpss})
Ejemplo n.º 2
0
    def solve_timestep(self, x0, t, dt, refnode=gnd):
        toolkit = self.toolkit
        concatenate, array = toolkit.concatenate, toolkit.array

        n = self.cir.n
        analysis_name = self.par.analysis
        ## Refer the voltages to the reference node by removing
        ## the rows and columns that corresponds to this node
        irefnode = self.cir.get_node_index(refnode)

        def func(x):
            x = concatenate((x[:irefnode], array([0.0]), x[irefnode:]))
            xlast = concatenate((x0[:irefnode], array([0.0]), x0[irefnode:]))
            C = self.cir.C(x)
            Geq = C / dt
            ueq = -self.cir.q(xlast) / dt
            f = self.cir.i(x) + self.cir.q(x) / dt + self.cir.u(
                t, analysis=analysis_name) + ueq
            J = self.cir.G(x) + Geq
            (f, J, C) = remove_row_col((f, J, C), irefnode, self.toolkit)
            self._Jf, self._C = J, C
            return f, J

        x = analysis.fsolve(func,
                            x0,
                            reltol=self.par.reltol,
                            toolkit=self.toolkit)
        # Insert reference node voltage
        #x = concatenate((x[:irefnode], array([0.0]), x[irefnode:]))
        return x
Ejemplo n.º 3
0
    def solve_timestep(self, x0, t, dt, refnode=gnd):
        toolkit = self.toolkit
        concatenate, array = toolkit.concatenate, toolkit.array

        n = self.cir.n
        analysis_name = self.par.analysis
        ## Refer the voltages to the reference node by removing
        ## the rows and columns that corresponds to this node
        irefnode = self.cir.get_node_index(refnode)

        def func(x):
            x = concatenate((x[:irefnode], array([0.0]), x[irefnode:]))
            xlast = concatenate((x0[:irefnode], array([0.0]), x0[irefnode:]))
            C = self.cir.C(x)
            Geq = C / dt
            ueq = -self.cir.q(xlast) / dt
            f = self.cir.i(x) + self.cir.q(x) / dt + self.cir.u(t, analysis=analysis_name) + ueq
            J = self.cir.G(x) + Geq
            (f, J, C) = remove_row_col((f, J, C), irefnode, self.toolkit)
            self._Jf, self._C = J, C
            return f, J

        x = analysis.fsolve(func, x0, reltol=self.par.reltol, toolkit=self.toolkit)
        # Insert reference node voltage
        # x = concatenate((x[:irefnode], array([0.0]), x[irefnode:]))
        return x
Ejemplo n.º 4
0
    def solve(self,
              refnode=gnd,
              period=1e-3,
              x0=None,
              timestep=1e-6,
              maxiterations=20):
        self.period = period
        toolkit = self.toolkit

        irefnode = self.cir.get_node_index(refnode)
        n = self.cir.n
        dt = timestep
        if x0 is None:
            x = toolkit.zeros(n - 1)  #currently without reference node !
        else:
            x = x0  # reference node not included !

        #create vector with timepoints and a more fitting dt
        times, dt = toolkit.linspace(0,
                                     period,
                                     num=int(period / dt),
                                     endpoint=True,
                                     retstep=True)
        alpha = 1

        def func(x):
            x = self.solve_timestep(x, times[0], dt)
            x0 = copy(x)
            Jshoot = np.mat(toolkit.eye(n - 1))
            C = copy(np.mat(self._C))

            ## Save C and transient jacobian for PAC analysis
            self.Cvec = [copy(self._C)]
            self.Jtvec = [copy(self._Jf)]
            self.times = times
            for t in times[1:]:
                x = copy(self.solve_timestep(x, t, dt))
                self.Cvec.append(copy(self._C))
                self.Jtvec.append(copy(self._Jf))
                Jshoot = np.mat(self._Jf).I * C * Jshoot
                C = copy(np.mat(self._C))

            residual = x0 - x

            D = np.mat(toolkit.eye(n - 1))
            return residual, D - alpha * Jshoot

        ## Find periodic steady state x-vector
        x0_ss = analysis.fsolve(func,
                                x,
                                maxiter=maxiterations,
                                toolkit=self.toolkit)

        X = [x0_ss]
        for t in times:
            x = self.solve_timestep(X[-1], t, dt)
            X.append(copy(x))

        X = toolkit.array(X[1:]).T

        # Insert reference node voltage
        X = toolkit.concatenate((X[:irefnode], toolkit.zeros(
            (1, len(times))), X[irefnode:]))

        tpss = analysis.CircuitResult(self.cir,
                                      x=X,
                                      xdot=None,
                                      sweep_values=times,
                                      sweep_label='time',
                                      sweep_unit='s')

        freqs, FX = freq_analysis(X[:, :-1], times[:-1])

        fpss = analysis.CircuitResult(self.cir,
                                      x=FX,
                                      xdot=None,
                                      sweep_values=freqs,
                                      sweep_label='freq',
                                      sweep_unit='Hz')

        return InternalResultDict({'tpss': tpss, 'fpss': fpss})