📄 nbjtload.c
字号:
/* vbc = vbe - vce; vbc = inst->NBJTtype * limitVbe(inst->NBJTtype * vbc, inst->NBJTtype * (*(ckt->CKTstate0 + inst->NBJTvbe) - *(ckt->CKTstate0 + inst->NBJTvce)), &icheck1); vce = vbe - vbc; */ vce = inst->NBJTtype * limitVce(inst->NBJTtype * vce, inst->NBJTtype * *(ckt->CKTstate0 + inst->NBJTvce), &icheck1); if (icheck1 == 1) icheck = 1; delVbe = vbe - *(ckt->CKTstate0 + inst->NBJTvbe); delVce = vce - *(ckt->CKTstate0 + inst->NBJTvce); } if (doInitSolve) { if (ONEdcDebug) { printVoltages(stdout, model->NBJTmodName, inst->NBJTname, deviceType, 2, 0.0, 0.0, 0.0, 0.0); } startTime2 = SPfrontEnd->IFseconds(); ONEequilSolve(pDevice); totalTime2 = SPfrontEnd->IFseconds() - startTime2; pDevice->pStats->totalTime[STAT_SETUP] += totalTime2; pDevice->pStats->totalTime[STAT_DC] -= totalTime2; ONEbiasSolve(pDevice, MaxIterations, FALSE, NULL); *(ckt->CKTstate0 + inst->NBJTvbe) = 0.0; *(ckt->CKTstate0 + inst->NBJTvce) = 0.0; if (initStateName != NULL) { if (ONEreadState(pDevice, initStateName, 2, &vce, &vbe ) < 0) { fprintf(stderr, "NBJTload: trouble reading state-file %s\n", initStateName); } else { NBJTsetBCs(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->NBJTc11 = inst->NBJTy11r = inst->NBJTy11i = 0.0; inst->NBJTc12 = inst->NBJTy12r = inst->NBJTy12i = 0.0; inst->NBJTc21 = inst->NBJTy21r = inst->NBJTy21i = 0.0; inst->NBJTc22 = inst->NBJTy22r = inst->NBJTy22i = 0.0; inst->NBJTsmSigAvail = FALSE; devNonCon: NBJTproject(pDevice, delVce, delVbe, vbe); if (ONEdcDebug) { printVoltages(stdout, model->NBJTmodName, inst->NBJTname, deviceType, 2, vce, delVce, vbe, delVbe); } ONEbiasSolve(pDevice, MaxIterations, FALSE, model->NBJTpInfo); devConverged = pDevice->converged; if (devConverged && finite(pDevice->rhsNorm)) { /* compute the currents */ NBJTcurrent(pDevice, FALSE, (double *) NULL, &ie, &ic); NBJTconductance(pDevice, FALSE, (double *) NULL, &dIeDVce, &dIcDVce, &dIeDVbe, &dIcDVbe); /* * Add Gmin terms to everything in case we are operating at * abnormally low current levels */ ie += ckt->CKTgmin * (vce + vbe); dIeDVce += ckt->CKTgmin; dIeDVbe += ckt->CKTgmin; ic += ckt->CKTgmin * (2.0 * vce - vbe); dIcDVce += 2.0 * ckt->CKTgmin; dIcDVbe -= ckt->CKTgmin; } else { /* reduce the voltage step until converged */ /* restore the boundary potential to previous value */ NBJTsetBCs(pDevice, vce - delVce, vbe - delVbe); ONEstoreInitialGuess(pDevice); ONEresetJacobian(pDevice); delVbe *= 0.5; delVce *= 0.5; vbe = delVbe + *(ckt->CKTstate0 + inst->NBJTvbe); vce = delVce + *(ckt->CKTstate0 + inst->NBJTvce); numDevNonCon++; icheck = 1; if (numDevNonCon > 10) { printVoltages(stderr, model->NBJTmodName, inst->NBJTname, 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(); NBJTinitSmSig(inst); pDevice->pStats->totalTime[STAT_AC] += SPfrontEnd->IFseconds() - startTime2; continue; } else { inst->NBJTsmSigAvail = FALSE; } /* * transient analysis */ if (ckt->CKTmode & MODEINITPRED) { NBJTsetBCs(pDevice, vce, vbe); ONEstoreInitialGuess(pDevice); } else { NBJTupdate(pDevice, delVce, delVbe, vbe, TRUE); } if (ONEtranDebug) { printVoltages(stdout, model->NBJTmodName, inst->NBJTname, deviceType, 2, vce, delVce, vbe, delVbe); } ONEbiasSolve(pDevice, 0, TRUE, model->NBJTpInfo); if (!finite(pDevice->rhsNorm)) { /* Timestep took us to never-never land. */ totalTime += SPfrontEnd->IFseconds() - startTime; pDevice->pStats->totalTime[STAT_TRAN] += totalTime; ckt->CKTtroubleElt = (GENinstance *) inst; return (E_BADMATRIX); } devConverged = ONEdeviceConverged(pDevice); pDevice->converged = devConverged; /* compute the currents */ NBJTcurrent(pDevice, TRUE, model->NBJTpInfo->intCoeff, &ie, &ic); NBJTconductance(pDevice, TRUE, model->NBJTpInfo->intCoeff, &dIeDVce, &dIcDVce, &dIeDVbe, &dIcDVbe); /* * Add Gmin terms to everything in case we are operating at * abnormally low current levels */ ie += ckt->CKTgmin * (vce + vbe); dIeDVce += ckt->CKTgmin; dIeDVbe += ckt->CKTgmin; ic += ckt->CKTgmin * (2.0 * vce - vbe); dIcDVce += 2.0 * ckt->CKTgmin; dIcDVbe -= ckt->CKTgmin; } } /* * check convergence */ if ((!(ckt->CKTmode & MODEINITFIX)) || (!(inst->NBJToff))) { 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->NBJTvbe) = vbe; *(ckt->CKTstate0 + inst->NBJTvce) = vce; *(ckt->CKTstate0 + inst->NBJTic) = ic; *(ckt->CKTstate0 + inst->NBJTie) = ie; *(ckt->CKTstate0 + inst->NBJTdIeDVce) = dIeDVce; *(ckt->CKTstate0 + inst->NBJTdIeDVbe) = dIeDVbe; *(ckt->CKTstate0 + inst->NBJTdIcDVce) = dIcDVce; *(ckt->CKTstate0 + inst->NBJTdIcDVbe) = dIcDVbe; load: /* * load current excitation vector */ iceq = ic - dIcDVce * vce - dIcDVbe * vbe; ieeq = ie - dIeDVce * vce - dIeDVbe * vbe; *(ckt->CKTrhs + inst->NBJTcolNode) -= iceq; *(ckt->CKTrhs + inst->NBJTbaseNode) -= ieeq - iceq; *(ckt->CKTrhs + inst->NBJTemitNode) += ieeq; /* * load y matrix */ *(inst->NBJTcolColPtr) += dIcDVce; *(inst->NBJTcolBasePtr) += dIcDVbe; *(inst->NBJTcolEmitPtr) -= dIcDVbe + dIcDVce; *(inst->NBJTbaseColPtr) -= dIcDVce - dIeDVce; *(inst->NBJTbaseBasePtr) -= dIcDVbe - dIeDVbe; *(inst->NBJTbaseEmitPtr) += dIcDVbe + dIcDVce - dIeDVbe - dIeDVce; *(inst->NBJTemitColPtr) -= dIeDVce; *(inst->NBJTemitBasePtr) -= dIeDVbe; *(inst->NBJTemitEmitPtr) += 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);}intNBJTinitSmSig(inst) NBJTinstance *inst;{ SPcomplex yIeVce, yIeVbe; SPcomplex yIcVce, yIcVbe; double omega = inst->NBJTmodPtr->NBJTmethods->METHomega; AcAnalysisMethod = SOR_ONLY; (void) NBJTadmittance(inst->NBJTpDevice, omega, &yIeVce, &yIcVce, &yIeVbe, &yIcVbe); inst->NBJTc11 = yIcVce.imag / omega; inst->NBJTc12 = yIcVbe.imag / omega; inst->NBJTc21 = (yIeVce.imag - yIcVce.imag) / omega; inst->NBJTc22 = (yIeVbe.imag - yIcVbe.imag) / omega; inst->NBJTy11r = yIcVce.real; inst->NBJTy11i = yIcVce.imag; inst->NBJTy12r = yIcVbe.real; inst->NBJTy12i = yIcVbe.imag; inst->NBJTy21r = yIeVce.real - yIcVce.real; inst->NBJTy21i = yIeVce.imag - yIcVce.imag; inst->NBJTy22r = yIeVbe.real - yIcVbe.real; inst->NBJTy22i = yIeVbe.imag - yIcVbe.imag; inst->NBJTsmSigAvail = TRUE; return (OK);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -