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

📄 nicomcof.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Thomas L. Quarles**********/#include "spice.h"#include <stdio.h>#include "cktdefs.h"#include "sperror.h"#include "suffix.h"intNIcomCof(ckt)    CKTcircuit *ckt;{    double mat[8][8];   /* matrix to compute the gear coefficients in */    int i,j,k;          /* generic loop indicies */    double arg;    double arg1;    /*  this routine calculates the timestep-dependent terms used in the     *  numerical integration.     */     /*       *  compute coefficients for particular integration method      */     switch(ckt->CKTintegrateMethod) {    case TRAPEZOIDAL:        switch(ckt->CKTorder) {        case 1:            ckt->CKTag[0] = 1/ckt->CKTdelta;            ckt->CKTag[1] = -1/ckt->CKTdelta;            break;        case 2:            ckt->CKTag[0]=1.0/ckt->CKTdelta/(1.0-0.5) ;            ckt->CKTag[1]=0.5/(1.0 - 0.5) ;            /* above lines should have 'xmu' instead of .5 eventually */            /* (in all three places) */            break;        default:            return(E_ORDER);        }        break;    case GEAR:        switch(ckt->CKTorder) {        case 1:        /*  ckt->CKTag[0] = 1/ckt->CKTdelta;            ckt->CKTag[1] = -1/ckt->CKTdelta;            break;*/        case 2:        case 3:        case 4:        case 5:        case 6:            bzero(ckt->CKTag,7*sizeof(double));            ckt->CKTag[1] = -1/ckt->CKTdelta;            /* first, set up the matrix */            arg=0;            for(i=0;i<=ckt->CKTorder;i++) { mat[0][i]=1; }            for(i=1;i<=ckt->CKTorder;i++) { mat[i][0]=0; }            /* SPICE2 difference warning             * the following block builds the corrector matrix             * using (sum of h's)/h(final) instead of just (sum of h's)             * because the h's are typically ~1e-10, so h^7 is an             * underflow on many machines, but the ratio is ~1             * and produces much better results             */            for(i=1;i<=ckt->CKTorder;i++) {                arg += ckt->CKTdeltaOld[i-1];                arg1 = 1;                for(j=1;j<=ckt->CKTorder;j++) {                    arg1 *= arg/ckt->CKTdelta;                    mat[j][i]=arg1;                }            }            /* lu decompose */            /* weirdness warning!              * The following loop (and the first one after the forward             * substitution comment) start at one instead of zero             * because of a SPECIAL CASE - the first column is 1 0 0 ...             * thus, the first iteration of both loops does nothing,             * so it is skipped             */            for(i=1;i<=ckt->CKTorder;i++) {                for(j=i+1;j<=ckt->CKTorder;j++) {                    mat[j][i] /= mat[i][i];                    for(k=i+1;k<=ckt->CKTorder;k++) {                        mat[j][k] -= mat[j][i]*mat[i][k];                    }                }            }            /* forward substitution */            for(i=1;i<=ckt->CKTorder;i++) {                for(j=i+1;j<=ckt->CKTorder;j++) {                    ckt->CKTag[j]=ckt->CKTag[j]-mat[j][i]*ckt->CKTag[i];                }            }            /* backward substitution */            ckt->CKTag[ckt->CKTorder] /= mat[ckt->CKTorder][ckt->CKTorder];            for(i=ckt->CKTorder-1;i>=0;i--) {                for(j=i+1;j<=ckt->CKTorder;j++) {                    ckt->CKTag[i]=ckt->CKTag[i]-mat[i][j]*ckt->CKTag[j];                }                ckt->CKTag[i] /= mat[i][i];            }            break;                        default:            return(E_ORDER);        }        break;    default:        return(E_METHOD);    }#ifdef PREDICTOR    /* ok, have the coefficients for corrector, now for the predictor */    switch(ckt->CKTintegrateMethod) {    default:        return(E_METHOD);    case TRAPEZOIDAL:        /*   ADAMS-BASHFORD PREDICTOR FOR TRAPEZOIDAL CORRECTOR         *     MAY BE SUPPLEMENTED BY SECOND ORDER GEAR CORRECTOR         *     AGP(1) STORES b0 AND AGP(2) STORES b1         */        arg = ckt->CKTdelta/(2*ckt->CKTdeltaOld[1]);        ckt->CKTagp[0] = 1+arg;        ckt->CKTagp[1] = -arg;        break;    case GEAR:        /*         *  CONSTRUCT GEAR PREDICTOR COEFICENT MATRIX         *  MUST STILL ACCOUNT FOR ARRAY AGP()         *  KEEP THE SAME NAME FOR GMAT         */        bzero(ckt->CKTagp,7*sizeof(double));        /*   SET UP RHS OF EQUATIONS */        ckt->CKTagp[0]=1;        for(i=0;i<=ckt->CKTorder;i++) {            mat[0][i] = 1;        }        arg = 0;        for(i=0;i<=ckt->CKTorder;i++){            arg += ckt->CKTdeltaOld[i];            arg1 = 1;            for(j=1;j<=ckt->CKTorder;j++) {                arg1 *= arg/ckt->CKTdelta;                mat[j][i]=arg1;            }        }        /*         *  SOLVE FOR GEAR COEFFICIENTS AGP(*)         */        /*         *  LU DECOMPOSITION         */        for(i=0;i<=ckt->CKTorder;i++) {            for(j=i+1;j<=ckt->CKTorder;j++) {                mat[j][i] /= mat[i][i];                for(k=i+1;k<=ckt->CKTorder;k++) {                    mat[j][k] -= mat[j][i]*mat[i][k];                }            }        }        /*         *  FORWARD SUBSTITUTION         */        for(i=0;i<=ckt->CKTorder;i++) {            for(j=i+1;j<=ckt->CKTorder;j++) {                ckt->CKTagp[j] -= mat[j][i]*ckt->CKTagp[i];            }        }        /*         *  BACKWARD SUBSTITUTION         */        ckt->CKTagp[ckt->CKTorder] /= mat[ckt->CKTorder][ckt->CKTorder];        for(i=ckt->CKTorder-1;i>=0;i--) {            for(j=i+1;j<=ckt->CKTorder;j++) {                ckt->CKTagp[i] -= mat[i][j]*ckt->CKTagp[j];            }            ckt->CKTagp[i] /= mat[i][i];        }        /*         *  FINISHED         */        break;    }#endif /* PREDICTOR */    return(OK);}

⌨️ 快捷键说明

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