📄 dctran.c
字号:
/* projected analog time, process them */ while((g_mif_info.circuit.evt_step = EVTnext_time(ckt)) <= (ckt->CKTtime + ckt->CKTdelta)) { /* Initialize temp analog bkpt to infinity */ g_mif_info.breakpoint.current = 1e30; /* Pull items off queue and process them */ EVTdequeue(ckt, g_mif_info.circuit.evt_step); EVTiter(ckt); /* If any instances have forced an earlier */ /* next analog time, cut the delta */ if(*(ckt->CKTbreaks) < g_mif_info.breakpoint.current) if(*(ckt->CKTbreaks) > (ckt->CKTtime + ckt->CKTminBreak)) g_mif_info.breakpoint.current = *(ckt->CKTbreaks); if(g_mif_info.breakpoint.current < (ckt->CKTtime + ckt->CKTdelta)) { /* Breakpoint must be > last accepted timepoint */ /* and >= current event time */ if(g_mif_info.breakpoint.current > (ckt->CKTtime + ckt->CKTminBreak) && (g_mif_info.breakpoint.current >= g_mif_info.circuit.evt_step)) { ckt->CKTsaveDelta = ckt->CKTdelta; ckt->CKTdelta = g_mif_info.breakpoint.current - ckt->CKTtime; g_mif_info.breakpoint.last = ckt->CKTtime + ckt->CKTdelta; } } } /* end while next event time <= next analog time */ } /* end if there are event instances *//* gtri - end - wbk - Do event solution */#endif for(i=5;i>=0;i--) { ckt->CKTdeltaOld[i+1]=ckt->CKTdeltaOld[i]; } ckt->CKTdeltaOld[0]=ckt->CKTdelta; temp = ckt->CKTstates[ckt->CKTmaxOrder+1]; for(i=ckt->CKTmaxOrder;i>=0;i--) { ckt->CKTstates[i+1] = ckt->CKTstates[i]; } ckt->CKTstates[0] = temp;/* 600 */ while (1) {#ifdef CLUSTER redostep = 1;#endif#ifdef XSPICE/* gtri - add - wbk - 4/17/91 - Fix Berkeley bug *//* This is needed here to allow CAPask to output currents *//* during Transient analysis. A grep for CKTcurrentAnalysis *//* indicates that it should not hurt anything else ... */ ckt->CKTcurrentAnalysis = DOING_TRAN;/* gtri - end - wbk - 4/17/91 - Fix Berkeley bug */#endif olddelta=ckt->CKTdelta; /* time abort? */ ckt->CKTtime += ckt->CKTdelta;#ifdef CLUSTER CLUinput(ckt);#endif ckt->CKTdeltaOld[0]=ckt->CKTdelta; NIcomCof(ckt);#ifdef PREDICTOR error = NIpred(ckt);#endif /* PREDICTOR */ save_mode = ckt->CKTmode; save_order = ckt->CKTorder;#ifdef XSPICE/* gtri - begin - wbk - Add Breakpoint stuff */ /* Initialize temporary breakpoint to infinity */ g_mif_info.breakpoint.current = 1.0e30;/* gtri - end - wbk - Add Breakpoint stuff *//* gtri - begin - wbk - add convergence problem reporting flags */ /* delta is forced to equal delmin on last attempt near line 650 */ if(ckt->CKTdelta <= ckt->CKTdelmin) ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE; else ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;/* gtri - begin - wbk - add convergence problem reporting flags */ /* gtri - begin - wbk - Call all hybrids *//* gtri - begin - wbk - Set evt_step */ if(ckt->evt->counts.num_insts > 0) { g_mif_info.circuit.evt_step = ckt->CKTtime; }/* gtri - end - wbk - Set evt_step */#endif converged = NIiter(ckt,ckt->CKTtranMaxIter); #ifdef XSPICE if(ckt->evt->counts.num_insts > 0) { g_mif_info.circuit.evt_step = ckt->CKTtime; EVTcall_hybrids(ckt); } /* gtri - end - wbk - Call all hybrids */#endif ckt->CKTstat->STATtimePts ++; ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITPRED; if(firsttime) { for(i=0;i<ckt->CKTnumStates;i++) { *(ckt->CKTstate2+i) = *(ckt->CKTstate1+i); *(ckt->CKTstate3+i) = *(ckt->CKTstate1+i); } } /* txl, cpl addition */ if (converged == 1111) { return(converged); } if(converged != 0) {#ifndef CLUSTER ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta; ckt->CKTstat->STATrejected ++;#endif ckt->CKTdelta = ckt->CKTdelta/8;#ifdef STEPDEBUG (void)printf("delta cut to %g for non-convergance\n",ckt->CKTdelta); fflush(stdout);#endif if(firsttime) { ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN; } ckt->CKTorder = 1;#ifdef XSPICE/* gtri - begin - wbk - Add Breakpoint stuff */ /* Force backup if temporary breakpoint is < current time */ } else if(g_mif_info.breakpoint.current < ckt->CKTtime) { ckt->CKTsaveDelta = ckt->CKTdelta; ckt->CKTtime -= ckt->CKTdelta; ckt->CKTdelta = g_mif_info.breakpoint.current - ckt->CKTtime; g_mif_info.breakpoint.last = ckt->CKTtime + ckt->CKTdelta; if(firsttime) { ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN; } ckt->CKTorder = 1;/* gtri - end - wbk - Add Breakpoint stuff */#endif } else { if (firsttime) {#ifdef WANT_SENSE2 if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){ save1 = ckt->CKTmode; save2 = ckt->CKTorder; ckt->CKTmode = save_mode; ckt->CKTorder = save_order; if(error = CKTsenDCtran(ckt)) return(error); ckt->CKTmode = save1; ckt->CKTorder = save2; }#endif firsttime =0;#ifndef CLUSTER goto nextTime; /* no check on * first time point */#else redostep = 0; goto chkStep;#endif } new = ckt->CKTdelta; error = CKTtrunc(ckt,&new); if(error) { ckt->CKTcurrentAnalysis = DOING_TRAN; ckt->CKTstat->STATtranTime += (*(SPfrontEnd->IFseconds))()-startTime; ckt->CKTstat->STATtranIter += ckt->CKTstat->STATnumIter - startIters; ckt->CKTstat->STATtranDecompTime += ckt->CKTstat->STATdecompTime - startdTime; ckt->CKTstat->STATtranSolveTime += ckt->CKTstat->STATsolveTime - startsTime; ckt->CKTstat->STATtranLoadTime += ckt->CKTstat->STATloadTime - startlTime; ckt->CKTstat->STATtranCombTime += ckt->CKTstat->STATcombineTime - startcTime; ckt->CKTstat->STATtranSyncTime += ckt->CKTstat->STATsyncTime - startkTime; return(error); } if(new>.9 * ckt->CKTdelta) { if(ckt->CKTorder == 1) { new = ckt->CKTdelta; ckt->CKTorder = 2; error = CKTtrunc(ckt,&new); if(error) { ckt->CKTcurrentAnalysis = DOING_TRAN; ckt->CKTstat->STATtranTime += (*(SPfrontEnd->IFseconds))()-startTime; ckt->CKTstat->STATtranIter += ckt->CKTstat->STATnumIter - startIters; ckt->CKTstat->STATtranDecompTime += ckt->CKTstat->STATdecompTime - startdTime; ckt->CKTstat->STATtranSolveTime += ckt->CKTstat->STATsolveTime - startsTime; ckt->CKTstat->STATtranLoadTime += ckt->CKTstat->STATloadTime - startlTime; ckt->CKTstat->STATtranCombTime += ckt->CKTstat->STATcombineTime - startcTime; ckt->CKTstat->STATtranSyncTime += ckt->CKTstat->STATsyncTime - startkTime; return(error); } if(new <= 1.05 * ckt->CKTdelta) { ckt->CKTorder = 1; } } /* time point OK - 630*/ ckt->CKTdelta = new;#ifdef STEPDEBUG (void)printf( "delta set to truncation error result: %g. Point accepted\n", ckt->CKTdelta); fflush(stdout);#endif#ifdef WANT_SENSE2 if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){ save1 = ckt->CKTmode; save2 = ckt->CKTorder; ckt->CKTmode = save_mode; ckt->CKTorder = save_order; if(error = CKTsenDCtran(ckt)) return(error); ckt->CKTmode = save1; ckt->CKTorder = save2; }#endif#ifndef CLUSTER /* go to 650 - trapezoidal */ goto nextTime;#else redostep = 0; goto chkStep;#endif } else {#ifndef CLUSTER ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta; ckt->CKTstat->STATrejected ++;#endif ckt->CKTdelta = new;#ifdef STEPDEBUG (void)printf( "delta set to truncation error result:point rejected\n");#endif } }#ifdef PARALLEL_ARCH DGOP_( &type, &(ckt->CKTdelta), &length, "min" );#endif /* PARALLEL_ARCH */ if (ckt->CKTdelta <= ckt->CKTdelmin) { if (olddelta > ckt->CKTdelmin) { ckt->CKTdelta = ckt->CKTdelmin;#ifdef STEPDEBUG (void)printf("delta at delmin\n");#endif } else { ckt->CKTcurrentAnalysis = DOING_TRAN; ckt->CKTstat->STATtranTime += (*(SPfrontEnd->IFseconds))()-startTime; ckt->CKTstat->STATtranIter += ckt->CKTstat->STATnumIter - startIters; ckt->CKTstat->STATtranDecompTime += ckt->CKTstat->STATdecompTime - startdTime; ckt->CKTstat->STATtranSolveTime += ckt->CKTstat->STATsolveTime - startsTime; ckt->CKTstat->STATtranLoadTime += ckt->CKTstat->STATloadTime - startlTime; ckt->CKTstat->STATtranCombTime += ckt->CKTstat->STATcombineTime - startcTime; ckt->CKTstat->STATtranSyncTime += ckt->CKTstat->STATsyncTime - startkTime; errMsg = CKTtrouble((void *) ckt, "Timestep too small"); return(E_TIMESTEP); } }#ifdef XSPICE/* gtri - begin - wbk - Do event backup */ if(ckt->evt->counts.num_insts > 0) EVTbackup(ckt, ckt->CKTtime + ckt->CKTdelta);/* gtri - end - wbk - Do event backup */#endif #ifdef CLUSTER chkStep: if(CLUsync(ckt->CKTtime,&ckt->CKTdelta,redostep)){ goto nextTime; } else { ckt->CKTtime -= olddelta; ckt->CKTstat->STATrejected ++; }#endif } /* NOTREACHED */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -