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

📄 ltraload.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1990 Jaijeet S. Roychowdhury**********/#include "spice.h"#include <stdio.h>#include "util.h"#include "cktdefs.h"#include "ltradefs.h"#include "trandefs.h"#include "sperror.h"#include "suffix.h"intLTRAload(inModel, ckt)  GENmodel *inModel;  register CKTcircuit *ckt;/* * load the appropriate values for the current timepoint into the sparse * matrix and the right-hand-side vector */{  register LTRAmodel *model = (LTRAmodel *) inModel;  register LTRAinstance *here;  double t1, t2, t3;  double qf1, qf2, qf3;  double lf2, lf3;  double v1d, v2d, i1d, i2d;  double dummy1, dummy2;  int isaved;  unsigned tdover;  register int i;  double max, min;  /* loop through all the transmission line models */  for (; model != NULL; model = model->LTRAnextModel) {    if (ckt->CKTmode & MODEDC) {      switch (model->LTRAspecialCase) {      case LTRA_MOD_RG:	dummy1 = model->LTRAlength * sqrt(model->LTRAresist *	    model->LTRAconduct);	dummy2 = exp(-dummy1);	dummy1 = exp(dummy1);	/* LTRA warning: may overflow! */	model->LTRAcoshlrootGR = 0.5 * (dummy1 + dummy2);	if (model->LTRAconduct <= 1.0e-10) {	/* hack! */	  model->LTRArRsLrGRorG = model->LTRAlength *	      model->LTRAresist;	} else {	  model->LTRArRsLrGRorG = 0.5 * (dummy1 -	      dummy2) * sqrt(model->LTRAresist /	      model->LTRAconduct);	}	if (model->LTRAresist <= 1.0e-10) {	/* hack! */	  model->LTRArGsLrGRorR = model->LTRAlength *	      model->LTRAconduct;	} else {	  model->LTRArGsLrGRorR = 0.5 * (dummy1 -	      dummy2) * sqrt(model->LTRAconduct /	      model->LTRAresist);	}	break;      case LTRA_MOD_RC:      case LTRA_MOD_LC:      case LTRA_MOD_RLC:	/* simple resistor-like behaviour */	/* nothing to set up */	break;      default:	return (E_BADPARM);      }				/* switch */    } else {      if ((ckt->CKTmode & MODEINITTRAN) ||	  (ckt->CKTmode & MODEINITPRED)) {	switch (model->LTRAspecialCase) {	case LTRA_MOD_RLC:	case LTRA_MOD_LC:	  if (ckt->CKTtime > model->LTRAtd) {	    tdover = 1;	  } else {	    tdover = 0;	  }	default:	  break;	}	switch (model->LTRAspecialCase) {	case LTRA_MOD_RLC:	  /*	   * set up lists of values of the functions at the necessary	   * timepoints.	   */	  /*	   * set up coefficient lists LTRAh1dashCoeffs, LTRAh2Coeffs,	   * LTRAh3dashCoeffs for current timepoint	   */	  /*	   * NOTE: h1, h2 and h3 here actually refer to h1tilde, h2tilde,	   * h3tilde in the paper	   */	  /*	   * Note: many function evaluations are saved by doing the following	   * all together in one procedure	   */	  (void)	      LTRArlcCoeffsSetup(&(model->LTRAh1dashFirstCoeff),	      &(model->LTRAh2FirstCoeff),	      &(model->LTRAh3dashFirstCoeff),	      model->LTRAh1dashCoeffs, model->LTRAh2Coeffs,	      model->LTRAh3dashCoeffs, model->LTRAmodelListSize,	      model->LTRAtd, model->LTRAalpha, model->LTRAbeta,	      ckt->CKTtime, ckt->CKTtimePoints, ckt->CKTtimeIndex,	      model->LTRAchopReltol, &(model->LTRAauxIndex));	case LTRA_MOD_LC:	  /* setting up the coefficients for interpolation */	  if (tdover) {		/* serious hack -fix! */	    for (i = ckt->CKTtimeIndex; i >= 0; i--) {	      if (*(ckt->CKTtimePoints + i) <		  ckt->CKTtime - model->LTRAtd) {		break;	      }	    }#ifdef LTRADEBUG	    if (i == ckt->CKTtimeIndex) {	      fprintf(stdout, "LTRAload: Warning: timestep larger than delay of line\n");	      fprintf(stdout, "	Time now: %g\n\n", ckt->CKTtime);	    }#endif	    if (i == ckt->CKTtimeIndex)	      i--;#ifdef LTRADEBUG	    if ((i == -1)) {	      printf("LTRAload: mistake: cannot find delayed timepoint\n");	    }#else	    return E_INTERN;#endif	    isaved = i;	    t2 = *(ckt->CKTtimePoints + i);	    t3 = *(ckt->CKTtimePoints + i + 1);	    if ((i != 0) && ((model->LTRAhowToInterp ==			LTRA_MOD_QUADINTERP) || (model->LTRAhowToInterp ==			LTRA_MOD_MIXEDINTERP))) {	      /* quadratic interpolation */	      t1 = *(ckt->CKTtimePoints + i - 1);	      LTRAquadInterp(ckt->CKTtime - model->LTRAtd,		  t1, t2, t3, &qf1, &qf2, &qf3);	    }	    if ((i == 0) || (model->LTRAhowToInterp ==		    LTRA_MOD_MIXEDINTERP) || (model->LTRAhowToInterp		    == LTRA_MOD_LININTERP)) {	/* linear interpolation */	      LTRAlinInterp(ckt->CKTtime - model->LTRAtd,		  t2, t3, &lf2, &lf3);	    }	  }	  /* interpolation coefficients set-up */	  break;	case LTRA_MOD_RC:	  /*	   * set up lists of values of the coefficients at the necessary	   * timepoints.	   */	  /*	   * set up coefficient lists LTRAh1dashCoeffs, LTRAh2Coeffs,	   * LTRAh3dashCoeffs for current timepoint	   */	  /*	   * Note: many function evaluations are saved by doing the following	   * all together in one procedure	   */	  (void)	      LTRArcCoeffsSetup(&(model->LTRAh1dashFirstCoeff),	      &(model->LTRAh2FirstCoeff),	      &(model->LTRAh3dashFirstCoeff),	      model->LTRAh1dashCoeffs, model->LTRAh2Coeffs,	      model->LTRAh3dashCoeffs, model->LTRAmodelListSize,	      model->LTRAcByR, model->LTRArclsqr, ckt->CKTtime,	      ckt->CKTtimePoints, ckt->CKTtimeIndex, model->LTRAchopReltol);	  break;	case LTRA_MOD_RG:	  break;	default:	  return (E_BADPARM);	}      }    }    /* loop through all the instances of the model */    for (here = model->LTRAinstances; here != NULL;	here = here->LTRAnextInstance) {      if (here->LTRAowner != ARCHme) continue;      if ((ckt->CKTmode & MODEDC) ||	  (model->LTRAspecialCase == LTRA_MOD_RG)) {	switch (model->LTRAspecialCase) {	case LTRA_MOD_RG:	  *(here->LTRAibr1Pos1Ptr) += 1.0;	  *(here->LTRAibr1Neg1Ptr) -= 1.0;	  *(here->LTRAibr1Pos2Ptr) -= model->LTRAcoshlrootGR;	  *(here->LTRAibr1Neg2Ptr) += model->LTRAcoshlrootGR;	  *(here->LTRAibr1Ibr2Ptr) += (1 + ckt->CKTgmin) *	      model->LTRArRsLrGRorG;	  *(here->LTRAibr2Ibr2Ptr) += model->LTRAcoshlrootGR;	  *(here->LTRAibr2Pos2Ptr) -= (1 + ckt->CKTgmin) *	      model->LTRArGsLrGRorR;	  *(here->LTRAibr2Neg2Ptr) += (1 + ckt->CKTgmin) *	      model->LTRArGsLrGRorR;	  *(here->LTRAibr2Ibr1Ptr) += 1.0;	  *(here->LTRApos1Ibr1Ptr) += 1.0;	  *(here->LTRAneg1Ibr1Ptr) -= 1.0;	  *(here->LTRApos2Ibr2Ptr) += 1.0;	  *(here->LTRAneg2Ibr2Ptr) -= 1.0;	  here->LTRAinput1 = here->LTRAinput2 = 0.0;	  /*	   * Somewhere else, we have fixed the matrix with zero entries so	   * that SMPpreOrder doesn't have fits	   */	  break;	case LTRA_MOD_LC:	case LTRA_MOD_RLC:	case LTRA_MOD_RC:	/* load a simple resistor */	  *(here->LTRApos1Ibr1Ptr) += 1.0;	  *(here->LTRAneg1Ibr1Ptr) -= 1.0;	  *(here->LTRApos2Ibr2Ptr) += 1.0;	  *(here->LTRAneg2Ibr2Ptr) -= 1.0;	  *(here->LTRAibr1Ibr1Ptr) += 1.0;	  *(here->LTRAibr1Ibr2Ptr) += 1.0;	  *(here->LTRAibr2Pos1Ptr) += 1.0;	  *(here->LTRAibr2Pos2Ptr) -= 1.0;	  *(here->LTRAibr2Ibr1Ptr) -= model->LTRAresist * model->LTRAlength;	  here->LTRAinput1 = here->LTRAinput2 = 0.0;	  break;	default:	  return (E_BADPARM);	}      } else {	/* all cases other than DC or the RG case */	/* first timepoint after zero */	if (ckt->CKTmode & MODEINITTRAN) {	  if (!(ckt->CKTmode & MODEUIC)) {	    here->LTRAinitVolt1 =		(*(ckt->CKTrhsOld + here->LTRAposNode1)		- *(ckt->CKTrhsOld + here->LTRAnegNode1));	    here->LTRAinitVolt2 =		(*(ckt->CKTrhsOld + here->LTRAposNode2)		- *(ckt->CKTrhsOld + here->LTRAnegNode2));	    here->LTRAinitCur1 = *(ckt->CKTrhsOld + here->LTRAbrEq1);	    here->LTRAinitCur2 = *(ckt->CKTrhsOld + here->LTRAbrEq2);	  }	}	/* matrix loading - done every time LTRAload is called */	switch (model->LTRAspecialCase) {	case LTRA_MOD_RLC:	  /* loading for convolution parts' first terms */	  dummy1 = model->LTRAadmit * model->LTRAh1dashFirstCoeff;	  *(here->LTRAibr1Pos1Ptr) += dummy1;	  *(here->LTRAibr1Neg1Ptr) -= dummy1;	  *(here->LTRAibr2Pos2Ptr) += dummy1;	  *(here->LTRAibr2Neg2Ptr) -= dummy1;	  /* end loading for convolution parts' first terms */	case LTRA_MOD_LC:	  /*	   * this section loads for the parts of the equations that resemble	   * the lossless equations	   */	  *(here->LTRAibr1Pos1Ptr) += model->LTRAadmit;	  *(here->LTRAibr1Neg1Ptr) -= model->LTRAadmit;	  *(here->LTRAibr1Ibr1Ptr) -= 1.0;	  *(here->LTRApos1Ibr1Ptr) += 1.0;	  *(here->LTRAneg1Ibr1Ptr) -= 1.0;	  *(here->LTRAibr2Pos2Ptr) += model->LTRAadmit;	  *(here->LTRAibr2Neg2Ptr) -= model->LTRAadmit;	  *(here->LTRAibr2Ibr2Ptr) -= 1.0;	  *(here->LTRApos2Ibr2Ptr) += 1.0;	  *(here->LTRAneg2Ibr2Ptr) -= 1.0;	  /* loading for lossless-like parts over */	  break;	case LTRA_MOD_RC:	  /*	   * this section loads for the parts of the equations that have no	   * convolution	   */	  *(here->LTRAibr1Ibr1Ptr) -= 1.0;	  *(here->LTRApos1Ibr1Ptr) += 1.0;	  *(here->LTRAneg1Ibr1Ptr) -= 1.0;	  *(here->LTRAibr2Ibr2Ptr) -= 1.0;	  *(here->LTRApos2Ibr2Ptr) += 1.0;	  *(here->LTRAneg2Ibr2Ptr) -= 1.0;	  /* loading for non-convolution parts over */	  /* loading for convolution parts' first terms */	  dummy1 = model->LTRAh1dashFirstCoeff;	  *(here->LTRAibr1Pos1Ptr) += dummy1;	  *(here->LTRAibr1Neg1Ptr) -= dummy1;	  *(here->LTRAibr2Pos2Ptr) += dummy1;	  *(here->LTRAibr2Neg2Ptr) -= dummy1;	  dummy1 = model->LTRAh2FirstCoeff;	  *(here->LTRAibr1Ibr2Ptr) -= dummy1;	  *(here->LTRAibr2Ibr1Ptr) -= dummy1;	  dummy1 = model->LTRAh3dashFirstCoeff;	  *(here->LTRAibr1Pos2Ptr) -= dummy1;	  *(here->LTRAibr1Neg2Ptr) += dummy1;	  *(here->LTRAibr2Pos1Ptr) -= dummy1;	  *(here->LTRAibr2Neg1Ptr) += dummy1;	  /* end loading for convolution parts' first terms */	  break;	default:	  return (E_BADPARM);	}	/* INITPRED - first NR iteration of each timepoint */	/* set up LTRAinputs - to go into the RHS of the circuit equations */	if (ckt->CKTmode & (MODEINITPRED | MODEINITTRAN)) {	  here->LTRAinput1 = here->LTRAinput2 = 0.0;	  switch (model->LTRAspecialCase) {	  case LTRA_MOD_LC:	  case LTRA_MOD_RLC:	    if (tdover) {	      /* have to interpolate values */	      if ((isaved != 0) &&		  ((model->LTRAhowToInterp ==			  LTRA_MOD_QUADINTERP) ||		      (model->LTRAhowToInterp ==			  LTRA_MOD_MIXEDINTERP))) {		v1d = *(here->LTRAv1 + isaved - 1) * qf1		    + *(here->LTRAv1 + isaved) * qf2		    + *(here->LTRAv1 + isaved + 1) * qf3;		max = MAX(*(here->LTRAv1 + isaved - 1),		    *(here->LTRAv1 + isaved));		max = MAX(max, *(here->LTRAv1 + isaved + 1));		min = MIN(*(here->LTRAv1 + isaved - 1),		    *(here->LTRAv1 + isaved));		min = MIN(min, *(here->LTRAv1 + isaved + 1));	      }	      if ((model->LTRAhowToInterp ==		      LTRA_MOD_LININTERP) || (isaved == 0) ||		  ((isaved != 0) &&		      ((model->LTRAhowToInterp ==			      LTRA_MOD_QUADINTERP) ||			  (model->LTRAhowToInterp ==			      LTRA_MOD_MIXEDINTERP)) &&		      ((v1d > max) || (v1d < min)))) {		if ((isaved != 0) &&		    (model->LTRAhowToInterp ==			LTRA_MOD_QUADINTERP)) {#ifdef LTRADEBUG		  fprintf(stdout, "LTRAload: warning: interpolated v1 is out of range after timepoint %d\n", ckt->CKTtimeIndex);		  fprintf(stdout, "	values: %1.8g %1.8g %1.8g; interpolated: %1.8g\n",		      *(here->LTRAv1 + isaved - 1),		      *(here->LTRAv1 + isaved),

⌨️ 快捷键说明

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