📄 dctran.c
字号:
/**********Copyright 1990 Regents of the University of California. All rights reserved.Author: 1985 Thomas L. QuarlesModified: 2000 AlansFixes**********//* subroutine to do DC TRANSIENT analysis --- ONLY, unlike spice2 routine with the same name! */#include<ngspice.h>#include <config.h>#include <cktdefs.h>#include <cktaccept.h>#include <trandefs.h>#include <sperror.h>#ifdef XSPICE/* gtri - add - wbk - Add headers */#include "miftypes.h" /* gtri - end - wbk - Add headers *//* gtri - add - wbk - Add headers */#include "evt.h"#include "mif.h"#include "evtproto.h"#include "ipctiein.h"/* gtri - end - wbk - Add headers */#endif#ifdef CLUSTER#include "cluster.h"#endif#ifdef HAS_WINDOWS /* hvogt 10.03.99, nach W. Mues */void SetAnalyse( char * Analyse, int Percent);#endifintDCtran(CKTcircuit *ckt, int restart) /* forced restart flag */{ 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 *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 if(restart || ckt->CKTtime == 0) { delta=MIN(ckt->CKTfinalTime/200,ckt->CKTstep)/10; /* 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 = ckt->CKTfinalTime / 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=(double *)MALLOC(2*sizeof(double)); if(ckt->CKTbreaks == (double *)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))((void *)ckt,&timeUid,(IFuid)NULL, "time", UID_OTHER, (void **)NULL); error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, (void*)ckt->CKTcurJob, ckt->CKTcurJob->JOBname,timeUid,IF_REAL,numNames,nameList, IF_REAL,&(((TRANan*)ckt->CKTcurJob)->TRANplot)); 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); if(converged != 0) { fprintf(stdout,"\nTransient solution failed -\n"); CKTncDump(ckt); /* CKTnode *node; double new, old, tol; int i=1; fprintf(stdout,"\nTransient solution failed -\n\n"); fprintf(stdout,"Last Node Voltages\n"); fprintf(stdout,"------------------\n\n"); fprintf(stdout,"%-30s %20s %20s\n", "Node", "Last Voltage", "Previous Iter"); fprintf(stdout,"%-30s %20s %20s\n", "----", "------------", "-------------"); for(node=ckt->CKTnodes->next;node;node=node->next) { if (strstr(node->name, "#branch") || !strstr(node->name, "#")) { new = *((ckt->CKTrhsOld) + i ) ; old = *((ckt->CKTrhs) + i ) ; fprintf(stdout,"%-30s %20g %20g", node->name, new, old); if(node->type == 3) { tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) + ckt->CKTvoltTol; } else { tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) + ckt->CKTabstol; } if (fabs(new-old) >tol ) { fprintf(stdout," *"); } fprintf(stdout,"\n"); }; i++; } */ } else { 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); 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,(((TRANan*)ckt->CKTcurJob)->TRANplot)); 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 ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN; /* modeinittran set here */ ckt->CKTag[0]=ckt->CKTag[1]=0; bcopy((char *)ckt->CKTstate0,(char *)ckt->CKTstate1, 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))();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -