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

📄 twoproj.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Copyright 1991 Regents of the University of California.  All rights reserved.Author:	1987 Kartikeya Mayaram, U. C. Berkeley CAD GroupAuthor:	1991 David A. Gates, U. C. Berkeley CAD Group**********//* * Functions for projecting the next solution point for use with the modified  * two-level Newton scheme */#include <math.h>#include "numglobs.h"#include "numenum.h"#include "nummacs.h"#include "twomesh.h"#include "twodev.h"#define MIN_DELV 1e-3/* Forward Declarations */void storeNewRhs(), TWOstoreInitialGuess();double guessNewConc();void NUMD2project( pDevice, delV )     TWOdevice *pDevice;     double delV;{  TWOnode *pNode;  TWOelem *pElem;  int index, eIndex, numContactNodes;  TWOcontact *pContact = pDevice->pLastContact;  double *incVpn, *solution = pDevice->dcSolution;  double delPsi, delN, delP, newN, newP;    delV = -delV / VNorm;  /* update the boundary condition for the last contact */  numContactNodes = pContact->numNodes;  for ( index = 0; index < numContactNodes; index++ ) {    pNode = pContact->pNodes[ index ];    pNode->psi += delV;  }    /*    * store the new rhs for computing the incremental quantities   * with the second to last node. solve the system of equations   */    if ( ABS(delV) < MIN_DELV ) {    TWOstoreInitialGuess( pDevice );    return;  }  incVpn = pDevice->dcDeltaSolution;  storeNewRhs( pDevice, pContact );  spSolve( pDevice->matrix, pDevice->rhs, incVpn);    for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {    pElem = pDevice->elements[ eIndex ];    for ( index = 0; index <= 3; index++ ) {      if ( pElem->evalNodes[ index ] ) {	pNode = pElem->pNodes[ index ];	if ( pNode->nodeType ISNOT CONTACT ) {	  delPsi = incVpn[ pNode->psiEqn ] * delV;	  solution[ pNode->psiEqn ] = pNode->psi + delPsi;	  if ( pElem->elemType IS SEMICON	      AND (NOT OneCarrier OR OneCarrier IS N_TYPE) ) {	    delN = incVpn[ pNode->nEqn ] * delV;	    newN = pNode->nConc + delN;	    if ( newN <= 0.0 ) {	      solution[ pNode->nEqn ] = guessNewConc( pNode->nConc, delN );	    }	    else {	      solution[ pNode->nEqn ] = newN;	    }	  }	  if ( pElem->elemType IS SEMICON	      AND (NOT OneCarrier OR OneCarrier IS P_TYPE) ) {	    delP = incVpn[ pNode->pEqn ] * delV;	    newP = pNode->pConc + delP;	    if ( newP <= 0.0 ) {	      solution[ pNode->pEqn ] = guessNewConc( pNode->pConc, delP );	    }	    else {	      solution[ pNode->pEqn ] = newP;	    }	  }	}      }    }  }}void NBJT2project( pDevice, delVce, delVbe )     TWOdevice *pDevice;     double delVce, delVbe;{  TWOnode *pNode;  TWOelem *pElem;  int index, eIndex, numContactNodes;  TWOcontact *pColContact = pDevice->pFirstContact;  TWOcontact *pBaseContact = pDevice->pFirstContact->next;  double *incVce, *incVbe, *solution = pDevice->dcSolution;  double delPsi, delN, delP, newN, newP;  double nConc, pConc;    /* Normalize the voltages for calculations. */  if ( delVce ISNOT 0.0 ) {    delVce = delVce / VNorm;    numContactNodes = pColContact->numNodes;    for ( index = 0; index < numContactNodes; index++ ) {      pNode = pColContact->pNodes[ index ];      pNode->psi += delVce;    }  }  if ( delVbe ISNOT 0.0 ) {    delVbe = delVbe / VNorm;    numContactNodes = pBaseContact->numNodes;    for ( index = 0; index < numContactNodes; index++ ) {      pNode = pBaseContact->pNodes[ index ];      pNode->psi += delVbe;    }  }    /*    * store the new rhs for computing the incremental quantities   * incVce (dcDeltaSolution) and incVbe (copiedSolution) are used to   * store the incremental quantities associated with Vce and Vbe   */    /* set incVce = dcDeltaSolution; incVbe = copiedSolution */    if ( ABS( delVce ) > MIN_DELV ) {    incVce = pDevice->dcDeltaSolution;    storeNewRhs( pDevice, pColContact );    spSolve( pDevice->matrix, pDevice->rhs, incVce);        for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {      pElem = pDevice->elements[ eIndex ];      for ( index = 0; index <= 3; index++ ) {	if ( pElem->evalNodes[ index ] ) {	  pNode = pElem->pNodes[ index ];	  if ( pNode->nodeType ISNOT CONTACT ) {	    delPsi = incVce[ pNode->psiEqn ] * delVce;	    solution[ pNode->psiEqn ] = pNode->psi + delPsi;	    if ( pElem->elemType IS SEMICON		AND (NOT OneCarrier OR OneCarrier IS N_TYPE) ) {	      delN = incVce[ pNode->nEqn ] * delVce;	      newN = pNode->nConc + delN;	      if ( newN <= 0.0 ) {		solution[ pNode->nEqn ] = guessNewConc( pNode->nConc, delN );	      }	      else {		solution[ pNode->nEqn ] = newN;	      }	    }	    if ( pElem->elemType IS SEMICON		AND (NOT OneCarrier OR OneCarrier IS P_TYPE) ) {	      delP = incVce[ pNode->pEqn ] * delVce;	      newP = pNode->pConc + delP;	      if ( newP <= 0.0 ) {		solution[ pNode->pEqn ] = guessNewConc( pNode->pConc, delP );	      }	      else {		solution[ pNode->pEqn ] = newP;	      }	    }	  }	}      }    }  }  else {    TWOstoreInitialGuess( pDevice );  }    if ( ABS( delVbe ) > MIN_DELV ) {    incVbe = pDevice->copiedSolution;    storeNewRhs( pDevice, pBaseContact );    spSolve( pDevice->matrix, pDevice->rhs, incVbe);        for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {      pElem = pDevice->elements[ eIndex ];      for ( index = 0; index <= 3; index++ ) {	if ( pElem->evalNodes[ index ] ) {	  pNode = pElem->pNodes[ index ];	  if ( pNode->nodeType ISNOT CONTACT ) {	    delPsi = incVbe[ pNode->psiEqn ] * delVbe;	    solution[ pNode->psiEqn ] += delPsi;	    if ( pElem->elemType IS SEMICON		AND (NOT OneCarrier OR OneCarrier IS N_TYPE) ) {	      delN = incVbe[ pNode->nEqn ] * delVbe;	      nConc = solution[ pNode->nEqn ];	      newN = nConc + delN;	      if ( newN <= 0.0 ) {		solution[ pNode->nEqn ] = guessNewConc( nConc, delN );	      }	      else {		solution[ pNode->nEqn ] = newN;	      }	    }	    if ( pElem->elemType IS SEMICON		AND (NOT OneCarrier OR OneCarrier IS P_TYPE) ) {	      delP = incVbe[ pNode->pEqn ] * delVbe;	      pConc = solution[ pNode->pEqn ];	      newP = pConc + delP;	      if ( newP <= 0.0 ) {		solution[ pNode->pEqn ] = guessNewConc( pConc, delP );	      }	      else {		solution[ pNode->pEqn ] = newP;	      }	    }	  }	}      }    }  }}void NUMOSproject( pDevice, delVdb, delVsb, delVgb )     TWOdevice *pDevice;     double delVdb, delVsb, delVgb;{  TWOnode *pNode;  TWOelem *pElem;  int index, eIndex, numContactNodes;  TWOcontact *pDContact = pDevice->pFirstContact;  TWOcontact *pGContact = pDevice->pFirstContact->next;  TWOcontact *pSContact = pDevice->pFirstContact->next->next;  double *incVdb, *incVsb, *incVgb, *solution = pDevice->dcSolution;  double delPsi, delN, delP, newN, newP;  double nConc, pConc;    /* normalize the voltages for calculations */  if ( delVdb ISNOT 0.0 ) {    delVdb = delVdb / VNorm;    numContactNodes = pDContact->numNodes;    for ( index = 0; index < numContactNodes; index++ ) {      pNode = pDContact->pNodes[ index ];      pNode->psi += delVdb;    }  }  if ( delVsb ISNOT 0.0 ) {    delVsb = delVsb / VNorm;    numContactNodes = pSContact->numNodes;    for ( index = 0; index < numContactNodes; index++ ) {      pNode = pSContact->pNodes[ index ];      pNode->psi += delVsb;    }  }  if ( delVgb ISNOT 0.0 ) {    delVgb = delVgb / VNorm;    numContactNodes = pGContact->numNodes;    for ( index = 0; index < numContactNodes; index++ ) {      pNode = pGContact->pNodes[ index ];      pNode->psi += delVgb;    }  }    /*    * store the new rhs for computing the incremental quantities   * incVdb (dcDeltaSolution), incVsb, incVgb    */    if ( ABS( delVdb ) > MIN_DELV ) {        incVdb = pDevice->dcDeltaSolution;    storeNewRhs( pDevice, pDContact );    spSolve( pDevice->matrix, pDevice->rhs, incVdb);        for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {      pElem = pDevice->elements[ eIndex ];      for ( index = 0; index <= 3; index++ ) {	if ( pElem->evalNodes[ index ] ) {	  pNode = pElem->pNodes[ index ];	  if ( pNode->nodeType ISNOT CONTACT ) {	    delPsi = incVdb[ pNode->psiEqn ] * delVdb;	    solution[ pNode->psiEqn ] = pNode->psi + delPsi;	    if ( pElem->elemType IS SEMICON		AND (NOT OneCarrier OR OneCarrier IS N_TYPE) ) {	      delN = incVdb[ pNode->nEqn ] * delVdb;	      newN = pNode->nConc + delN;	      if ( newN <= 0.0 ) {		solution[ pNode->nEqn ] = guessNewConc( pNode->nConc, delN );	      }	      else {		solution[ pNode->nEqn ] = newN;	      }	    }	    if ( pElem->elemType IS SEMICON		AND (NOT OneCarrier OR OneCarrier IS P_TYPE) ) {	      delP = incVdb[ pNode->pEqn ] * delVdb;	      newP = pNode->pConc + delP;	      if ( newP <= 0.0 ) {		solution[ pNode->pEqn ] = guessNewConc( pNode->pConc, delP );	      }	      else {		solution[ pNode->pEqn ] = newP;	      }	    }	  }	}      }    }  }  else {    TWOstoreInitialGuess( pDevice );  }    if ( ABS( delVsb ) > MIN_DELV ) {        incVsb = pDevice->dcDeltaSolution;    storeNewRhs( pDevice, pSContact );    spSolve( pDevice->matrix, pDevice->rhs, incVsb);        for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {      pElem = pDevice->elements[ eIndex ];      for ( index = 0; index <= 3; index++ ) {	if ( pElem->evalNodes[ index ] ) {	  pNode = pElem->pNodes[ index ];	  if ( pNode->nodeType ISNOT CONTACT ) {	    delPsi = incVsb[ pNode->psiEqn ] * delVsb;	    solution[ pNode->psiEqn ] += delPsi;	    if ( pElem->elemType IS SEMICON		AND (NOT OneCarrier OR OneCarrier IS N_TYPE) ) {	      delN = incVsb[ pNode->nEqn ] * delVsb;	      nConc = solution[ pNode->nEqn ];	      newN = nConc + delN;	      if ( newN <= 0.0 ) {		solution[ pNode->nEqn ] = guessNewConc( nConc, delN );	      }	      else {		solution[ pNode->nEqn ] = newN;	      }	    }	    if ( pElem->elemType IS SEMICON		AND (NOT OneCarrier OR OneCarrier IS P_TYPE) ) {	      delP = incVsb[ pNode->pEqn ] * delVsb;	      pConc = solution[ pNode->pEqn ];	      newP = pConc + delP;	      if ( newP <= 0.0 ) {		solution[ pNode->pEqn ] = guessNewConc( pConc, delP );	      }	      else {

⌨️ 快捷键说明

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