diff --git a/ChangeLog b/ChangeLog index 98e9df9b5..7ef87edc6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2011-08-04 Holger Vogt * dcpss.c: tiny update to obtain compilation with MS VS 2008, code beautyfied + * winmain.c, dcpss.c: Windows progress message improved 2011-08-04 Paolo Nenzi * (new) tests/pss , diff --git a/src/spicelib/analysis/dcpss.c b/src/spicelib/analysis/dcpss.c index c01ec9934..deb1ddfa7 100755 --- a/src/spicelib/analysis/dcpss.c +++ b/src/spicelib/analysis/dcpss.c @@ -50,1360 +50,1349 @@ CKTfour(int, int, double *, double *, double *, double, double *, double *, doub int DCpss(CKTcircuit *ckt, int restart) { - int oscnNode; - int i; - double olddelta; - double delta; - double new; - double *temp; - double startdTime; - double startsTime; - double startlTime; - double startcTime; - double startkTime; - double startTime; - int startIters; - int converged; - int firsttime; - int error; - #ifdef WANT_SENSE2 - #ifdef SENSDEBUG - FILE *outsen; - #endif /* SENSDEBUG */ - #endif - int save_order; - long save_mode; - IFuid timeUid; - IFuid freqUid; - IFuid *nameList; - int numNames; - double maxstepsize=0.0; + int oscnNode; + int i; + double olddelta; + double delta; + double new; + double *temp; + double startdTime; + double startsTime; + double startlTime; + double startcTime; + double startkTime; + double startTime; + int startIters; + int converged; + int firsttime; + int error; +#ifdef WANT_SENSE2 +#ifdef SENSDEBUG + FILE *outsen; +#endif /* SENSDEBUG */ +#endif + int save_order; + long save_mode; + IFuid timeUid; + IFuid freqUid; + IFuid *nameList; + int numNames; + double maxstepsize=0.0; - int ltra_num; - CKTnode *node; - #ifdef PARALLEL_ARCH - long type = MT_TRANAN, length = 1; - #endif /* PARALLEL_ARCH */ - #ifdef XSPICE - /* gtri - add - wbk - 12/19/90 - Add IPC stuff */ - Ipc_Boolean_t ipc_firsttime = IPC_TRUE; - Ipc_Boolean_t ipc_secondtime = IPC_FALSE; - Ipc_Boolean_t ipc_delta_cut = IPC_FALSE; - double ipc_last_time = 0.0; - double ipc_last_delta = 0.0; - /* gtri - end - wbk - 12/19/90 - Add IPC stuff */ - #endif - #ifdef CLUSTER - int redostep; - #endif - /* new variables - to be reorganized */ - double time_temp, gf_history[1024], rr_history[1024]; - int msize, cont_1=1, in_stabilization=1, in_pss=0,shooting_cycle_counter=0, k; - long int nextTime_count=0, ntc_start_sh=0; - double *RHS_copy_se, err, err_0=1.0e30, time_temp_0, delta_t; - double time_err_min_1=0, time_err_min_0=0, err_min_0=1.0e30, err_min_1, delta_0, delta_1; - double flag_tu_2, times_fft[8192], err_1=0, err_max, time_err_max; - int flag_tu_1=0, pss_cycle_counter=1, pss_points_cycle=0, i4, i5, k1,rest; - int count_1, count_2, count_3, count_4, count_5, count_6, count_7, dynamic_test=0; - double ntc_mv, ntc_vec[4], ntc_old, gf_last_0=1e+30, gf_last_1=313; - double err_last=0, f_proj, thd; - double *psstimes, *pssvalues, *pssValues, tv_01, tv_03, tv_04, - *pssfreqs, *pssmags, *pssphases, *pssnmags, *pssnphases, *pssResults, - *RHS_max, *RHS_min, err_conv_ref, *S_old, *S_diff; + int ltra_num; + CKTnode *node; +#ifdef PARALLEL_ARCH + long type = MT_TRANAN, length = 1; +#endif /* PARALLEL_ARCH */ +#ifdef XSPICE + /* gtri - add - wbk - 12/19/90 - Add IPC stuff */ + Ipc_Boolean_t ipc_firsttime = IPC_TRUE; + Ipc_Boolean_t ipc_secondtime = IPC_FALSE; + Ipc_Boolean_t ipc_delta_cut = IPC_FALSE; + double ipc_last_time = 0.0; + double ipc_last_delta = 0.0; + /* gtri - end - wbk - 12/19/90 - Add IPC stuff */ +#endif +#ifdef CLUSTER + int redostep; +#endif + /* new variables - to be reorganized */ + double time_temp, gf_history[1024], rr_history[1024]; + int msize, cont_1=1, in_stabilization=1, in_pss=0,shooting_cycle_counter=0, k; + long int nextTime_count=0, ntc_start_sh=0; + double *RHS_copy_se, err, err_0=1.0e30, time_temp_0, delta_t; + double time_err_min_1=0, time_err_min_0=0, err_min_0=1.0e30, err_min_1, delta_0, delta_1; + double flag_tu_2, times_fft[8192], err_1=0, err_max, time_err_max; + int flag_tu_1=0, pss_cycle_counter=1, pss_points_cycle=0, i4, i5, k1,rest; + int count_1, count_2, count_3, count_4, count_5, count_6, count_7, dynamic_test=0; + double ntc_mv, ntc_vec[4], ntc_old, gf_last_0=1e+30, gf_last_1=313; + double err_last=0, f_proj, thd; + double *psstimes, *pssvalues, *pssValues, tv_01, tv_03, tv_04, + *pssfreqs, *pssmags, *pssphases, *pssnmags, *pssnphases, *pssResults, + *RHS_max, *RHS_min, err_conv_ref, *S_old, *S_diff; - printf("Periodic Steady State analysis started.\n"); + PSSan *job = (PSSan*) (ckt->CKTcurJob); - PSSan *job = (PSSan*) (ckt->CKTcurJob); - oscnNode = job->PSSoscNode->number; - printf("PSS guessed frequency %g.\n", ckt->CKTguessedFreq); - printf("PSS points %ld.\n", ckt->CKTpsspoints); - printf("PSS harmonics number %d.\n", ckt->CKTharms); - printf("PSS steady coefficient %g.\n", ckt->CKTsteady_coeff); + printf("Periodic Steady State analysis started.\n"); - /* set first delta time step and circuit time */ - delta=ckt->CKTstep; - ckt->CKTtime=ckt->CKTinitTime; - ckt->CKTfinalTime=ckt->CKTstabTime; - /* printf("initial delta: %g\n", ckt->CKTdelta); */ + oscnNode = job->PSSoscNode->number; + printf("PSS guessed frequency %g.\n", ckt->CKTguessedFreq); + printf("PSS points %ld.\n", ckt->CKTpsspoints); + printf("PSS harmonics number %d.\n", ckt->CKTharms); + printf("PSS steady coefficient %g.\n", ckt->CKTsteady_coeff); - /* 100906 - Paste from dctran.c */ - if(restart || ckt->CKTtime == 0) { - delta=MIN(1/(ckt->CKTguessedFreq)/100,ckt->CKTstep); + /* set first delta time step and circuit time */ + delta=ckt->CKTstep; + ckt->CKTtime=ckt->CKTinitTime; + ckt->CKTfinalTime=ckt->CKTstabTime; + /* printf("initial delta: %g\n", ckt->CKTdelta); */ + + /* 100906 - Paste from dctran.c */ + if(restart || ckt->CKTtime == 0) { + delta=MIN(1/(ckt->CKTguessedFreq)/100,ckt->CKTstep); + +#ifdef STEPDEBUG + printf("delta = %g finalTime/200: %g CKTstep: %g\n",delta,ckt->CKTfinalTime/200,ckt->CKTstep); +#endif + /* begin LTRA code addition */ + if (ckt->CKTtimePoints != NULL) + FREE(ckt->CKTtimePoints); + + if (ckt->CKTstep >= ckt->CKTmaxStep) + maxstepsize = ckt->CKTstep; + else + maxstepsize = ckt->CKTmaxStep; + + ckt->CKTsizeIncr = 10; + ckt->CKTtimeIndex = -1; /* before the DC soln has been stored */ + ckt->CKTtimeListSize = (int)(1 / (ckt->CKTguessedFreq) / maxstepsize + 0.5); + ltra_num = CKTtypelook("LTRA"); + if (ltra_num >= 0 && ckt->CKThead[ltra_num] != NULL) + ckt->CKTtimePoints = NEWN(double, ckt->CKTtimeListSize); + /* end LTRA code addition */ + + if(ckt->CKTbreaks) FREE(ckt->CKTbreaks); + ckt->CKTbreaks = TMALLOC(double, 2); + if(ckt->CKTbreaks == NULL) return(E_NOMEM); + *(ckt->CKTbreaks)=0; + *(ckt->CKTbreaks+1)=ckt->CKTfinalTime; + ckt->CKTbreakSize=2; + +#ifdef XSPICE + /* gtri - begin - wbk - 12/19/90 - Modify setting of CKTminBreak */ + /* if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5; */ + /* Set to 10 times delmin for ATESSE 1 compatibity */ + if(ckt->CKTminBreak==0) ckt->CKTminBreak = 10.0 * ckt->CKTdelmin; + /* gtri - end - wbk - 12/19/90 - Modify setting of CKTminBreak */ +#else + if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5; +#endif + +#ifdef XSPICE + /* gtri - add - wbk - 12/19/90 - Add IPC stuff and set anal_init and anal_type */ + + /* Tell the beginPlot routine what mode we're in */ + g_ipc.anal_type = IPC_ANAL_TRAN; + + /* Tell the code models what mode we're in */ + g_mif_info.circuit.anal_type = MIF_DC; + + g_mif_info.circuit.anal_init = MIF_TRUE; + + /* gtri - end - wbk */ +#endif + error = CKTnames(ckt,&numNames,&nameList); + if(error) return(error); + SPfrontEnd->IFnewUid (ckt, &timeUid, NULL, + "time", UID_OTHER, NULL); + error = SPfrontEnd->OUTpBeginPlot (ckt, + ckt->CKTcurJob, + "Time Domain Periodic Steady State",timeUid,IF_REAL,numNames,nameList, + IF_REAL,&(((PSSan*)ckt->CKTcurJob)->PSSplot_td)); + tfree(nameList); + if(error) return(error); + + ckt->CKTtime = 0; + ckt->CKTdelta = 0; + ckt->CKTbreak=1; + firsttime = 1; + save_mode = (ckt->CKTmode&MODEUIC)|MODETRANOP | MODEINITJCT; + save_order = ckt->CKTorder; +#ifdef XSPICE + /* gtri - begin - wbk - set a breakpoint at end of supply ramping time */ + /* must do this after CKTtime set to 0 above */ + if(ckt->enh->ramp.ramptime > 0.0) + CKTsetBreak(ckt, ckt->enh->ramp.ramptime); + /* gtri - end - wbk - set a breakpoint at end of supply ramping time */ + + /* gtri - begin - wbk - Call EVTop if event-driven instances exist */ + if(ckt->evt->counts.num_insts != 0) { + /* use new DCOP algorithm */ + converged = EVTop(ckt, + (ckt->CKTmode & MODEUIC) | MODETRANOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITFLOAT, + ckt->CKTdcMaxIter, + MIF_TRUE); + EVTdump(ckt, IPC_ANAL_DCOP, 0.0); + + EVTop_save(ckt, MIF_FALSE, 0.0); + + /* gtri - end - wbk - Call EVTop if event-driven instances exist */ + } else +#endif + converged = CKTop(ckt, + (ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITJCT, + (ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITFLOAT, + ckt->CKTdcMaxIter); +#ifdef STEPDEBUG + if(converged != 0) { + fprintf(stdout,"\nTransient solution failed -\n"); + CKTncDump(ckt); + fprintf(stdout,"\n"); + fflush(stdout); + } else if (!ft_noacctprint && !ft_noinitprint) { + fprintf(stdout,"\nInitial Transient Solution\n"); + fprintf(stdout,"--------------------------\n\n"); + fprintf(stdout,"%-30s %15s\n", "Node", "Voltage"); + fprintf(stdout,"%-30s %15s\n", "----", "-------"); + for(node=ckt->CKTnodes->next; node; node=node->next) { + if (strstr(node->name, "#branch") || !strstr(node->name, "#")) + fprintf(stdout,"%-30s %15g\n", node->name, + *(ckt->CKTrhsOld+node->number)); + } + fprintf(stdout,"\n"); + fflush(stdout); + } +#endif + if(converged != 0) return(converged); +#ifdef XSPICE + /* gtri - add - wbk - 12/19/90 - Add IPC stuff */ + + /* Send the operating point results for Mspice compatibility */ + if(g_ipc.enabled) { + ipc_send_dcop_prefix(); + CKTdump(ckt,(double)0,(((PSSan*)ckt->CKTcurJob)->PSSplot_td)); + ipc_send_dcop_suffix(); + } + + /* gtri - end - wbk */ + + + /* gtri - add - wbk - 12/19/90 - set anal_init and anal_type */ + + g_mif_info.circuit.anal_init = MIF_TRUE; + + /* Tell the code models what mode we're in */ + g_mif_info.circuit.anal_type = MIF_TRAN; + + /* gtri - end - wbk */ + + /* gtri - begin - wbk - Add Breakpoint stuff */ + + /* Initialize the temporary breakpoint variables to infinity */ + g_mif_info.breakpoint.current = 1.0e30; + g_mif_info.breakpoint.last = 1.0e30; + + /* gtri - end - wbk - Add Breakpoint stuff */ +#endif + ckt->CKTstat->STATtimePts ++; + ckt->CKTorder=1; + for(i=0; i<7; i++) { + ckt->CKTdeltaOld[i]=ckt->CKTmaxStep; + } + ckt->CKTdelta = delta; +#ifdef STEPDEBUG + (void)printf("delta initialized to %g\n",ckt->CKTdelta); +#endif + ckt->CKTsaveDelta = ckt->CKTfinalTime/50; + +#ifdef WANT_SENSE2 + if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)) { +#ifdef SENSDEBUG + printf("\nTransient Sensitivity Results\n\n"); + CKTsenPrint(ckt); +#endif /* SENSDEBUG */ + save = ckt->CKTsenInfo->SENmode; + 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 + /*print*/ + ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN; + /* modeinittran set here */ + ckt->CKTag[0]=ckt->CKTag[1]=0; + bcopy(ckt->CKTstate0, ckt->CKTstate1, + (size_t) ckt->CKTnumStates * sizeof(double)); + +#ifdef WANT_SENSE2 + if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)) { + size = SMPmatSize(ckt->CKTmatrix); + for(i = 1; i<=size ; i++) + *(ckt->CKTrhsOp + i) = *(ckt->CKTrhsOld + i); + } +#endif + + startTime = SPfrontEnd->IFseconds(); + startIters = ckt->CKTstat->STATnumIter; + startdTime = ckt->CKTstat->STATdecompTime; + startsTime = ckt->CKTstat->STATsolveTime; + startlTime = ckt->CKTstat->STATloadTime; + startcTime = ckt->CKTstat->STATcombineTime; + startkTime = ckt->CKTstat->STATsyncTime; +#ifdef CLUSTER + CLUsetup(ckt); +#endif + } else { + /*saj As traninit resets CKTmode */ + ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITPRED; + /* saj */ + startTime = SPfrontEnd->IFseconds(); + 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 + (NULL, NULL, NULL, NULL, 0, 666, NULL, 666, &(((PSSan*)ckt->CKTcurJob)->PSSplot_td)); + if(error) { + fprintf(stderr, "Couldn't relink rawfile\n"); + return error; + } + /*end saj*/ + goto resume; + } + + /* 650 */ +nextTime: + + nextTime_count=nextTime_count+1; + /* Does not start from initial time avoiding IC issues */ + if ( nextTime_count>=10 && nextTime_count<8202 && in_stabilization) { + times_fft[nextTime_count-10]=ckt->CKTtime; + } - #ifdef STEPDEBUG - printf("delta = %g finalTime/200: %g CKTstep: %g\n",delta,ckt->CKTfinalTime/200,ckt->CKTstep); - #endif /* begin LTRA code addition */ - if (ckt->CKTtimePoints != NULL) - FREE(ckt->CKTtimePoints); - - if (ckt->CKTstep >= ckt->CKTmaxStep) - maxstepsize = ckt->CKTstep; - else - maxstepsize = ckt->CKTmaxStep; - - ckt->CKTsizeIncr = 10; - ckt->CKTtimeIndex = -1; /* before the DC soln has been stored */ - ckt->CKTtimeListSize = (int)(1 / (ckt->CKTguessedFreq) / maxstepsize + 0.5); - ltra_num = CKTtypelook("LTRA"); - if (ltra_num >= 0 && ckt->CKThead[ltra_num] != NULL) - ckt->CKTtimePoints = NEWN(double, ckt->CKTtimeListSize); + if (ckt->CKTtimePoints) { + ckt->CKTtimeIndex++; + if (ckt->CKTtimeIndex >= ckt->CKTtimeListSize) { + /* need more space */ + int need; + if (in_stabilization) { + need = (int)(0.5 + (ckt->CKTstabTime - ckt->CKTtime) / maxstepsize); /* FIXME, ceil ? */ + } else { + need = (int)(0.5 + (time_temp + (1 / ckt->CKTguessedFreq) - ckt->CKTtime) / maxstepsize); + } + if (need < ckt->CKTsizeIncr) + need = ckt->CKTsizeIncr; + ckt->CKTtimeListSize += need; + ckt->CKTtimePoints = TREALLOC(double, ckt->CKTtimePoints, ckt->CKTtimeListSize); + ckt->CKTsizeIncr = (int) ceil(1.4 * ckt->CKTsizeIncr); + } + *(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); - if(ckt->CKTbreaks) FREE(ckt->CKTbreaks); - ckt->CKTbreaks = TMALLOC(double, 2); - if(ckt->CKTbreaks == NULL) return(E_NOMEM); - *(ckt->CKTbreaks)=0; - *(ckt->CKTbreaks+1)=ckt->CKTfinalTime; - ckt->CKTbreakSize=2; + /* + * 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 XSPICE - /* gtri - begin - wbk - 12/19/90 - Modify setting of CKTminBreak */ - /* if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5; */ - /* Set to 10 times delmin for ATESSE 1 compatibity */ - if(ckt->CKTminBreak==0) ckt->CKTminBreak = 10.0 * ckt->CKTdelmin; - /* gtri - end - wbk - 12/19/90 - Modify setting of CKTminBreak */ - #else - if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5; - #endif - - #ifdef XSPICE - /* gtri - add - wbk - 12/19/90 - Add IPC stuff and set anal_init and anal_type */ - - /* Tell the beginPlot routine what mode we're in */ - g_ipc.anal_type = IPC_ANAL_TRAN; - - /* Tell the code models what mode we're in */ - g_mif_info.circuit.anal_type = MIF_DC; - - g_mif_info.circuit.anal_init = MIF_TRUE; - - /* gtri - end - wbk */ - #endif - error = CKTnames(ckt,&numNames,&nameList); - if(error) return(error); - SPfrontEnd->IFnewUid (ckt, &timeUid, NULL, - "time", UID_OTHER, NULL); - error = SPfrontEnd->OUTpBeginPlot (ckt, - ckt->CKTcurJob, - "Time Domain Periodic Steady State",timeUid,IF_REAL,numNames,nameList, - IF_REAL,&(((PSSan*)ckt->CKTcurJob)->PSSplot_td)); - tfree(nameList); - if(error) return(error); - - ckt->CKTtime = 0; - ckt->CKTdelta = 0; - ckt->CKTbreak=1; - firsttime = 1; - save_mode = (ckt->CKTmode&MODEUIC)|MODETRANOP | MODEINITJCT; - save_order = ckt->CKTorder; - #ifdef XSPICE - /* gtri - begin - wbk - set a breakpoint at end of supply ramping time */ - /* must do this after CKTtime set to 0 above */ - if(ckt->enh->ramp.ramptime > 0.0) - CKTsetBreak(ckt, ckt->enh->ramp.ramptime); - /* gtri - end - wbk - set a breakpoint at end of supply ramping time */ - - /* gtri - begin - wbk - Call EVTop if event-driven instances exist */ - if(ckt->evt->counts.num_insts != 0){ - /* use new DCOP algorithm */ - converged = EVTop(ckt, - (ckt->CKTmode & MODEUIC) | MODETRANOP | MODEINITJCT, - (ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITFLOAT, - ckt->CKTdcMaxIter, - MIF_TRUE); - EVTdump(ckt, IPC_ANAL_DCOP, 0.0); - - EVTop_save(ckt, MIF_FALSE, 0.0); - - /* gtri - end - wbk - Call EVTop if event-driven instances exist */ - } else - #endif - converged = CKTop(ckt, - (ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITJCT, - (ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITFLOAT, - ckt->CKTdcMaxIter); - #ifdef STEPDEBUG - if(converged != 0) { - fprintf(stdout,"\nTransient solution failed -\n"); - CKTncDump(ckt); - fprintf(stdout,"\n"); - fflush(stdout); - } else if (!ft_noacctprint && !ft_noinitprint) { - fprintf(stdout,"\nInitial Transient Solution\n"); - fprintf(stdout,"--------------------------\n\n"); - fprintf(stdout,"%-30s %15s\n", "Node", "Voltage"); - fprintf(stdout,"%-30s %15s\n", "----", "-------"); - for(node=ckt->CKTnodes->next;node;node=node->next) { - if (strstr(node->name, "#branch") || !strstr(node->name, "#")) - fprintf(stdout,"%-30s %15g\n", node->name, - *(ckt->CKTrhsOld+node->number)); - } - fprintf(stdout,"\n"); - fflush(stdout); - } - #endif - if(converged != 0) return(converged); - #ifdef XSPICE - /* gtri - add - wbk - 12/19/90 - Add IPC stuff */ - - /* Send the operating point results for Mspice compatibility */ - if(g_ipc.enabled) { - ipc_send_dcop_prefix(); - CKTdump(ckt,(double)0,(((PSSan*)ckt->CKTcurJob)->PSSplot_td)); - ipc_send_dcop_suffix(); - } - - /* gtri - end - wbk */ - - - /* gtri - add - wbk - 12/19/90 - set anal_init and anal_type */ - - g_mif_info.circuit.anal_init = MIF_TRUE; - - /* Tell the code models what mode we're in */ - g_mif_info.circuit.anal_type = MIF_TRAN; - - /* gtri - end - wbk */ - - /* gtri - begin - wbk - Add Breakpoint stuff */ - - /* Initialize the temporary breakpoint variables to infinity */ - g_mif_info.breakpoint.current = 1.0e30; - g_mif_info.breakpoint.last = 1.0e30; - - /* gtri - end - wbk - Add Breakpoint stuff */ - #endif - ckt->CKTstat->STATtimePts ++; - ckt->CKTorder=1; - for(i=0;i<7;i++) { - ckt->CKTdeltaOld[i]=ckt->CKTmaxStep; - } - ckt->CKTdelta = delta; - #ifdef STEPDEBUG - (void)printf("delta initialized to %g\n",ckt->CKTdelta); - #endif - ckt->CKTsaveDelta = ckt->CKTfinalTime/50; - - #ifdef WANT_SENSE2 - if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){ - #ifdef SENSDEBUG - printf("\nTransient Sensitivity Results\n\n"); - CKTsenPrint(ckt); - #endif /* SENSDEBUG */ - save = ckt->CKTsenInfo->SENmode; - 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 - /*print*/ - ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN; - /* modeinittran set here */ - ckt->CKTag[0]=ckt->CKTag[1]=0; - bcopy(ckt->CKTstate0, ckt->CKTstate1, - (size_t) ckt->CKTnumStates * sizeof(double)); - - #ifdef WANT_SENSE2 - if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){ - size = SMPmatSize(ckt->CKTmatrix); - for(i = 1; i<=size ; i++) - *(ckt->CKTrhsOp + i) = *(ckt->CKTrhsOld + i); - } - #endif - - startTime = SPfrontEnd->IFseconds(); - startIters = ckt->CKTstat->STATnumIter; - startdTime = ckt->CKTstat->STATdecompTime; - startsTime = ckt->CKTstat->STATsolveTime; - startlTime = ckt->CKTstat->STATloadTime; - startcTime = ckt->CKTstat->STATcombineTime; - startkTime = ckt->CKTstat->STATsyncTime; - #ifdef CLUSTER - CLUsetup(ckt); - #endif - } else { - /*saj As traninit resets CKTmode */ - ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITPRED; - /* saj */ - startTime = SPfrontEnd->IFseconds(); - 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 - (NULL, NULL, NULL, NULL, 0, 666, NULL, 666, &(((PSSan*)ckt->CKTcurJob)->PSSplot_td)); - if(error) { - fprintf(stderr, "Couldn't relink rawfile\n"); - return error; +#ifdef STEPDEBUG + printf("Delta %g accepted at time %g (finaltime: %g)\n",ckt->CKTdelta,ckt->CKTtime,ckt->CKTfinalTime); + 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); } - /*end saj*/ - goto resume; - } - - /* 650 */ - nextTime: - - nextTime_count=nextTime_count+1; - /* Does not start from initial time avoiding IC issues */ - if ( nextTime_count>=10 && nextTime_count<8202 && in_stabilization) { - times_fft[nextTime_count-10]=ckt->CKTtime; - } - - /* begin LTRA code addition */ - if (ckt->CKTtimePoints) { - ckt->CKTtimeIndex++; - if (ckt->CKTtimeIndex >= ckt->CKTtimeListSize) { - /* need more space */ - int need; - if (in_stabilization) { - need = (int)(0.5 + (ckt->CKTstabTime - ckt->CKTtime) / maxstepsize); /* FIXME, ceil ? */ - } else { - need = (int)(0.5 + (time_temp + (1 / ckt->CKTguessedFreq) - ckt->CKTtime) / maxstepsize); - } - if (need < ckt->CKTsizeIncr) - need = ckt->CKTsizeIncr; - ckt->CKTtimeListSize += need; - ckt->CKTtimePoints = TREALLOC(double, ckt->CKTtimePoints, ckt->CKTtimeListSize); - ckt->CKTsizeIncr = (int) ceil(1.4 * ckt->CKTsizeIncr); - } - *(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 (finaltime: %g)\n",ckt->CKTdelta,ckt->CKTtime,ckt->CKTfinalTime); - 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) { - - if ( in_pss && pss_cycle_counter==1 ) { - /* 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, - (((PSSan*)ckt->CKTcurJob)->PSSplot_td)); - 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 +#ifdef XSPICE /* gtri - modify - wbk - 12/19/90 - Send IPC stuff */ - #endif - #ifdef CLUSTER + + if(g_ipc.enabled) { + + if ( in_pss && pss_cycle_counter==1 ) { + /* 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, + (((PSSan*)ckt->CKTcurJob)->PSSplot_td)); + 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 + if ( in_pss && pss_cycle_counter==1 ) { + CLUoutput(ckt); + } +#endif if ( in_pss && pss_cycle_counter==1 ) { - CLUoutput(ckt); + if(ckt->CKTtime >= ckt->CKTinitTime) CKTdump( ckt, ckt->CKTtime, ( ((PSSan*)ckt->CKTcurJob)->PSSplot_td) ); + *(psstimes+pss_points_cycle)=ckt->CKTtime; + for(count_1=1; count_1CKTrhsOld+count_1); + } + pss_points_cycle++; } - #endif - if ( in_pss && pss_cycle_counter==1 ) { - if(ckt->CKTtime >= ckt->CKTinitTime) CKTdump( ckt, ckt->CKTtime, ( ((PSSan*)ckt->CKTcurJob)->PSSplot_td) ); - *(psstimes+pss_points_cycle)=ckt->CKTtime; - for(count_1=1; count_1CKTrhsOld+count_1); - } - pss_points_cycle++; - } - #ifdef XSPICE +#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); + EVTaccept(ckt, ckt->CKTtime); /* gtri - end - wbk - Update event queues/data for accepted timepoint */ - #endif +#endif ckt->CKTstat->STAToldIter = ckt->CKTstat->STATnumIter; /* ***********************************/ /* ******* SHOOTING CODE BLOCK *******/ /* ***********************************/ if (in_stabilization) { - /* test if stabTime has been reached */ - if ( AlmostEqualUlps( ckt->CKTtime , ckt->CKTstabTime, 100 ) ) - { - /* use the 'dirty hack' to get near the fundamental frequency */ - if (nextTime_count<8192) { - for(count_2=1; count_20) { - delta_t += (times_fft[count_2]-times_fft[count_2-1])/nextTime_count; - } - } - } else { - for(count_2=1; count_2<8192; count_2++) { - if (times_fft[count_2]>0) { - delta_t += (times_fft[count_2]-times_fft[count_2-1])/8192; - } - } - } - if (ckt->CKTguessedFreq>1.1/delta_t/10 || ckt->CKTguessedFreq<0.9/delta_t/10) { - ckt->CKTguessedFreq=1.0/delta_t/10; /*** FREQUENCY INITIAL GUESS ***/ - printf("Frequency initial guess changed to %g from stabilization transient analysis.\n",ckt->CKTguessedFreq); - } - cont_1=1; - time_temp=ckt->CKTtime; - ckt->CKTfinalTime=time_temp+2/(ckt->CKTguessedFreq); - /* set the first requested breakpoint */ - CKTsetBreak(ckt, time_temp+1/(ckt->CKTguessedFreq)); - printf("Exiting from stabilization.\n"); - printf("Time of first shooting evaluation will be %1.10g.\n",time_temp+1/(ckt->CKTguessedFreq)); - /* next time is no more in stab - unset the flag */ - in_stabilization=0; - /* get matrix size and allocate memory */ - msize = SMPmatSize(ckt->CKTmatrix); - RHS_copy_se = TMALLOC(double, msize); - RHS_max = TMALLOC(double, msize); - RHS_min = TMALLOC(double, msize); - S_old = TMALLOC(double, msize); - S_diff = TMALLOC(double, msize); - /* print RHS on exiting from stab */ - printf("RHS on exiting from stabilization: "); - for(count_3 = 1; count_3 <= msize; count_3++) { - *(RHS_copy_se+count_3-1)= *(ckt->CKTrhsOld+count_3); - printf("%-15g ", *(RHS_copy_se+count_3-1)); - } - printf("\n"); - } + /* test if stabTime has been reached */ + if ( AlmostEqualUlps( ckt->CKTtime , ckt->CKTstabTime, 100 ) ) { + /* use the 'dirty hack' to get near the fundamental frequency */ + if (nextTime_count<8192) { + for(count_2=1; count_20) { + delta_t += (times_fft[count_2]-times_fft[count_2-1])/nextTime_count; + } + } + } else { + for(count_2=1; count_2<8192; count_2++) { + if (times_fft[count_2]>0) { + delta_t += (times_fft[count_2]-times_fft[count_2-1])/8192; + } + } + } + if (ckt->CKTguessedFreq>1.1/delta_t/10 || ckt->CKTguessedFreq<0.9/delta_t/10) { + ckt->CKTguessedFreq=1.0/delta_t/10; /*** FREQUENCY INITIAL GUESS ***/ + printf("Frequency initial guess changed to %g from stabilization transient analysis.\n",ckt->CKTguessedFreq); + } + cont_1=1; + time_temp=ckt->CKTtime; + ckt->CKTfinalTime=time_temp+2/(ckt->CKTguessedFreq); + /* set the first requested breakpoint */ + CKTsetBreak(ckt, time_temp+1/(ckt->CKTguessedFreq)); + printf("Exiting from stabilization.\n"); + printf("Time of first shooting evaluation will be %1.10g.\n",time_temp+1/(ckt->CKTguessedFreq)); + /* next time is no more in stab - unset the flag */ + in_stabilization=0; + /* get matrix size and allocate memory */ + msize = SMPmatSize(ckt->CKTmatrix); + RHS_copy_se = TMALLOC(double, msize); + RHS_max = TMALLOC(double, msize); + RHS_min = TMALLOC(double, msize); + S_old = TMALLOC(double, msize); + S_diff = TMALLOC(double, msize); + /* print RHS on exiting from stab */ + printf("RHS on exiting from stabilization: "); + for(count_3 = 1; count_3 <= msize; count_3++) { + *(RHS_copy_se+count_3-1)= *(ckt->CKTrhsOld+count_3); + printf("%-15g ", *(RHS_copy_se+count_3-1)); + } + printf("\n"); + } - /* ELSE not in stabilization but in shooting */ + /* ELSE not in stabilization but in shooting */ } else if ( !in_pss ) { - /* error norms of RHS solution on every accepted nextTime if out of stabilization */ - err=0; - for(count_4 = 1; count_4 <= msize; count_4++) - { - double diff = *(ckt->CKTrhsOld+count_4) - *(RHS_copy_se+count_4-1); - err += diff * diff; - /* save max and min per node or branch on every estimated period */ - if (*(RHS_max+count_4-1) < *(ckt->CKTrhsOld+count_4)) - *(RHS_max+count_4-1) = *(ckt->CKTrhsOld+count_4); - if (*(RHS_min+count_4-1) > *(ckt->CKTrhsOld+count_4)) - *(RHS_min+count_4-1) = *(ckt->CKTrhsOld+count_4); - } - err=sqrt(err); - /*** frequency projection ***/ - f_proj=(err-err_last)*(ckt->CKTguessedFreq); + /* error norms of RHS solution on every accepted nextTime if out of stabilization */ + err=0; + for(count_4 = 1; count_4 <= msize; count_4++) { + double diff = *(ckt->CKTrhsOld+count_4) - *(RHS_copy_se+count_4-1); + err += diff * diff; + /* save max and min per node or branch on every estimated period */ + if (*(RHS_max+count_4-1) < *(ckt->CKTrhsOld+count_4)) + *(RHS_max+count_4-1) = *(ckt->CKTrhsOld+count_4); + if (*(RHS_min+count_4-1) > *(ckt->CKTrhsOld+count_4)) + *(RHS_min+count_4-1) = *(ckt->CKTrhsOld+count_4); + } + err=sqrt(err); + /*** frequency projection ***/ + f_proj=(err-err_last)*(ckt->CKTguessedFreq); - err_last=err; + err_last=err; - /* Start frequency estimation */ - if (errCKTtime>=time_temp+0.5/ckt->CKTguessedFreq) /* far enough from time temp... */ - { - if (errCKTtime; /* store minimum of RHS vector error time */ - delta_1=delta_0; - delta_0=ckt->CKTdelta; - } - } - err_0=err; + /* Start frequency estimation */ + if (errCKTtime>=time_temp+0.5/ckt->CKTguessedFreq) { /* far enough from time temp... */ + if (errCKTtime; /* store minimum of RHS vector error time */ + delta_1=delta_0; + delta_0=ckt->CKTdelta; + } + } + err_0=err; - if (err>err_1 && ckt->CKTtime>=time_temp+0.1/ckt->CKTguessedFreq) /* far enough from time temp... */ - { - if (err>err_max) { - err_max=err; /* store maximum of RHS vector error */ - time_err_max=ckt->CKTtime; /* store maximum of RHS vector error time */ - } - } - err_1=err; + if (err>err_1 && ckt->CKTtime>=time_temp+0.1/ckt->CKTguessedFreq) { /* far enough from time temp... */ + if (err>err_max) { + err_max=err; /* store maximum of RHS vector error */ + time_err_max=ckt->CKTtime; /* store maximum of RHS vector error time */ + } + } + err_1=err; - /* if evolution is near shooting */ - if ( AlmostEqualUlps( ckt->CKTtime, time_temp+1/ckt->CKTguessedFreq, 10 ) || (ckt->CKTtime > time_temp+1/ckt->CKTguessedFreq) ) - { - if (shooting_cycle_counter == 0) { - /* If first time in shooting we warn about that ! */ - ntc_start_sh=nextTime_count; - printf("In shooting...\n"); - } + /* if evolution is near shooting */ + if ( AlmostEqualUlps( ckt->CKTtime, time_temp+1/ckt->CKTguessedFreq, 10 ) || (ckt->CKTtime > time_temp+1/ckt->CKTguessedFreq) ) { + if (shooting_cycle_counter == 0) { + /* If first time in shooting we warn about that ! */ + ntc_start_sh=nextTime_count; + printf("In shooting...\n"); + } - /* Take mean value of number of next time steps in one shooting evaluation - 4 frame window */ - ntc_vec[3]=ntc_vec[2]; - ntc_vec[2]=ntc_vec[1]; - ntc_vec[1]=ntc_vec[0]; - ntc_vec[0]=nextTime_count-ntc_old; - ntc_mv=(ntc_vec[0]+ntc_vec[1]+ntc_vec[2]+ntc_vec[3])*0.25; - ntc_old=nextTime_count; - printf("\n----------------\n"); - printf("Shooting cycle iteration number: %3d ||", shooting_cycle_counter); - printf("NTC_MV: %g || f_proj: %g\n", ntc_mv, f_proj); /* for debugging purpose */ - printf("Print of dynamically consistent nodes voltages or branches currents:\n"); + /* Take mean value of number of next time steps in one shooting evaluation - 4 frame window */ + ntc_vec[3]=ntc_vec[2]; + ntc_vec[2]=ntc_vec[1]; + ntc_vec[1]=ntc_vec[0]; + ntc_vec[0]=nextTime_count-ntc_old; + ntc_mv=(ntc_vec[0]+ntc_vec[1]+ntc_vec[2]+ntc_vec[3])*0.25; + ntc_old=nextTime_count; + printf("\n----------------\n"); + printf("Shooting cycle iteration number: %3d ||", shooting_cycle_counter); + printf("NTC_MV: %g || f_proj: %g\n", ntc_mv, f_proj); /* for debugging purpose */ + printf("Print of dynamically consistent nodes voltages or branches currents:\n"); - for(i=1, node=ckt->CKTnodes->next; node; i++, node=node->next) { + for(i=1, node=ckt->CKTnodes->next; node; i++, node=node->next) { - if (!strstr(node->name, "#")) { + if (!strstr(node->name, "#")) { - if (fabs(*(RHS_max+i-1))>fabs(*(RHS_min+i-1))) { - tv_01=fabs(*(RHS_max+i-1)); - } else { - tv_01=fabs(*(RHS_min+i-1)); - } - err_conv_ref += ( ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )*1e-3+1e-6)*7*ckt->CKTsteady_coeff; - if ( fabs( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) ) > 10*1e-6) - { - *(S_diff+i-1)= ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )/tv_01 - *(S_old+i-1); - *(S_old+i-1)= ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )/tv_01; - if(fabs(*(S_old+i-1))>0.1) printf("Node voltage %15s: RHS diff. %-15g || Conv. ref. %-15g || RHS max. %-15g || RHS min. %-15g || Snode %-15g\n",node->name, - (*(ckt->CKTrhsOld+i)-*(RHS_copy_se+i-1)), - ( ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )*1e-3+1e-6)*7*ckt->CKTsteady_coeff, - *(RHS_max+i-1), - *(RHS_min+i-1), - *(S_diff+i-1) - //( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) ) / ( (*(RHS_max+i-1)) + (*(RHS_min+i-1)) ) / 0.5 - ); - dynamic_test++; /* test on voltage dynamic consistence */ - } else - { - *(S_old+i-1)=0; - *(S_diff+i-1)=0; - } - } else { + if (fabs(*(RHS_max+i-1))>fabs(*(RHS_min+i-1))) { + tv_01=fabs(*(RHS_max+i-1)); + } else { + tv_01=fabs(*(RHS_min+i-1)); + } + err_conv_ref += ( ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )*1e-3+1e-6)*7*ckt->CKTsteady_coeff; + if ( fabs( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) ) > 10*1e-6) { + *(S_diff+i-1)= ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )/tv_01 - *(S_old+i-1); + *(S_old+i-1)= ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )/tv_01; + if(fabs(*(S_old+i-1))>0.1) printf("Node voltage %15s: RHS diff. %-15g || Conv. ref. %-15g || RHS max. %-15g || RHS min. %-15g || Snode %-15g\n",node->name, + (*(ckt->CKTrhsOld+i)-*(RHS_copy_se+i-1)), + ( ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )*1e-3+1e-6)*7*ckt->CKTsteady_coeff, + *(RHS_max+i-1), + *(RHS_min+i-1), + *(S_diff+i-1) + //( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) ) / ( (*(RHS_max+i-1)) + (*(RHS_min+i-1)) ) / 0.5 + ); + dynamic_test++; /* test on voltage dynamic consistence */ + } else { + *(S_old+i-1)=0; + *(S_diff+i-1)=0; + } + } else { - if (fabs(*(RHS_max+i-1))>fabs(*(RHS_min+i-1))) { - tv_01=fabs(*(RHS_max+i-1)); - } else { - tv_01=fabs(*(RHS_min+i-1)); - } - err_conv_ref += ( ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )*1e-3+1e-9)*7*ckt->CKTsteady_coeff; - if ( fabs( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) ) > 10*1e-9) - { - *(S_diff+i-1)= ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )/tv_01 - *(S_old+i-1); - *(S_old+i-1)= ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )/tv_01; - if(fabs(*(S_old+i-1))>0.1) printf("Branch current %15s: RHS diff. %-15g || Conv. ref. %-15g || RHS max. %-15g || RHS min. %-15g || Sbranch %-15g \n",node->name, - (*(ckt->CKTrhsOld+i)-*(RHS_copy_se+i-1)), - ( ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )*1e-3+1e-9)*7*ckt->CKTsteady_coeff, - *(RHS_max+i-1), - *(RHS_min+i-1), - *(S_diff+i-1) - //( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) ) / ( (*(RHS_max+i-1)) + (*(RHS_min+i-1)) ) / 0.5 - ); - dynamic_test++; /* test on current dynamic consistence */ - } else - { - *(S_old+i-1)=0; - *(S_diff+i-1)=0; - } - } - } - if (dynamic_test==0) { - /* Test for dynamic existence */ - printf("No detectable dynamic on voltages nodes or currents branches. PSS analysis aborted.\n"); - FREE(RHS_copy_se); - FREE(RHS_max); - FREE(RHS_min); - FREE(S_old); - FREE(S_diff); - return(OK); - } - if ((time_err_min_0-time_temp)<0) { - /* Something has gone wrong... */ - printf("Cannot find a minimum for error vector in estimated period. Try to adjust tstab! PSS analysis aborted.\n"); - FREE(RHS_copy_se); - FREE(RHS_max); - FREE(RHS_min); - FREE(S_old); - FREE(S_diff); - return(OK); - } - printf("Global Convergence Error reference: %g.\n", err_conv_ref/dynamic_test); - /*** FREQUENCY ESTIMATION UPDATE ***/ - if ( err_min_0==err || err_min_0==1e+30 ) { - ckt->CKTguessedFreq=(ckt->CKTguessedFreq)+f_proj; - #ifdef STEPDEBUG - printf("Frequency DOWN: est per %g, err min %g, err min 1 %g, err max %g, ntc %ld, err %g, err_last %g\n", time_err_min_0-time_temp,err_min_0,err_min_1,err_max,nextTime_count,err,err_last); - #endif - gf_last_1=gf_last_0; - gf_last_0=ckt->CKTguessedFreq; - } else { - ckt->CKTguessedFreq=1/(time_err_min_0-time_temp); - #ifdef STEPDEBUG - printf("Frequency UP: est per %g, err min %g, err min 1 %g, err max %g, ntc %ld, err %g, err_last %g\n", time_err_min_0-time_temp,err_min_0,err_min_1,err_max,nextTime_count,err,err_last); - #endif - gf_last_1=gf_last_0; - gf_last_0=ckt->CKTguessedFreq; - } - /* Store auxiliary variable of time_temp */ - time_temp_0=time_temp; - /* Next evaluation of shooting will be updated time (time_temp) summed to updated guessed period */ - time_temp=ckt->CKTtime; - /* IMPORTANT! Final time must be updated! Otherwise delta time can be wrongly calculated */ - ckt->CKTfinalTime=time_temp+2/ckt->CKTguessedFreq; - /* Set next the breakpoint */ - CKTsetBreak(ckt, time_temp+1/(ckt->CKTguessedFreq)); - /* Store error history */ - rr_history[shooting_cycle_counter]=err; - gf_history[shooting_cycle_counter]=ckt->CKTguessedFreq; - shooting_cycle_counter++; - printf("Updated guessed frequency: %1.10lg .\n",ckt->CKTguessedFreq); - printf("Next shooting evaluation time is %1.10g and current time is %1.10g.\n",time_temp+1/(ckt->CKTguessedFreq),ckt->CKTtime); - /* shooting exit condition */ - if ( shooting_cycle_counter>ckt->CKTsc_iter || (rr_history[shooting_cycle_counter-1] FE: %15.10g || RR: %15.10g\n",count_5+1,1.0/delta_t/10,rr_history[count_5+1]); /* the very lucky case */ - } else { - printf("%-3d -> FE: %15.10g || RR: %15.10g\n",count_5+1,gf_history[count_5],rr_history[count_5+1]); - } - #endif - /* reuse variables */ - if (rr_history[count_5]CKTsc_iter) { - ckt->CKTguessedFreq=gf_history[shooting_cycle_counter-1]; - printf("\nConvergence reached. Final circuit time is %1.10g s and predicted fundamental frequency is %g Hz.\n",ckt->CKTtime,ckt->CKTguessedFreq); - in_pss=1; /* PERIODIC STEADY STATE NOT REACHED however set the flag */ - } else { - ckt->CKTguessedFreq=gf_history[k-1]; - printf("\nConvergence not reached. However the most near convergence iteration has predicted (iteration %d) a fundamental frequency of %g Hz.\n",k,ckt->CKTguessedFreq); - in_pss=1; /* PERIODIC STEADY STATE REACHED set the flag */ - } - /* Allocates memory for nodes data in PSS */ - psstimes = TMALLOC(double, ckt->CKTpsspoints); - pssvalues = TMALLOC(double, msize*ckt->CKTpsspoints); - pssValues = TMALLOC(double, ckt->CKTpsspoints); - pssfreqs = TMALLOC(double, ckt->CKTharms); - pssmags = TMALLOC(double, ckt->CKTharms); - pssphases = TMALLOC(double, ckt->CKTharms); - pssnmags = TMALLOC(double, ckt->CKTharms); - pssnphases = TMALLOC(double, ckt->CKTharms); - pssResults = TMALLOC(double, msize*ckt->CKTharms); - } - /* restore maximum and minimum error for next search */ - err_min_0=1.0e+30; - err_max=-1.0e+30; - err_0=1.e30; - err_1=-1.0e+30; - tv_03=err_conv_ref; - err_conv_ref=0; - tv_04=dynamic_test; - dynamic_test=0; - rest=shooting_cycle_counter%2; - /* Reset actual RHS reference for next shooting evaluation */ - for(count_6 = 1; count_6 <= msize; count_6++) { - *(RHS_copy_se+count_6-1)= *(ckt->CKTrhsOld+count_6); - } - #ifdef STEPDEBUG - printf("RHS on new shooting cycle: "); - for(count_3 = 1; count_3 <= msize; count_3++) { - printf("%-15g ", *(RHS_copy_se+count_3-1)); - } - printf("\n"); - #endif - if (in_pss!=1) { - for(count_7 = 1; count_7 <= msize; count_7++) - { - /* reset max and min per node or branch on every shooting cycle */ - *(RHS_max+count_7-1)=-1.0e+30; - *(RHS_min+count_7-1)=1.0e+30; - } - } - printf("----------------\n\n"); - } + if (fabs(*(RHS_max+i-1))>fabs(*(RHS_min+i-1))) { + tv_01=fabs(*(RHS_max+i-1)); + } else { + tv_01=fabs(*(RHS_min+i-1)); + } + err_conv_ref += ( ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )*1e-3+1e-9)*7*ckt->CKTsteady_coeff; + if ( fabs( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) ) > 10*1e-9) { + *(S_diff+i-1)= ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )/tv_01 - *(S_old+i-1); + *(S_old+i-1)= ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )/tv_01; + if(fabs(*(S_old+i-1))>0.1) printf("Branch current %15s: RHS diff. %-15g || Conv. ref. %-15g || RHS max. %-15g || RHS min. %-15g || Sbranch %-15g \n",node->name, + (*(ckt->CKTrhsOld+i)-*(RHS_copy_se+i-1)), + ( ( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) )*1e-3+1e-9)*7*ckt->CKTsteady_coeff, + *(RHS_max+i-1), + *(RHS_min+i-1), + *(S_diff+i-1) + //( (*(RHS_max+i-1)) - (*(RHS_min+i-1)) ) / ( (*(RHS_max+i-1)) + (*(RHS_min+i-1)) ) / 0.5 + ); + dynamic_test++; /* test on current dynamic consistence */ + } else { + *(S_old+i-1)=0; + *(S_diff+i-1)=0; + } + } + } + if (dynamic_test==0) { + /* Test for dynamic existence */ + printf("No detectable dynamic on voltages nodes or currents branches. PSS analysis aborted.\n"); + FREE(RHS_copy_se); + FREE(RHS_max); + FREE(RHS_min); + FREE(S_old); + FREE(S_diff); + return(OK); + } + if ((time_err_min_0-time_temp)<0) { + /* Something has gone wrong... */ + printf("Cannot find a minimum for error vector in estimated period. Try to adjust tstab! PSS analysis aborted.\n"); + FREE(RHS_copy_se); + FREE(RHS_max); + FREE(RHS_min); + FREE(S_old); + FREE(S_diff); + return(OK); + } + printf("Global Convergence Error reference: %g.\n", err_conv_ref/dynamic_test); + /*** FREQUENCY ESTIMATION UPDATE ***/ + if ( err_min_0==err || err_min_0==1e+30 ) { + ckt->CKTguessedFreq=(ckt->CKTguessedFreq)+f_proj; +#ifdef STEPDEBUG + printf("Frequency DOWN: est per %g, err min %g, err min 1 %g, err max %g, ntc %ld, err %g, err_last %g\n", time_err_min_0-time_temp,err_min_0,err_min_1,err_max,nextTime_count,err,err_last); +#endif + gf_last_1=gf_last_0; + gf_last_0=ckt->CKTguessedFreq; + } else { + ckt->CKTguessedFreq=1/(time_err_min_0-time_temp); +#ifdef STEPDEBUG + printf("Frequency UP: est per %g, err min %g, err min 1 %g, err max %g, ntc %ld, err %g, err_last %g\n", time_err_min_0-time_temp,err_min_0,err_min_1,err_max,nextTime_count,err,err_last); +#endif + gf_last_1=gf_last_0; + gf_last_0=ckt->CKTguessedFreq; + } + /* Store auxiliary variable of time_temp */ + time_temp_0=time_temp; + /* Next evaluation of shooting will be updated time (time_temp) summed to updated guessed period */ + time_temp=ckt->CKTtime; + /* IMPORTANT! Final time must be updated! Otherwise delta time can be wrongly calculated */ + ckt->CKTfinalTime=time_temp+2/ckt->CKTguessedFreq; + /* Set next the breakpoint */ + CKTsetBreak(ckt, time_temp+1/(ckt->CKTguessedFreq)); + /* Store error history */ + rr_history[shooting_cycle_counter]=err; + gf_history[shooting_cycle_counter]=ckt->CKTguessedFreq; + shooting_cycle_counter++; + printf("Updated guessed frequency: %1.10lg .\n",ckt->CKTguessedFreq); + printf("Next shooting evaluation time is %1.10g and current time is %1.10g.\n",time_temp+1/(ckt->CKTguessedFreq),ckt->CKTtime); + /* shooting exit condition */ + if ( shooting_cycle_counter>ckt->CKTsc_iter || (rr_history[shooting_cycle_counter-1] FE: %15.10g || RR: %15.10g\n",count_5+1,1.0/delta_t/10,rr_history[count_5+1]); /* the very lucky case */ + } else { + printf("%-3d -> FE: %15.10g || RR: %15.10g\n",count_5+1,gf_history[count_5],rr_history[count_5+1]); + } +#endif + /* reuse variables */ + if (rr_history[count_5]CKTsc_iter) { + ckt->CKTguessedFreq=gf_history[shooting_cycle_counter-1]; + printf("\nConvergence reached. Final circuit time is %1.10g s and predicted fundamental frequency is %g Hz.\n",ckt->CKTtime,ckt->CKTguessedFreq); + in_pss=1; /* PERIODIC STEADY STATE NOT REACHED however set the flag */ + } else { + ckt->CKTguessedFreq=gf_history[k-1]; + printf("\nConvergence not reached. However the most near convergence iteration has predicted (iteration %d) a fundamental frequency of %g Hz.\n",k,ckt->CKTguessedFreq); + in_pss=1; /* PERIODIC STEADY STATE REACHED set the flag */ + } + /* Allocates memory for nodes data in PSS */ + psstimes = TMALLOC(double, ckt->CKTpsspoints); + pssvalues = TMALLOC(double, msize*ckt->CKTpsspoints); + pssValues = TMALLOC(double, ckt->CKTpsspoints); + pssfreqs = TMALLOC(double, ckt->CKTharms); + pssmags = TMALLOC(double, ckt->CKTharms); + pssphases = TMALLOC(double, ckt->CKTharms); + pssnmags = TMALLOC(double, ckt->CKTharms); + pssnphases = TMALLOC(double, ckt->CKTharms); + pssResults = TMALLOC(double, msize*ckt->CKTharms); + } + /* restore maximum and minimum error for next search */ + err_min_0=1.0e+30; + err_max=-1.0e+30; + err_0=1.e30; + err_1=-1.0e+30; + tv_03=err_conv_ref; + err_conv_ref=0; + tv_04=dynamic_test; + dynamic_test=0; + rest=shooting_cycle_counter%2; + /* Reset actual RHS reference for next shooting evaluation */ + for(count_6 = 1; count_6 <= msize; count_6++) { + *(RHS_copy_se+count_6-1)= *(ckt->CKTrhsOld+count_6); + } +#ifdef STEPDEBUG + printf("RHS on new shooting cycle: "); + for(count_3 = 1; count_3 <= msize; count_3++) { + printf("%-15g ", *(RHS_copy_se+count_3-1)); + } + printf("\n"); +#endif + if (in_pss!=1) { + for(count_7 = 1; count_7 <= msize; count_7++) { + /* reset max and min per node or branch on every shooting cycle */ + *(RHS_max+count_7-1)=-1.0e+30; + *(RHS_min+count_7-1)=1.0e+30; + } + } + printf("----------------\n\n"); + } } else { - /* return on the converged shooting condition */ - if ( AlmostEqualUlps( ckt->CKTtime, time_temp+1/ckt->CKTguessedFreq, 10 ) || (ckt->CKTtime > time_temp+1/ckt->CKTguessedFreq) ) - { - /* restore time */ - ckt->CKTtime=time_temp; - /* Set the breakpoint */ - CKTsetBreak(ckt, time_temp+1/(ckt->CKTguessedFreq)); - pss_cycle_counter++; - if (pss_cycle_counter>1) { - /* End plot in time domain */ - SPfrontEnd->OUTendPlot (((PSSan*)ckt->CKTcurJob)->PSSplot_td); - /* The following line must be placed just before a new OUTpBeginPlot is called */ - error = CKTnames(ckt,&numNames,&nameList); - if (error) return (error); - SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, - "frequency", UID_OTHER, NULL); - error = SPfrontEnd->OUTpBeginPlot (ckt, - ckt->CKTcurJob, - "Frequency Domain Periodic Steady State",freqUid,IF_REAL,numNames,nameList, - IF_REAL,&(((PSSan*)ckt->CKTcurJob)->PSSplot_fd)); - tfree(nameList); - /* ************************* */ - /* Fourier transform on data */ - /* ************************* */ - for(i4 = 1; i4 <= msize; i4++) { - for(k1=0; k1CKTpsspoints; k1++){ - *(pssValues+k1)=*(pssvalues+k1*msize+i4-1); - } - CKTfour(ckt->CKTpsspoints, ckt->CKTharms, &thd, psstimes, pssValues, - ckt->CKTguessedFreq, pssfreqs, pssmags, pssphases, pssnmags, - pssnphases); - for(k1 = 1; k1 <= ckt->CKTharms; k1++) { - *(pssResults+k1-1+(i4-1)*msize)=*(pssmags+k1-1); - } - } - for(k1 = 1; k1 <= ckt->CKTharms; k1++) { - for(i4 = 1; i4 <= msize; i4++) { - *(ckt->CKTrhsOld+i4)=*(pssResults+(k1-1)+(i4-1)*msize); - } - CKTdump( ckt, *(pssfreqs+(k1-1)), ( ((PSSan*)ckt->CKTcurJob)->PSSplot_fd) ); - } - /* End plot in freq domain */ - SPfrontEnd->OUTendPlot (((PSSan*)ckt->CKTcurJob)->PSSplot_fd); - FREE(RHS_copy_se); - FREE(RHS_max); - FREE(RHS_min); - FREE(S_old); - FREE(S_diff); - FREE(pssfreqs); - FREE(psstimes); - FREE(pssValues); - FREE(pssResults); - FREE(pssmags); - FREE(pssphases); - FREE(pssnmags); - FREE(pssnphases); - return(OK); - } - } + /* return on the converged shooting condition */ + if ( AlmostEqualUlps( ckt->CKTtime, time_temp+1/ckt->CKTguessedFreq, 10 ) || (ckt->CKTtime > time_temp+1/ckt->CKTguessedFreq) ) { + /* restore time */ + ckt->CKTtime=time_temp; + /* Set the breakpoint */ + CKTsetBreak(ckt, time_temp+1/(ckt->CKTguessedFreq)); + pss_cycle_counter++; + if (pss_cycle_counter>1) { + /* End plot in time domain */ + SPfrontEnd->OUTendPlot (((PSSan*)ckt->CKTcurJob)->PSSplot_td); + /* The following line must be placed just before a new OUTpBeginPlot is called */ + error = CKTnames(ckt,&numNames,&nameList); + if (error) return (error); + SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, + "frequency", UID_OTHER, NULL); + error = SPfrontEnd->OUTpBeginPlot (ckt, + ckt->CKTcurJob, + "Frequency Domain Periodic Steady State",freqUid,IF_REAL,numNames,nameList, + IF_REAL,&(((PSSan*)ckt->CKTcurJob)->PSSplot_fd)); + tfree(nameList); + /* ************************* */ + /* Fourier transform on data */ + /* ************************* */ + for(i4 = 1; i4 <= msize; i4++) { + for(k1=0; k1CKTpsspoints; k1++) { + *(pssValues+k1)=*(pssvalues+k1*msize+i4-1); + } + CKTfour(ckt->CKTpsspoints, ckt->CKTharms, &thd, psstimes, pssValues, + ckt->CKTguessedFreq, pssfreqs, pssmags, pssphases, pssnmags, + pssnphases); + for(k1 = 1; k1 <= ckt->CKTharms; k1++) { + *(pssResults+k1-1+(i4-1)*msize)=*(pssmags+k1-1); + } + } + for(k1 = 1; k1 <= ckt->CKTharms; k1++) { + for(i4 = 1; i4 <= msize; i4++) { + *(ckt->CKTrhsOld+i4)=*(pssResults+(k1-1)+(i4-1)*msize); + } + CKTdump( ckt, *(pssfreqs+(k1-1)), ( ((PSSan*)ckt->CKTcurJob)->PSSplot_fd) ); + } + /* End plot in freq domain */ + SPfrontEnd->OUTendPlot (((PSSan*)ckt->CKTcurJob)->PSSplot_fd); + FREE(RHS_copy_se); + FREE(RHS_max); + FREE(RHS_min); + FREE(S_old); + FREE(S_diff); + FREE(pssfreqs); + FREE(psstimes); + FREE(pssValues); + FREE(pssResults); + FREE(pssmags); + FREE(pssphases); + FREE(pssnmags); + FREE(pssnphases); + return(OK); + } + } } /* ********************************** */ /* **** END SHOOTING CODE BLOCK ***** */ /* ********************************** */ 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); + /* 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 */ - resume: +resume: if( (ckt->CKTdelta <= ckt->CKTfinalTime/50) && - (ckt->CKTdelta <= ckt->CKTmaxStep)) { - ; - } else { - #ifdef STEPDEBUG - if(ckt->CKTfinalTime/50CKTmaxStep) { - (void)printf("limited by Tstop/50\n"); - } else { - (void)printf("limited by Tmax == %g\n",ckt->CKTmaxStep); - } - #endif - } - #ifdef HAS_WINDOWS - if (ckt->CKTtime == 0.) - SetAnalyse( "tran init", 0); - else - SetAnalyse( "tran", (int)((ckt->CKTtime * 1000.) / 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) - if ( AlmostEqualUlps( ckt->CKTtime, g_mif_info.breakpoint.last, 100 ) ) - ckt->CKTorder = 1; - /* gtri - end - wbk - Cut integration order if first timepoint after breakpoint */ + (ckt->CKTdelta <= ckt->CKTmaxStep)) { + ; + } else { +#ifdef STEPDEBUG + if(ckt->CKTfinalTime/50CKTmaxStep) { + (void)printf("limited by Tstop/50\n"); + } else { + (void)printf("limited by Tmax == %g\n",ckt->CKTmaxStep); + } +#endif + } +#ifdef HAS_WINDOWS + if (ckt->CKTtime == 0.) + SetAnalyse( "tran init", 0); + else if (( !in_pss ) && (shooting_cycle_counter > 0)) + SetAnalyse( "shooting", shooting_cycle_counter); + else + SetAnalyse( "tran", (int)((ckt->CKTtime * 1000.) / 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) + if ( AlmostEqualUlps( ckt->CKTtime, g_mif_info.breakpoint.last, 100 ) ) + ckt->CKTorder = 1; + /* gtri - end - wbk - Cut integration order if first timepoint after breakpoint */ - #endif +#endif - /* are we at a breakpoint, or indistinguishably close? */ - //if ((ckt->CKTtime == *(ckt->CKTbreaks)) || (*(ckt->CKTbreaks) - - if ( (*(ckt->CKTbreaks)-(ckt->CKTtime) <= ckt->CKTdelmin) ) { - /*if ( AlmostEqualUlps( ckt->CKTtime, *(ckt->CKTbreaks), 100 ) || (*(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; - if( (ckt->CKTdelta >.1* ckt->CKTsaveDelta) || - (ckt->CKTdelta > .1*(*(ckt->CKTbreaks+1)-*(ckt->CKTbreaks))) ) { - if(ckt->CKTsaveDelta < (*(ckt->CKTbreaks+1)-*(ckt->CKTbreaks))) { - #ifdef STEPDEBUG - (void)printf("limited by pre-breakpoint delta (saveDelta: %1.10g, nxt_breakpt: %1.10g, curr_breakpt: %1.10g and CKTtime: %1.10g\n", - ckt->CKTsaveDelta, *(ckt->CKTbreaks+1), *(ckt->CKTbreaks), ckt->CKTtime); - #endif - } else { - #ifdef STEPDEBUG - (void)printf("limited by next breakpoint\n"); - (void)printf("(saveDelta: %1.10g, Delta: %1.10g, CKTtime: %1.10g and delmin: %1.10g\n",ckt->CKTsaveDelta,ckt->CKTdelta,ckt->CKTtime,ckt->CKTdelmin); - #endif - } - } + /* are we at a breakpoint, or indistinguishably close? */ + //if ((ckt->CKTtime == *(ckt->CKTbreaks)) || (*(ckt->CKTbreaks) - + if ( (*(ckt->CKTbreaks)-(ckt->CKTtime) <= ckt->CKTdelmin) ) { + /*if ( AlmostEqualUlps( ckt->CKTtime, *(ckt->CKTbreaks), 100 ) || (*(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; + if( (ckt->CKTdelta >.1* ckt->CKTsaveDelta) || + (ckt->CKTdelta > .1*(*(ckt->CKTbreaks+1)-*(ckt->CKTbreaks))) ) { + if(ckt->CKTsaveDelta < (*(ckt->CKTbreaks+1)-*(ckt->CKTbreaks))) { +#ifdef STEPDEBUG + (void)printf("limited by pre-breakpoint delta (saveDelta: %1.10g, nxt_breakpt: %1.10g, curr_breakpt: %1.10g and CKTtime: %1.10g\n", + ckt->CKTsaveDelta, *(ckt->CKTbreaks+1), *(ckt->CKTbreaks), ckt->CKTtime); +#endif + } else { +#ifdef STEPDEBUG + (void)printf("limited by next breakpoint\n"); + (void)printf("(saveDelta: %1.10g, Delta: %1.10g, CKTtime: %1.10g and delmin: %1.10g\n",ckt->CKTsaveDelta,ckt->CKTdelta,ckt->CKTtime,ckt->CKTdelmin); +#endif + } + } - if ( (*(ckt->CKTbreaks+1)-*(ckt->CKTbreaks)) == 0 ) { - ckt->CKTdelta = ckt->CKTdelmin; - } else { - ckt->CKTdelta = MIN(ckt->CKTdelta, .1 * MIN(ckt->CKTsaveDelta, - *(ckt->CKTbreaks+1)-*(ckt->CKTbreaks))); - } + if ( (*(ckt->CKTbreaks+1)-*(ckt->CKTbreaks)) == 0 ) { + ckt->CKTdelta = ckt->CKTdelmin; + } else { + 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 - } + if(firsttime) { + ckt->CKTdelta /= 10; +#ifdef STEPDEBUG + (void)printf("delta cut for initial timepoint\n"); +#endif + } - #ifdef XSPICE - } +#ifdef XSPICE + } - /* gtri - begin - wbk - Add Breakpoint stuff */ + /* 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; - } + 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 - end - wbk - Add Breakpoint stuff */ - /* gtri - begin - wbk - Modify Breakpoint stuff */ - /* Throw out any permanent breakpoint times <= current time */ - while(1) { - printf(" brk_pt: %g ckt_time: %g ckt_min_break: %g\n",*(ckt->CKTbreaks), ckt->CKTtime, ckt->CKTminBreak); - if(AlmostEqualUlps(*(ckt->CKTbreaks),ckt->CKTtime, 100) || *(ckt->CKTbreaks) <= (ckt->CKTtime + ckt->CKTminBreak)) { - printf("throwing out permanent breakpoint times <= current time (brk pt: %g)\n",*(ckt->CKTbreaks)); - printf("ckt_time: %g ckt_min_break: %g\n",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 - begin - wbk - Modify Breakpoint stuff */ + /* Throw out any permanent breakpoint times <= current time */ + while(1) { +#ifdef STEPDEBUG + printf(" brk_pt: %g ckt_time: %g ckt_min_break: %g\n",*(ckt->CKTbreaks), ckt->CKTtime, ckt->CKTminBreak); +#endif + if(AlmostEqualUlps(*(ckt->CKTbreaks),ckt->CKTtime, 100) || *(ckt->CKTbreaks) <= (ckt->CKTtime + ckt->CKTminBreak)) { + printf("throwing out permanent breakpoint times <= current time (brk pt: %g)\n",*(ckt->CKTbreaks)); + printf("ckt_time: %g ckt_min_break: %g\n",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 */ + /* 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; - /*(void)printf("delta cut to %g to hit breakpoint\n",ckt->CKTdelta);*/ - fflush(stdout); - 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 */ + /* 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; + /*(void)printf("delta cut to %g to hit breakpoint\n",ckt->CKTdelta);*/ + fflush(stdout); + 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 */ +#endif /* XSPICE */ - #ifdef XSPICE - /* gtri - begin - wbk - Do event solution */ +#ifdef XSPICE + /* gtri - begin - wbk - Do event solution */ - if(ckt->evt->counts.num_insts > 0) { + 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); + /* 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 */ - /* projected analog time, process them */ - while((g_mif_info.circuit.evt_step = EVTnext_time(ckt)) - <= (ckt->CKTtime + ckt->CKTdelta)) { + /* while there are events on the queue with event time <= next */ + /* 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; + /* 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); + /* 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; - } - } + /* 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 */ + } /* end while next event time <= next analog time */ + } /* end if there are event instances */ - /* gtri - end - wbk - Do event solution */ - #endif - for(i5=5;i5>=0;i5--) { - ckt->CKTdeltaOld[i5+1]=ckt->CKTdeltaOld[i5]; - } - ckt->CKTdeltaOld[0]=ckt->CKTdelta; + /* gtri - end - wbk - Do event solution */ +#endif + for(i5=5; i5>=0; i5--) + { + ckt->CKTdeltaOld[i5+1]=ckt->CKTdeltaOld[i5]; + } + ckt->CKTdeltaOld[0]=ckt->CKTdelta; - temp = ckt->CKTstates[ckt->CKTmaxOrder+1]; - for(i5=ckt->CKTmaxOrder;i5>=0;i5--) { - ckt->CKTstates[i5+1] = ckt->CKTstates[i5]; - } - ckt->CKTstates[0] = temp; + temp = ckt->CKTstates[ckt->CKTmaxOrder+1]; + for(i5=ckt->CKTmaxOrder; i5>=0; i5--) + { + ckt->CKTstates[i5+1] = ckt->CKTstates[i5]; + } + 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 ... */ + /* 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; + ckt->CKTcurrentAnalysis = DOING_TRAN; - /* gtri - end - wbk - 4/17/91 - Fix Berkeley bug */ - #endif - olddelta=ckt->CKTdelta; - /* time abort? */ + /* gtri - end - wbk - 4/17/91 - Fix Berkeley bug */ +#endif + olddelta=ckt->CKTdelta; + /* time abort? */ - /* ************************************ */ - /* ********** CKTtime update ********** */ - /* ************************************ */ - /* delta manipulation */ - if (!in_stabilization && !in_pss){ - if ( (ckt->CKTtime-(time_temp+1/ckt->CKTguessedFreq)<1/ckt->CKTguessedFreq/10) && (ckt->CKTbreak==0) ) - { - if ( !(flag_tu_1) ) flag_tu_2=ckt->CKTdelta; /* store previous delta */ - if ( (ckt->CKTtime-(time_temp+1/ckt->CKTguessedFreq)<1/ckt->CKTguessedFreq/1.0e5) && (ckt->CKTbreak==0) ) - { - if ( (ckt->CKTtime-(time_temp+1/ckt->CKTguessedFreq)<1/ckt->CKTguessedFreq/1.0e7) && (ckt->CKTbreak==0) ) - { - if (rr_history[shooting_cycle_counter-1]CKTdelta=1/ckt->CKTguessedFreq/1.0e5; /* get closer to accurate solution? */ - } else { - ckt->CKTdelta=1/ckt->CKTguessedFreq/1.0e4; - } - } else - { - ckt->CKTdelta=1/ckt->CKTguessedFreq/1.0e1; - } - } else - { - ckt->CKTdelta=1/ckt->CKTguessedFreq/0.25e1; - } - flag_tu_1=1; - } else - { - if (flag_tu_1) { - ckt->CKTdelta=flag_tu_2; /* restore prevoius delta */ - flag_tu_1=0; - } - } - } - if ( in_pss ) ckt->CKTdelta=1/ckt->CKTguessedFreq/((ckt->CKTpsspoints-1)); /* fixed delta in PSS */ - /* ************************************ */ - /* ******* END CKTtime update ********* */ - /* ************************************ */ + /* ************************************ */ + /* ********** CKTtime update ********** */ + /* ************************************ */ + /* delta manipulation */ + if (!in_stabilization && !in_pss) { + if ( (ckt->CKTtime-(time_temp+1/ckt->CKTguessedFreq)<1/ckt->CKTguessedFreq/10) && (ckt->CKTbreak==0) ) { + if ( !(flag_tu_1) ) flag_tu_2=ckt->CKTdelta; /* store previous delta */ + if ( (ckt->CKTtime-(time_temp+1/ckt->CKTguessedFreq)<1/ckt->CKTguessedFreq/1.0e5) && (ckt->CKTbreak==0) ) { + if ( (ckt->CKTtime-(time_temp+1/ckt->CKTguessedFreq)<1/ckt->CKTguessedFreq/1.0e7) && (ckt->CKTbreak==0) ) { + if (rr_history[shooting_cycle_counter-1]CKTdelta=1/ckt->CKTguessedFreq/1.0e5; /* get closer to accurate solution? */ + } else { + ckt->CKTdelta=1/ckt->CKTguessedFreq/1.0e4; + } + } else { + ckt->CKTdelta=1/ckt->CKTguessedFreq/1.0e1; + } + } else { + ckt->CKTdelta=1/ckt->CKTguessedFreq/0.25e1; + } + flag_tu_1=1; + } else { + if (flag_tu_1) { + ckt->CKTdelta=flag_tu_2; /* restore prevoius delta */ + flag_tu_1=0; + } + } + } + if ( in_pss ) ckt->CKTdelta=1/ckt->CKTguessedFreq/((ckt->CKTpsspoints-1)); /* fixed delta in PSS */ + /* ************************************ */ + /* ******* END CKTtime update ********* */ + /* ************************************ */ - ckt->CKTtime += ckt->CKTdelta; + 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 */ +#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; + /* Initialize temporary breakpoint to infinity */ + g_mif_info.breakpoint.current = 1.0e30; - /* gtri - end - wbk - Add Breakpoint stuff */ + /* 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 - 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 - Call all hybrids */ - /* gtri - begin - wbk - Set evt_step */ + /* 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 + 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); + 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 */ +#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;iCKTnumStates;i++) { - *(ckt->CKTstate2+i) = *(ckt->CKTstate1+i); - *(ckt->CKTstate3+i) = *(ckt->CKTstate1+i); - } - } - /* txl, cpl addition */ - if (converged == 1111) { - return(converged); - } +#endif + ckt->CKTstat->STATtimePts ++; + ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITPRED; + if(firsttime) { + for(i=0; iCKTnumStates; 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; - /*printf("delta cut to %g for non-convergance\n",ckt->CKTdelta);*/ - #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; + if(converged != 0) { +#ifndef CLUSTER + ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta; + ckt->CKTstat->STATrejected ++; +#endif + ckt->CKTdelta = ckt->CKTdelta/8; + /*printf("delta cut to %g for non-convergance\n",ckt->CKTdelta);*/ +#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 */ +#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; + /* 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; + if(firsttime) { + ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN; + } + ckt->CKTorder = 1; - /* gtri - end - wbk - Add Breakpoint stuff */ - #endif + /* 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 + } 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 NDEV - /* show a time process indicator, by Gong Ding, gdiso@ustc.edu */ - if(ckt->CKTtime/ckt->CKTfinalTime*100<10.0) - printf("%%%3.2lf\b\b\b\b\b",ckt->CKTtime/ckt->CKTfinalTime*100); - else if(ckt->CKTtime/ckt->CKTfinalTime*100<100.0) - printf("%%%4.2lf\b\b\b\b\b\b",ckt->CKTtime/ckt->CKTfinalTime*100); - else - printf("%%%5.2lf\b\b\b\b\b\b\b",ckt->CKTtime/ckt->CKTfinalTime*100); - fflush(stdout); - #endif +#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 NDEV + /* show a time process indicator, by Gong Ding, gdiso@ustc.edu */ + if(ckt->CKTtime/ckt->CKTfinalTime*100<10.0) + printf("%%%3.2lf\b\b\b\b\b",ckt->CKTtime/ckt->CKTfinalTime*100); + else if(ckt->CKTtime/ckt->CKTfinalTime*100<100.0) + printf("%%%4.2lf\b\b\b\b\b\b",ckt->CKTtime/ckt->CKTfinalTime*100); + else + printf("%%%5.2lf\b\b\b\b\b\b\b",ckt->CKTtime/ckt->CKTfinalTime*100); + fflush(stdout); +#endif - #ifdef STEPDEBUG - (void)printf( - "delta set to truncation error result: %g. Point accepted at CKTtime: %g\n", - ckt->CKTdelta,ckt->CKTtime); - 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 */ +#ifdef STEPDEBUG + (void)printf( + "delta set to truncation error result: %g. Point accepted at CKTtime: %g\n", + ckt->CKTdelta,ckt->CKTtime); + 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(ckt, "Timestep too small"); - return(E_TIMESTEP); - } - } - #ifdef XSPICE - /* gtri - begin - wbk - Do event backup */ + 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(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); + 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 */ + /* 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 */ } int CKTfour(int ndata, /* number of entries in the Time and Value arrays */ - int numFreq, /* number of harmonics to calculate */ - double *thd, /* total harmonic distortion (percent) + int numFreq, /* number of harmonics to calculate */ + double *thd, /* total harmonic distortion (percent) to be returned */ - double *Time, /* times at which the voltage/current + double *Time, /* times at which the voltage/current values were measured*/ - double *Value, /* voltage or current vector whose + double *Value, /* voltage or current vector whose transform is desired */ - double FundFreq, /* the fundamental frequency of the + double FundFreq, /* the fundamental frequency of the analysis */ - double *Freq, /* the frequency value of the various + double *Freq, /* the frequency value of the various harmonics */ - double *Mag, /* the Magnitude of the fourier + double *Mag, /* the Magnitude of the fourier transform */ - double *Phase, /* the Phase of the fourier transform */ - double *nMag, /* the normalized magnitude of the + double *Phase, /* the Phase of the fourier transform */ + double *nMag, /* the normalized magnitude of the transform: nMag(fund)=1*/ - double *nPhase) /* the normalized phase of the + double *nPhase) /* the normalized phase of the transform: Nphase(fund)=0 */ { /* Note: we can consider these as a set of arrays. The sizes are: @@ -1426,12 +1415,12 @@ CKTfour(int ndata, /* number of entries in the Time and /* clear output/computation arrays */ - for(i=0;i