📄 nbt2load.c
字号:
ie = *(ckt->CKTstate0 + inst->NBJT2ie); dIeDVce = *(ckt->CKTstate0 + inst->NBJT2dIeDVce); dIeDVbe = *(ckt->CKTstate0 + inst->NBJT2dIeDVbe); dIcDVce = *(ckt->CKTstate0 + inst->NBJT2dIcDVce); dIcDVbe = *(ckt->CKTstate0 + inst->NBJT2dIcDVbe); goto load; }#endif /* NOBYPASS */ /* * limit nonlinear branch voltages */ icheck1 = 1; if (deviceType == OPTN_JFET) { double vbc, vbc0; vbe = inst->NBJT2type * limitJunctionVoltage(inst->NBJT2type * vbe, inst->NBJT2type * *(ckt->CKTstate0 + inst->NBJT2vbe), &icheck); vbc = vbe - vce; vbc0 = *(ckt->CKTstate0 + inst->NBJT2vbe) - *(ckt->CKTstate0 + inst->NBJT2vce); vbc = inst->NBJT2type * limitJunctionVoltage(inst->NBJT2type * vbc, inst->NBJT2type * vbc0, &icheck); if (icheck1 == 1) icheck = 1; vce = vbe - vbc; } else { vbe = inst->NBJT2type * limitJunctionVoltage(inst->NBJT2type * vbe, inst->NBJT2type * *(ckt->CKTstate0 + inst->NBJT2vbe), &icheck); vce = inst->NBJT2type * limitVce(inst->NBJT2type * vce, inst->NBJT2type * *(ckt->CKTstate0 + inst->NBJT2vce), &icheck1); if (icheck1 == 1) icheck = 1; } delVbe = vbe - *(ckt->CKTstate0 + inst->NBJT2vbe); delVce = vce - *(ckt->CKTstate0 + inst->NBJT2vce); NBJT2setBCs(pDevice, vce - delVce, vbe - delVbe); } if (doInitSolve) { if (TWOdcDebug) { printVoltages(stdout, model->NBJT2modName, inst->NBJT2name, deviceType, 2, 0.0, 0.0, 0.0, 0.0); } startTime2 = SPfrontEnd->IFseconds(); TWOequilSolve(pDevice); totalTime2 = SPfrontEnd->IFseconds() - startTime2; pDevice->pStats->totalTime[STAT_SETUP] += totalTime2; pDevice->pStats->totalTime[STAT_DC] -= totalTime2; TWObiasSolve(pDevice, MaxIterations, FALSE, NULL); *(ckt->CKTstate0 + inst->NBJT2vbe) = 0.0; *(ckt->CKTstate0 + inst->NBJT2vce) = 0.0; if (initStateName != NULL) { if (TWOreadState(pDevice, initStateName, 2, &vce, &vbe, NULL ) < 0) { fprintf(stderr, "NBJT2load: trouble reading state-file %s\n", initStateName); } else { NBJT2setBCs(pDevice, vce, vbe); delVce = delVbe = 0.0; } } } /* * determine dc current and derivatives using the numerical routines */ if (ckt->CKTmode & (MODEDCOP | MODETRANOP | MODEDCTRANCURVE | MODEINITSMSIG)) { numDevNonCon = 0; inst->NBJT2c11 = inst->NBJT2y11r = inst->NBJT2y11i = 0.0; inst->NBJT2c12 = inst->NBJT2y12r = inst->NBJT2y12i = 0.0; inst->NBJT2c21 = inst->NBJT2y21r = inst->NBJT2y21i = 0.0; inst->NBJT2c22 = inst->NBJT2y22r = inst->NBJT2y22i = 0.0; inst->NBJT2smSigAvail = FALSE; devNonCon: NBJT2project(pDevice, delVce, delVbe); if (TWOdcDebug) { printVoltages(stdout, model->NBJT2modName, inst->NBJT2name, deviceType, 2, vce, delVce, vbe, delVbe); } TWObiasSolve(pDevice, MaxIterations, FALSE, model->NBJT2pInfo); devConverged = pDevice->converged; if (devConverged && finite(pDevice->rhsNorm)) { /* compute the currents */ NBJT2current(pDevice, FALSE, (double *) NULL, &ie, &ic); NBJT2conductance(pDevice, FALSE, (double *) NULL, &dIeDVce, &dIcDVce, &dIeDVbe, &dIcDVbe); } else { /* reduce the voltage step until converged */ /* restore boundary nodes to previous potential */ NBJT2setBCs(pDevice, vce - delVce, vbe - delVbe); TWOstoreInitialGuess(pDevice); TWOresetJacobian(pDevice); delVbe *= 0.5; delVce *= 0.5; vbe = delVbe + *(ckt->CKTstate0 + inst->NBJT2vbe); vce = delVce + *(ckt->CKTstate0 + inst->NBJT2vce); numDevNonCon++; icheck = 1; if (numDevNonCon > 10) { printVoltages(stderr, model->NBJT2modName, inst->NBJT2name, deviceType, 2, vce, delVce, vbe, delVbe); fprintf(stderr, "*** Non-convergence during load ***\n"); totalTime += SPfrontEnd->IFseconds() - startTime; pDevice->pStats->totalTime[STAT_DC] += totalTime; ckt->CKTtroubleElt = (GENinstance *) inst; return (E_BADMATRIX); } else { goto devNonCon; } } } if ((ckt->CKTmode & (MODETRAN | MODEAC)) || ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) || (ckt->CKTmode & MODEINITSMSIG)) { /* * store small-signal parameters */ if ((!(ckt->CKTmode & MODETRANOP)) || (!(ckt->CKTmode & MODEUIC))) { if (ckt->CKTmode & MODEINITSMSIG) { totalTime += SPfrontEnd->IFseconds() - startTime; pDevice->pStats->totalTime[STAT_DC] += totalTime; startTime2 = SPfrontEnd->IFseconds(); NBJT2initSmSig(inst); pDevice->pStats->totalTime[STAT_AC] += SPfrontEnd->IFseconds() - startTime2; continue; } else { inst->NBJT2smSigAvail = FALSE; } /* * transient analysis */ if (ckt->CKTmode & MODEINITPRED) { NBJT2setBCs(pDevice, vce, vbe); TWOstoreInitialGuess(pDevice); } else { NBJT2update(pDevice, delVce, delVbe, TRUE); } if (TWOtranDebug) { printVoltages(stdout, model->NBJT2modName, inst->NBJT2name, deviceType, 2, vce, delVce, vbe, delVbe); } TWObiasSolve(pDevice, 0, TRUE, model->NBJT2pInfo); if (!finite(pDevice->rhsNorm)) { totalTime += SPfrontEnd->IFseconds() - startTime; pDevice->pStats->totalTime[STAT_TRAN] += totalTime; ckt->CKTtroubleElt = (GENinstance *) inst; return (E_BADMATRIX); } devConverged = TWOdeviceConverged(pDevice); pDevice->converged = devConverged; /* compute the currents */ NBJT2current(pDevice, TRUE, model->NBJT2pInfo->intCoeff, &ie, &ic); NBJT2conductance(pDevice, TRUE, model->NBJT2pInfo->intCoeff, &dIeDVce, &dIcDVce, &dIeDVbe, &dIcDVbe); } } /* * check convergence */ if ((!(ckt->CKTmode & MODEINITFIX)) || (!(inst->NBJT2off))) { if (icheck == 1 || !devConverged) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) inst; } else { tol = ckt->CKTreltol * MAX(FABS(ichat), FABS(ic)) + ckt->CKTabstol; if (FABS(ichat - ic) > tol) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) inst; } else { tol = ckt->CKTreltol * MAX(FABS(iehat), FABS(ie)) + ckt->CKTabstol; if (FABS(iehat - ie) > tol) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) inst; } } } } *(ckt->CKTstate0 + inst->NBJT2vbe) = vbe; *(ckt->CKTstate0 + inst->NBJT2vce) = vce; *(ckt->CKTstate0 + inst->NBJT2ic) = ic; *(ckt->CKTstate0 + inst->NBJT2ie) = ie; *(ckt->CKTstate0 + inst->NBJT2dIeDVce) = dIeDVce; *(ckt->CKTstate0 + inst->NBJT2dIeDVbe) = dIeDVbe; *(ckt->CKTstate0 + inst->NBJT2dIcDVce) = dIcDVce; *(ckt->CKTstate0 + inst->NBJT2dIcDVbe) = dIcDVbe; load: /* * load current excitation vector */ iceq = ic - dIcDVce * vce - dIcDVbe * vbe; ieeq = ie - dIeDVce * vce - dIeDVbe * vbe; *(ckt->CKTrhs + inst->NBJT2colNode) -= iceq; *(ckt->CKTrhs + inst->NBJT2baseNode) += ieeq + iceq; *(ckt->CKTrhs + inst->NBJT2emitNode) -= ieeq; /* * load y matrix */ *(inst->NBJT2colColPtr) += dIcDVce; *(inst->NBJT2colBasePtr) += dIcDVbe; *(inst->NBJT2colEmitPtr) -= dIcDVbe + dIcDVce; *(inst->NBJT2baseColPtr) -= dIcDVce + dIeDVce; *(inst->NBJT2baseBasePtr) -= dIcDVbe + dIeDVbe; *(inst->NBJT2baseEmitPtr) += dIcDVbe + dIcDVce + dIeDVbe + dIeDVce; *(inst->NBJT2emitColPtr) += dIeDVce; *(inst->NBJT2emitBasePtr) += dIeDVbe; *(inst->NBJT2emitEmitPtr) -= dIeDVbe + dIeDVce; totalTime += SPfrontEnd->IFseconds() - startTime; if (ckt->CKTmode & MODETRAN) { pDevice->pStats->totalTime[STAT_TRAN] += totalTime; } else { pDevice->pStats->totalTime[STAT_DC] += totalTime; } } } return (OK);}intNBJT2initSmSig(inst) NBJT2instance *inst;{ SPcomplex yIeVce, yIeVbe; SPcomplex yIcVce, yIcVbe; double omega = inst->NBJT2modPtr->NBJT2methods->METHomega; AcAnalysisMethod = SOR_ONLY; (void) NBJT2admittance(inst->NBJT2pDevice, omega, &yIeVce, &yIcVce, &yIeVbe, &yIcVbe); inst->NBJT2c11 = yIcVce.imag / omega; inst->NBJT2c12 = yIcVbe.imag / omega; inst->NBJT2c21 = (yIeVce.imag - yIcVce.imag) / omega; inst->NBJT2c22 = (yIeVbe.imag - yIcVbe.imag) / omega; inst->NBJT2y11r = yIcVce.real; inst->NBJT2y11i = yIcVce.imag; inst->NBJT2y12r = yIcVbe.real; inst->NBJT2y12i = yIcVbe.imag; inst->NBJT2y21r = yIeVce.real - yIcVce.real; inst->NBJT2y21i = yIeVce.imag - yIcVce.imag; inst->NBJT2y22r = yIeVbe.real - yIcVbe.real; inst->NBJT2y22i = yIeVbe.imag - yIcVbe.imag; inst->NBJT2smSigAvail = TRUE; return (OK);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -