📄 ltraload.c
字号:
/**********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--; if ((i == -1)) {#ifdef LTRADEBUG 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((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), *(here->LTRAv1 + isaved + 1), v1d); fprintf(stdout," timepoints are: %1.8g %1.8g %1.8g %1.8g\n",t1,t2,t3,ckt->CKTtime - model->LTRAtd);#endif } else { v1d = *(here->LTRAv1 + isaved) * lf2 + *(here->LTRAv1 + isaved + 1) * lf3; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -