Exemple #1
0
    def solve_homotopy_gmin2(self, x0, sV):
        """Newton's method with gmin stepping (nonlinear ports)"""
        # Adds gmin in parallel with nonlinear element (external) ports
        # Create Gmin matrix (structure is fixed)
        Gonesll = pysparse.spmatrix.ll_mat(self.ckt.nD_dimension, 
                                            self.ckt.nD_dimension)
        for elem in self.ckt.nD_nlinElem:
            Gadd = np.eye(len(elem.nD_extPorts))
            # import pdb; pdb.set_trace()
            set_Jac(Gonesll, elem.nD_epos, elem.nD_eneg, 
                    elem.nD_epos, elem.nD_eneg, Gadd)
        Gones = Gonesll.to_csr()
        tmpVec =  np.empty(self.ckt.nD_dimension)

        def get_deltax(xVec):
            (iVec, Jac) = self.get_i_Jac(xVec) 
            Gones.matvec(xVec, tmpVec)
            iVec += self.gmin * tmpVec
            Jac.shift(self.gmin, Gonesll)
            return self._get_deltax(iVec - sV, Jac)
        def f_eval(xVec):
            iVec = self.get_i(xVec)
            self.Gones.matvec(xVec, tmpVec)
            iVec += self.gmin * tmpVec
            return iVec - sV
        (x, res, iterations, success) = \
            self._homotopy(0.5, self._set_gmin, x0, get_deltax, f_eval)
        if success:
            return (x, res, iterations)
        else:
            raise NoConvergenceError('gmin stepping did not converge')
Exemple #2
0
    def get_i_Jac(self, xVec):
        """
        Calculate total current and Jacobian

        Returns (iVec, Jac)::

            iVec = G xVec + i(xVec)
            Jac = G + (di/dx)(xVec)

        xVec: input vector of nodal voltages. 

        iVec: output vector of currents

        Jac: system Jacobian
        """
        # Erase sparse matrix
        self.Jac.scale(0.)
        # Linear contribution
        self.G.matvec(xVec, self.iVec)
        self.Jac.shift(1., self.Gll)
        # Nonlinear contribution
        for elem in self.ckt.nD_nlinElem:
            # first have to retrieve port voltages from xVec
            xin = np.zeros(len(elem.controlPorts))
            set_xin(xin, elem.nD_vpos, elem.nD_vneg, xVec)
            (outV, outJac) = elem.eval_and_deriv(xin)
            # Update iVec and Jacobian now. outV may have extra charge
            # elements but they are not used in the following
            set_i(self.iVec, elem.nD_cpos, elem.nD_cneg, outV)
            set_Jac(self.Jac, elem.nD_cpos, elem.nD_cneg, 
                    elem.nD_vpos, elem.nD_vneg, outJac)

        return (self.iVec, self.Jac)
Exemple #3
0
    def solve_homotopy_gmin2(self, x0, sV):
        """Newton's method with gmin stepping (nonlinear ports)"""
        # Adds gmin in parallel with nonlinear element (external) ports
        # Create Gmin matrix (structure is fixed)
        Gonesll = pysparse.spmatrix.ll_mat(self.ckt.nD_dimension,
                                           self.ckt.nD_dimension)
        for elem in self.ckt.nD_nlinElem:
            Gadd = np.eye(len(elem.nD_extPorts))
            # import pdb; pdb.set_trace()
            set_Jac(Gonesll, elem.nD_epos, elem.nD_eneg, elem.nD_epos,
                    elem.nD_eneg, Gadd)
        Gones = Gonesll.to_csr()
        tmpVec = np.empty(self.ckt.nD_dimension)

        def get_deltax(xVec):
            (iVec, Jac) = self.get_i_Jac(xVec)
            Gones.matvec(xVec, tmpVec)
            iVec += self.gmin * tmpVec
            Jac.shift(self.gmin, Gonesll)
            return self._get_deltax(iVec - sV, Jac)

        def f_eval(xVec):
            iVec = self.get_i(xVec)
            self.Gones.matvec(xVec, tmpVec)
            iVec += self.gmin * tmpVec
            return iVec - sV
        (x, res, iterations, success) = \
            self._homotopy(0.5, self._set_gmin, x0, get_deltax, f_eval)
        if success:
            return (x, res, iterations)
        else:
            raise NoConvergenceError('gmin stepping did not converge')
Exemple #4
0
    def get_i_Jac(self, xVec):
        """
        Calculate total current and Jacobian

        Returns (iVec, Jac)::

            iVec = G xVec + i(xVec)
            Jac = G + (di/dx)(xVec)

        xVec: input vector of nodal voltages. 

        iVec: output vector of currents

        Jac: system Jacobian
        """
        # Erase sparse matrix
        self.Jac.scale(0.)
        # Linear contribution
        self.G.matvec(xVec, self.iVec)
        self.Jac.shift(1., self.Gll)
        # Nonlinear contribution
        for elem in self.ckt.nD_nlinElem:
            # first have to retrieve port voltages from xVec
            xin = np.zeros(len(elem.controlPorts))
            set_xin(xin, elem.nD_vpos, elem.nD_vneg, xVec)
            (outV, outJac) = elem.eval_and_deriv(xin)
            # Update iVec and Jacobian now. outV may have extra charge
            # elements but they are not used in the following
            set_i(self.iVec, elem.nD_cpos, elem.nD_cneg, outV)
            set_Jac(self.Jac, elem.nD_cpos, elem.nD_cneg, elem.nD_vpos,
                    elem.nD_vneg, outJac)

        return (self.iVec, self.Jac)
Exemple #5
0
    def refresh(self):
        """
        Re-generate linear matrices

        Used for parameter sweeps
        """
        self.Gll = pysparse.spmatrix.ll_mat(self.ckt.nD_dimension, 
                                            self.ckt.nD_dimension)
        # Generate G matrix (never changes)
        for elem in self.ckt.nD_elemList:
            # All elements have nD_linVCCS (perhaps empty)
            for vccs in elem.nD_linVCCS:
                set_quad(self.Gll, *vccs)
        # Frequency-defined elements
        for elem in self.ckt.nD_freqDefinedElem:
            set_Jac(self.Gll, elem.nD_fpos, elem.nD_fneg, 
                    elem.nD_fpos, elem.nD_fneg, elem.get_G_matrix())
        # Free unused memory
        self.Gll.compress()        
        # Create G in csr form for efficient matrix-vector multiplication
        self.G = self.Gll.to_csr()
Exemple #6
0
    def refresh(self):
        """
        Re-generate linear matrices

        Used for parameter sweeps
        """
        self.Gll = pysparse.spmatrix.ll_mat(self.ckt.nD_dimension,
                                            self.ckt.nD_dimension)
        # Generate G matrix (never changes)
        for elem in self.ckt.nD_elemList:
            # All elements have nD_linVCCS (perhaps empty)
            for vccs in elem.nD_linVCCS:
                set_quad(self.Gll, *vccs)
        # Frequency-defined elements
        for elem in self.ckt.nD_freqDefinedElem:
            set_Jac(self.Gll, elem.nD_fpos, elem.nD_fneg, elem.nD_fpos,
                    elem.nD_fneg, elem.get_G_matrix())
        # Free unused memory
        self.Gll.compress()
        # Create G in csr form for efficient matrix-vector multiplication
        self.G = self.Gll.to_csr()