📄 dctran.c
字号:
#endif /* SENSDEBUG */ }#endif return(OK); } if( (*(SPfrontEnd->IFpauseTest))() ) { /* user requested pause... */ 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(E_PAUSE); }resume:#ifdef STEPDEBUG if( (ckt->CKTdelta <= ckt->CKTfinalTime/50) && (ckt->CKTdelta <= ckt->CKTmaxStep)) { ; } else { if(ckt->CKTfinalTime/50<ckt->CKTmaxStep) { (void)printf("limited by Tstop/50\n"); } else { (void)printf("limited by Tmax\n"); } }#endif ckt->CKTdelta = MIN(ckt->CKTdelta,ckt->CKTmaxStep); /* are we at a breakpoint, or indistinguishably close? */ if ((ckt->CKTtime == *(ckt->CKTbreaks)) || (*(ckt->CKTbreaks) - (ckt->CKTtime) <= ckt->CKTdelmin)) { /* first timepoint after a breakpoint - cut integration order */ /* and limit timestep to .1 times minimum of time to next breakpoint, * and previous timestep */ ckt->CKTorder = 1;#ifdef STEPDEBUG if( (ckt->CKTdelta >.1* ckt->CKTsaveDelta) || (ckt->CKTdelta > .1*(*(ckt->CKTbreaks+1)-*(ckt->CKTbreaks))) ) { if(ckt->CKTsaveDelta < (*(ckt->CKTbreaks+1)-*(ckt->CKTbreaks))) { (void)printf("limited by pre-breakpoint delta\n"); } else { (void)printf("limited by next breakpoint\n"); } }#endif#ifdef HAS_SHORTMACRO mt= MIN(ckt->CKTsaveDelta, *(ckt->CKTbreaks+1)-*(ckt->CKTbreaks)); ckt->CKTdelta = MIN(ckt->CKTdelta, .1 * mt);#else ckt->CKTdelta = MIN(ckt->CKTdelta, .1 * MIN(ckt->CKTsaveDelta, *(ckt->CKTbreaks+1)-*(ckt->CKTbreaks)));#endif if(firsttime) { ckt->CKTdelta /= 10;#ifdef STEPDEBUG (void)printf("delta cut for initial timepoint\n");#endif } /* don't want to get below delmin for no reason */ ckt->CKTdelta = MAX(ckt->CKTdelta, ckt->CKTdelmin*2.0); } else if(ckt->CKTtime + ckt->CKTdelta >= *(ckt->CKTbreaks)) { ckt->CKTsaveDelta = ckt->CKTdelta; ckt->CKTdelta = *(ckt->CKTbreaks) - ckt->CKTtime;#ifdef STEPDEBUG (void)printf("delta cut to hit breakpoint\n");#endif ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */ }#ifdef PARALLEL_ARCH DGOP_( &type, &(ckt->CKTdelta), &length, "min" );#endif /* PARALLEL_ARCH */ 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) { olddelta=ckt->CKTdelta; /* time abort? */ ckt->CKTtime += ckt->CKTdelta; ckt->CKTdeltaOld[0]=ckt->CKTdelta; NIcomCof(ckt);#ifdef PREDICTOR error = NIpred(ckt);#endif /* PREDICTOR */ save_mode = ckt->CKTmode; save_order = ckt->CKTorder; converged = NIiter(ckt,ckt->CKTtranMaxIter); 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); } } if(converged != 0) { ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta; ckt->CKTstat->STATrejected ++; ckt->CKTdelta = ckt->CKTdelta/8;#ifdef STEPDEBUG (void)printf("delta cut for non-convergence\n");#endif if(firsttime) { ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN; } ckt->CKTorder = 1; } else { if (firsttime) {#ifdef HAS_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; goto nextTime; /* no check on * first time point */ } 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:point accepted\n");#endif#ifdef HAS_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 /* go to 650 - trapezoidal */ goto nextTime; } else { ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta; ckt->CKTstat->STATrejected ++; 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((GENERIC *) ckt, "Timestep too small"); return(E_TIMESTEP); } } } /* NOTREACHED */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -