📄 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--;#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 + -