⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 niiter.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Thomas L. Quarles**********//* * NIiter(ckt,maxIter) * *  This subroutine performs the actual numerical iteration. *  It uses the sparse matrix stored in the circuit struct *  along with the matrix loading program, the load data, the *  convergence test function, and the convergence parameters */#include "spice.h"#include <stdio.h>#include "trandefs.h"#include "cktdefs.h"#include "smpdefs.h"#include "sperror.h"#include "util.h"#include "suffix.h"/* NIiter() - return value is non-zero for convergence failure */intNIiter(ckt,maxIter)    register CKTcircuit * ckt;    int maxIter;{    int iterno;    int ipass;    int error;    int i,j; /* temporaries for finding error location */    char *message;  /* temporary message buffer */    double *temp;    double startTime;    static char *msg = "Too many iterations without convergence";    iterno=0;    ipass=0;    if( (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)){        temp = ckt->CKTrhsOld;        ckt->CKTrhsOld = ckt->CKTrhs;        ckt->CKTrhs = temp;	error = CKTload(ckt);	if(error) {	    return(error);	}        return(OK);    }#ifdef HAS_SENSE2    if(ckt->CKTsenInfo){        error = NIsenReinit(ckt);        if(error) return(error);    }#endif    if(ckt->CKTniState & NIUNINITIALIZED) {        error = NIreinit(ckt);        if(error){#ifdef STEPDEBUG            printf("re-init returned error \n");#endif            return(error);        }    }    for(;;){        ckt->CKTnoncon=0;#ifdef NEWPRED        if(!(ckt->CKTmode & MODEINITPRED)) {#else /* NEWPRED */        if(1) { /* } */#endif /* NEWPRED */            error = CKTload(ckt);            /*printf("loaded, noncon is %d\n",ckt->CKTnoncon);*/            /*fflush(stdout);*/            iterno++;            if(error) {                ckt->CKTstat->STATnumIter += iterno;#ifdef STEPDEBUG                printf("load returned error \n");#endif                return(error);            }            /*printf("after loading, before solving\n");*/            /*CKTdump(ckt);*/            if(!(ckt->CKTniState & NIDIDPREORDER)) {                error = SMPpreOrder(ckt->CKTmatrix);                if(error) {                    ckt->CKTstat->STATnumIter += iterno;#ifdef STEPDEBUG                    printf("pre-order returned error \n");#endif                    return(error); /* badly formed matrix */                }                ckt->CKTniState |= NIDIDPREORDER;            }            if( (ckt->CKTmode & MODEINITJCT) ||                     ( (ckt->CKTmode & MODEINITTRAN) && (iterno==1))) {                ckt->CKTniState |= NISHOULDREORDER;            }            if(ckt->CKTniState & NISHOULDREORDER) {                startTime = (*(SPfrontEnd->IFseconds))();                error = SMPreorder(ckt->CKTmatrix,ckt->CKTpivotAbsTol,                        ckt->CKTpivotRelTol,ckt->CKTdiagGmin);                ckt->CKTstat->STATreorderTime +=                         (*(SPfrontEnd->IFseconds))()-startTime;                if(error) {                    /* new feature - we can now find out something about what is                     * wrong - so we ask for the troublesome entry                      */                    SMPgetError(ckt->CKTmatrix,&i,&j);                    message = (char *)MALLOC(1000); /* should be enough */                    (void)sprintf(message,                            "singular matrix:  check nodes %s and %s\n",                            NODENAME(ckt,i),NODENAME(ckt,j));                    (*(SPfrontEnd->IFerror))(ERR_WARNING,message,(IFuid *)NULL);                    FREE(message);                    ckt->CKTstat->STATnumIter += iterno;#ifdef STEPDEBUG                    printf("reorder returned error \n");#endif                    return(error); /* can't handle these errors - pass up! */                }                ckt->CKTniState &= ~NISHOULDREORDER;            } else {                startTime = (*(SPfrontEnd->IFseconds))();                error=SMPluFac(ckt->CKTmatrix,ckt->CKTpivotAbsTol,                        ckt->CKTdiagGmin);                ckt->CKTstat->STATdecompTime +=                         (*(SPfrontEnd->IFseconds))()-startTime;                if(error) {                    if( error == E_SINGULAR ) {                        ckt->CKTniState |= NISHOULDREORDER;                        DEBUGMSG(" forced reordering....\n");                        continue;                    }                    /*CKTload(ckt);*/                    /*SMPprint(ckt->CKTmatrix,stdout);*/                    /* seems to be singular - pass the bad news up */                    ckt->CKTstat->STATnumIter += iterno;#ifdef STEPDEBUG                    printf("lufac returned error \n");#endif                    return(error);                }            }             startTime = (*(SPfrontEnd->IFseconds))();            SMPsolve(ckt->CKTmatrix,ckt->CKTrhs,ckt->CKTrhsSpare);            ckt->CKTstat->STATsolveTime += (*(SPfrontEnd->IFseconds))()-                    startTime;#ifdef STEPDEBUG/*XXXX*/	    if (*ckt->CKTrhs != 0.0)		    printf("NIiter: CKTrhs[0] = %g\n", *ckt->CKTrhs);	    if (*ckt->CKTrhsSpare != 0.0)		    printf("NIiter: CKTrhsSpare[0] = %g\n", *ckt->CKTrhsSpare);	    if (*ckt->CKTrhsOld != 0.0)		    printf("NIiter: CKTrhsOld[0] = %g\n", *ckt->CKTrhsOld);/*XXXX*/#endif            *ckt->CKTrhs = 0;            *ckt->CKTrhsSpare = 0;            *ckt->CKTrhsOld = 0;            if(iterno > maxIter) {                /*printf("too many iterations without convergence: %d iter's\n",                        iterno);*/                ckt->CKTstat->STATnumIter += iterno;                errMsg = MALLOC(strlen(msg)+1);                strcpy(errMsg,msg);#ifdef STEPDEBUG                    printf("iterlim exceeded \n");#endif                return(E_ITERLIM);            }            if(ckt->CKTnoncon==0 && iterno!=1) {                ckt->CKTnoncon = NIconvTest(ckt);            } else {                ckt->CKTnoncon = 1;            }#ifdef STEPDEBUG            printf("noncon is %d\n",ckt->CKTnoncon);#endif        }        if(ckt->CKTmode & MODEINITFLOAT) {            if ((ckt->CKTmode & MODEDC) &&                    ( ckt->CKThadNodeset)  ) {                if(ipass) {                    ckt->CKTnoncon=ipass;                }                ipass=0;            }            if(ckt->CKTnoncon == 0) {                ckt->CKTstat->STATnumIter += iterno;                return(OK);            }        } else if(ckt->CKTmode & MODEINITJCT) {            ckt->CKTmode = (ckt->CKTmode&(~INITF))|MODEINITFIX;            ckt->CKTniState |= NISHOULDREORDER;        } else if (ckt->CKTmode & MODEINITFIX) {            if(ckt->CKTnoncon==0) ckt->CKTmode =                    (ckt->CKTmode&(~INITF))|MODEINITFLOAT;            ipass=1;        } else if (ckt->CKTmode & MODEINITSMSIG) {            ckt->CKTmode = (ckt->CKTmode&(~INITF))|MODEINITFLOAT;        } else if (ckt->CKTmode & MODEINITTRAN) {            if(iterno<=1) ckt->CKTniState |= NISHOULDREORDER;            ckt->CKTmode = (ckt->CKTmode&(~INITF))|MODEINITFLOAT;        } else if (ckt->CKTmode & MODEINITPRED) {            ckt->CKTmode = (ckt->CKTmode&(~INITF))|MODEINITFLOAT;        } else {            ckt->CKTstat->STATnumIter += iterno;#ifdef STEPDEBUG                printf("bad initf state \n");#endif            return(E_INTERN);            /* impossible - no such INITF flag! */        }            /* build up the lvnim1 array from the lvn array */        temp = ckt->CKTrhsOld;        ckt->CKTrhsOld = ckt->CKTrhs;        ckt->CKTrhs = temp;        /*printf("after loading, after solving\n");*/        /*CKTdump(ckt);*/    }    /*NOTREACHED*/}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -