📄 dctran.c
字号:
startIters = ckt->CKTstat->STATnumIter; startdTime = ckt->CKTstat->STATdecompTime; startsTime = ckt->CKTstat->STATsolveTime; startlTime = ckt->CKTstat->STATloadTime; startcTime = ckt->CKTstat->STATcombineTime; startkTime = ckt->CKTstat->STATsyncTime; if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5; firsttime=0; /* To get rawfile working saj*/ error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, (void*)ckt->CKTcurJob, ckt->CKTcurJob->JOBname,timeUid,IF_REAL,666,nameList, 666,&(((TRANan*)ckt->CKTcurJob)->TRANplot));/*magic 666 nums as flags */ if(error) { fprintf(stderr, "Couldn't relink rawfile\n"); return error; } /*end saj*/ goto resume; }/* 650 */nextTime: /* begin LTRA code addition */ if (ckt->CKTtimePoints) { ckt->CKTtimeIndex++; if (ckt->CKTtimeIndex >= ckt->CKTtimeListSize) { /* need more space */ int need; need = 0.5 + (ckt->CKTfinalTime - ckt->CKTtime) / maxstepsize; if (need < ckt->CKTsizeIncr) need = ckt->CKTsizeIncr; ckt->CKTtimeListSize += need; ckt->CKTtimePoints = (double *) REALLOC( (char *) ckt->CKTtimePoints, sizeof(double) * ckt->CKTtimeListSize); ckt->CKTsizeIncr *= 1.4; } *(ckt->CKTtimePoints + ckt->CKTtimeIndex) = ckt->CKTtime; } /* end LTRA code addition */ error = CKTaccept(ckt); /* check if current breakpoint is outdated; if so, clear */ if (ckt->CKTtime > *(ckt->CKTbreaks)) CKTclrBreak(ckt);/* * Breakpoint handling scheme: * When a timepoint t is accepted (by CKTaccept), clear all previous * breakpoints, because they will never be needed again. * * t may itself be a breakpoint, or indistinguishably close. DON'T * clear t itself; recognise it as a breakpoint and act accordingly * * if t is not a breakpoint, limit the timestep so that the next * breakpoint is not crossed */#ifdef STEPDEBUG printf("Delta %g accepted at time %g\n",ckt->CKTdelta,ckt->CKTtime); fflush(stdout);#endif /* STEPDEBUG */ ckt->CKTstat->STATaccepted ++; ckt->CKTbreak=0; /* XXX Error will cause single process to bail. */ 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); }#ifdef XSPICE/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */ if(g_ipc.enabled) { /* Send event-driven results */ EVTdump(ckt, IPC_ANAL_TRAN, 0.0); /* Then follow with analog results... */ /* Test to see if delta was cut by a breakpoint, */ /* a non-convergence, or a too large truncation error */ if(ipc_firsttime) ipc_delta_cut = IPC_FALSE; else if(ckt->CKTtime < (ipc_last_time + (0.999 * ipc_last_delta))) ipc_delta_cut = IPC_TRUE; else ipc_delta_cut = IPC_FALSE; /* Record the data required to check for delta cuts */ ipc_last_time = ckt->CKTtime; ipc_last_delta = MIN(ckt->CKTdelta, ckt->CKTmaxStep); /* Send results data if time since last dump is greater */ /* than 'mintime', or if first or second timepoints, */ /* or if delta was cut */ if( (ckt->CKTtime >= (g_ipc.mintime + g_ipc.last_time)) || ipc_firsttime || ipc_secondtime || ipc_delta_cut ) { ipc_send_data_prefix(ckt->CKTtime); CKTdump(ckt,ckt->CKTtime, (((TRANan*)ckt->CKTcurJob)->TRANplot)); ipc_send_data_suffix(); if(ipc_firsttime) { ipc_firsttime = IPC_FALSE; ipc_secondtime = IPC_TRUE; } else if(ipc_secondtime) ipc_secondtime = IPC_FALSE; g_ipc.last_time = ckt->CKTtime; } } else /* gtri - modify - wbk - 12/19/90 - Send IPC stuff */#endif#ifdef CLUSTER CLUoutput(ckt);#endif if(ckt->CKTtime >= ckt->CKTinitTime) CKTdump(ckt,ckt->CKTtime, (((TRANan*)ckt->CKTcurJob)->TRANplot));#ifdef XSPICE/* gtri - begin - wbk - Update event queues/data for accepted timepoint */ /* Note: this must be done AFTER sending results to SI so it can't */ /* go next to CKTaccept() above */ if(ckt->evt->counts.num_insts > 0) EVTaccept(ckt, ckt->CKTtime);/* gtri - end - wbk - Update event queues/data for accepted timepoint */#endif ckt->CKTstat->STAToldIter = ckt->CKTstat->STATnumIter; if(fabs(ckt->CKTtime - ckt->CKTfinalTime) < ckt->CKTminBreak) { /*printf(" done: time is %g, final time is %g, and tol is %g\n",*/ /*ckt->CKTtime,ckt->CKTfinalTime,ckt->CKTminBreak);*/ (*(SPfrontEnd->OUTendPlot))( (((TRANan*)ckt->CKTcurJob)->TRANplot)); ckt->CKTcurrentAnalysis = 0; 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;#ifdef WANT_SENSE2 if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){ ckt->CKTsenInfo->SENmode = save;#ifdef SENSDEBUG fclose(outsen);#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#ifdef HAS_WINDOWS SetAnalyse( "tran", (int)((ckt->CKTtime * 100) / ckt->CKTfinalTime));#endif ckt->CKTdelta = MIN(ckt->CKTdelta,ckt->CKTmaxStep);#ifdef XSPICE/* gtri - begin - wbk - Cut integration order if first timepoint after breakpoint */ if(ckt->CKTtime == g_mif_info.breakpoint.last) ckt->CKTorder = 1;/* gtri - end - wbk - Cut integration order if first timepoint after breakpoint */#endif /* 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 ckt->CKTdelta = MIN(ckt->CKTdelta, .1 * MIN(ckt->CKTsaveDelta, *(ckt->CKTbreaks+1)-*(ckt->CKTbreaks))); if(firsttime) { ckt->CKTdelta /= 10;#ifdef STEPDEBUG (void)printf("delta cut for initial timepoint\n");#endif } #ifdef XSPICE }/* gtri - begin - wbk - Add Breakpoint stuff */ if(ckt->CKTtime + ckt->CKTdelta >= g_mif_info.breakpoint.current) { /* If next time > temporary breakpoint, force it to the breakpoint */ /* And mark that timestep was set by temporary breakpoint */ ckt->CKTsaveDelta = ckt->CKTdelta; ckt->CKTdelta = g_mif_info.breakpoint.current - ckt->CKTtime; g_mif_info.breakpoint.last = ckt->CKTtime + ckt->CKTdelta; } else { /* Else, mark that timestep was not set by temporary breakpoint */ g_mif_info.breakpoint.last = 1.0e30; }/* gtri - end - wbk - Add Breakpoint stuff *//* gtri - begin - wbk - Modify Breakpoint stuff */ /* Throw out any permanent breakpoint times <= current time */ while(1) { if(*(ckt->CKTbreaks) <= (ckt->CKTtime + ckt->CKTminBreak)) CKTclrBreak(ckt); else break; } /* Force the breakpoint if appropriate */ if((ckt->CKTtime + ckt->CKTdelta) > *(ckt->CKTbreaks)) { ckt->CKTbreak = 1; ckt->CKTsaveDelta = ckt->CKTdelta; ckt->CKTdelta = *(ckt->CKTbreaks) - ckt->CKTtime; }/* gtri - end - wbk - Modify Breakpoint stuff */#else /* !XSPICE */ /* 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 %g to hit breakpoint\n",ckt->CKTdelta); fflush(stdout);#endif ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */ }#ifdef CLUSTER if(!CLUsync(ckt->CKTtime,&ckt->CKTdelta,0)){ printf("Sync error!\n"); exit(0); }#endif#ifdef PARALLEL_ARCH DGOP_( &type, &(ckt->CKTdelta), &length, "min" );#endif /* PARALLEL_ARCH */#endif /* XSPICE */#ifdef XSPICE/* gtri - begin - wbk - Do event solution */ if(ckt->evt->counts.num_insts > 0) { /* if time = 0 and op_alternate was specified as false during */ /* dcop analysis, call any changed instances to let them */ /* post their outputs with their associated delays */ if((ckt->CKTtime == 0.0) && (! ckt->evt->options.op_alternate)) EVTiter(ckt); /* while there are events on the queue with event time <= next */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -