Fixed xspice extensions.
This commit is contained in:
parent
51988dfb80
commit
b8dca1b4c2
23
ChangeLog
23
ChangeLog
|
|
@ -1,3 +1,26 @@
|
|||
2005-06-25 Paolo Nenzi <p.nenzi@ieee.org>
|
||||
|
||||
* src/spicelib/analysis/acan.c: modified original integration of xspice
|
||||
event driven algorithm into spice3 code. Now CKTncDump() is used by
|
||||
xspice too.
|
||||
|
||||
* src/spicelib/analysis/cktdojob.c: added ipc stuff.
|
||||
|
||||
* src/spicelib/analysis/cktload.c: cosmetics.
|
||||
|
||||
* src/spicelib/analysis/cktop.c: modularized the source and gmin stepping
|
||||
algorithm. I have extracted the code for gmin and source stepping to
|
||||
improve CKTop readability and manutenibity.
|
||||
|
||||
* src/spicelib/analysis/dcop.c: added event driven algorithm and ipc stuff.
|
||||
|
||||
* src/spicelib/analysis/dctran.c: added xspice breakpoint control.
|
||||
|
||||
* src/spicelib/analysis/dctrcurv.c: added event driven algorithm and ipc
|
||||
stuff.
|
||||
|
||||
|
||||
|
||||
2005-06-12 Steven Borley <steven.borley@virgin.net>
|
||||
|
||||
* Changes supplied bt Hitoshi Tanaka to allow XSpice to compile using MinGW
|
||||
|
|
|
|||
|
|
@ -42,17 +42,20 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
static void *acPlot = NULL;
|
||||
void *plot = NULL;
|
||||
|
||||
/* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */
|
||||
|
||||
/* Tell the beginPlot routine what mode we're in */
|
||||
g_ipc.anal_type = IPC_ANAL_AC;
|
||||
|
||||
/* 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;
|
||||
#endif
|
||||
|
||||
/* gtri - end - wbk */
|
||||
#endif
|
||||
|
||||
|
||||
if(((ACAN*)ckt->CKTcurJob)->ACsaveFreq == 0 || restart) {
|
||||
/* start at beginning */
|
||||
|
|
@ -87,16 +90,8 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
}
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - Call EVTop if event-driven instances exist */
|
||||
if(ckt->evt->counts.num_insts == 0) {
|
||||
/* If no event-driven instances, do what SPICE normally does */
|
||||
error = CKTop(ckt,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
|
||||
ckt->CKTdcMaxIter);
|
||||
if(error) return(error);
|
||||
}
|
||||
else {
|
||||
/* Else, use new DCOP algorithm */
|
||||
|
||||
if(ckt->evt->counts.num_insts != 0) {
|
||||
error = EVTop(ckt,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
|
||||
|
|
@ -104,21 +99,21 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
MIF_TRUE);
|
||||
EVTdump(ckt, IPC_ANAL_DCOP, 0.0);
|
||||
EVTop_save(ckt, MIF_TRUE, 0.0);
|
||||
if(error)
|
||||
return(error);
|
||||
}
|
||||
/* gtri - end - wbk - Call EVTop if event-driven instances exist */
|
||||
#else
|
||||
error = CKTop(ckt,
|
||||
else
|
||||
#endif
|
||||
/* If no event-driven instances, do what SPICE normally does */
|
||||
|
||||
error = CKTop(ckt,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
|
||||
ckt->CKTdcMaxIter);
|
||||
|
||||
if(error){
|
||||
fprintf(stdout,"\nAC operating point failed -\n");
|
||||
CKTncDump(ckt);
|
||||
return(error);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 12/19/90 - Add IPC stuff */
|
||||
|
|
@ -126,14 +121,18 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
/* Send the operating point results for Mspice compatibility */
|
||||
if(g_ipc.enabled)
|
||||
{
|
||||
/* Call CKTnames to get names of nodes/branches used by BeginPlot */
|
||||
/* Probably should free nameList after this block since called again... */
|
||||
/* Call CKTnames to get names of nodes/branches used by
|
||||
BeginPlot */
|
||||
/* Probably should free nameList after this block since
|
||||
called again... */
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
if(error) return(error);
|
||||
|
||||
/* We have to do a beginPlot here since the data to return is */
|
||||
/* different for the DCOP than it is for the AC analysis. Moreover */
|
||||
/* the begin plot has not even been done yet at this point... */
|
||||
/* We have to do a beginPlot here since the data to return is
|
||||
* different for the DCOP than it is for the AC analysis.
|
||||
* Moreover the begin plot has not even been done yet at this
|
||||
* point...
|
||||
*/
|
||||
(*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,(void*)ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,(IFuid)NULL,IF_REAL,numNames,nameList,
|
||||
IF_REAL,&acPlot);
|
||||
|
|
@ -148,6 +147,7 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
|
||||
/* gtri - end - wbk */
|
||||
#endif
|
||||
|
||||
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
|
||||
error = CKTload(ckt);
|
||||
if(error) return(error);
|
||||
|
|
@ -205,14 +205,18 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
return(E_BADPARM);
|
||||
}
|
||||
|
||||
/* gtri - add - wbk - 12/19/90 - Set anal_init and anal_type */
|
||||
|
||||
#ifdef XSPICE
|
||||
/* 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_AC;
|
||||
#endif
|
||||
|
||||
/* gtri - end - wbk */
|
||||
#endif
|
||||
|
||||
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
startdTime = ckt->CKTstat->STATdecompTime;
|
||||
|
|
@ -267,8 +271,10 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
ckt->CKTsenInfo->SENmode = save1;
|
||||
}
|
||||
#endif
|
||||
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
|
||||
|
||||
if(g_ipc.enabled)
|
||||
ipc_send_data_prefix(freq);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ Modified: 2000 AlansFixes
|
|||
#include "mif.h"
|
||||
#include "evtproto.h"
|
||||
/* gtri - end - wbk - 11/26/90 */
|
||||
/* gtri - add - 12/12/90 - wbk - include ipc stuff */
|
||||
#include "ipctiein.h"
|
||||
/* gtri - end - 12/12/90 */
|
||||
#endif
|
||||
|
||||
extern SPICEanalysis *analInfo[];
|
||||
|
|
@ -119,12 +122,52 @@ printf("Doing analysis at TEMP = %f and TNOM = %f\n",
|
|||
/* normal reset */
|
||||
if (!error)
|
||||
error = CKTunsetup(ckt);
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - 12/12/90 - wbk - set ipc syntax error flag */
|
||||
if(error) g_ipc.syntax_error = IPC_TRUE;
|
||||
/* gtri - end - 12/12/90 */
|
||||
#endif
|
||||
|
||||
if (!error)
|
||||
error = CKTsetup(ckt);
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - 12/12/90 - wbk - set ipc syntax error flag */
|
||||
if(error) g_ipc.syntax_error = IPC_TRUE;
|
||||
/* gtri - end - 12/12/90 */
|
||||
#endif
|
||||
|
||||
if (!error)
|
||||
error = CKTtemp(ckt);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - 12/12/90 - wbk - set ipc syntax error flag */
|
||||
if(error) g_ipc.syntax_error = IPC_TRUE;
|
||||
/* gtri - end - 12/12/90 */
|
||||
#endif
|
||||
|
||||
if (error) {
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - 12/12/90 - wbk - return if syntax errors from parsing */
|
||||
if(g_ipc.enabled) {
|
||||
if(g_ipc.syntax_error)
|
||||
;
|
||||
else {
|
||||
/* else, send (GO) errchk status if we got this far */
|
||||
/* Caller is responsible for sending NOGO status if we returned earlier */
|
||||
ipc_send_errchk();
|
||||
}
|
||||
}
|
||||
/* gtri - end - 12/12/90 */
|
||||
#endif
|
||||
|
||||
|
||||
return error;
|
||||
|
||||
|
||||
}/* if error */
|
||||
}
|
||||
|
||||
error2 = OK;
|
||||
|
|
|
|||
|
|
@ -83,8 +83,10 @@ CKTload(CKTcircuit *ckt)
|
|||
}
|
||||
}
|
||||
|
||||
/* gtri - add - wbk - 11/26/90 - reset the MIF init flags */
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 11/26/90 - reset the MIF init flags */
|
||||
|
||||
/* init is set by CKTinit and should be true only for first load call */
|
||||
g_mif_info.circuit.init = MIF_FALSE;
|
||||
|
||||
|
|
@ -104,9 +106,9 @@ CKTload(CKTcircuit *ckt)
|
|||
*(ckt->enh->rshunt_data.diag[i]) += gshunt;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* gtri - end - Put resistors to ground at all nodes */
|
||||
|
||||
/* gtri - end - Put resistors to ground at all nodes */
|
||||
#endif
|
||||
|
||||
if(ckt->CKTmode & MODEDC) {
|
||||
/* consider doing nodeset & ic assignments */
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
Modified: 2005 Paolo Nenzi - Restructured
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -10,340 +11,75 @@ Modified: 2000 AlansFixes
|
|||
#include "sperror.h"
|
||||
|
||||
|
||||
static int dynamic_gmin (CKTcircuit *, long int, long int, int);
|
||||
static int spice3_gmin (CKTcircuit *, long int, long int, int);
|
||||
static int gillespie_src (CKTcircuit *, long int, long int, int);
|
||||
static int spice3_src (CKTcircuit *, long int, long int, int);
|
||||
|
||||
|
||||
int
|
||||
CKTop(CKTcircuit *ckt, long int firstmode, long int continuemode, int iterlim)
|
||||
CKTop (CKTcircuit * ckt, long int firstmode, long int continuemode,
|
||||
int iterlim)
|
||||
{
|
||||
int converged;
|
||||
int i;
|
||||
CKTnode *n;
|
||||
double raise, ConvFact, NumNodes;
|
||||
double *OldRhsOld, *OldCKTstate0;
|
||||
int iters;
|
||||
|
||||
ckt->CKTmode = firstmode;
|
||||
if(!ckt->CKTnoOpIter) {
|
||||
converged = NIiter(ckt,iterlim);
|
||||
int converged;
|
||||
|
||||
ckt->CKTmode = firstmode;
|
||||
|
||||
if (!ckt->CKTnoOpIter){
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||
if ((ckt->CKTnumGminSteps <= 0) && (ckt->CKTnumSrcSteps <= 0))
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
||||
else
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||
#endif
|
||||
converged = NIiter (ckt, iterlim);
|
||||
} else {
|
||||
converged = 1; /* the 'go directly to gmin stepping' option */
|
||||
}
|
||||
if(converged != 0) {
|
||||
/* no convergence on the first try, so we do something else */
|
||||
/* first, check if we should try gmin stepping */
|
||||
/* note that no path out of this code allows ckt->CKTdiagGmin to be
|
||||
* anything but 0.000000000
|
||||
*/
|
||||
converged = 1; /* the 'go directly to gmin stepping' option */
|
||||
}
|
||||
|
||||
|
||||
if (converged != 0)
|
||||
{
|
||||
/* no convergence on the first try, so we do something else */
|
||||
/* first, check if we should try gmin stepping */
|
||||
|
||||
if (ckt->CKTnumGminSteps >= 1){
|
||||
if (ckt->CKTnumGminSteps == 1){
|
||||
converged = dynamic_gmin(ckt, firstmode, continuemode, iterlim);
|
||||
} else {
|
||||
converged = spice3_gmin(ckt, firstmode, continuemode, iterlim);
|
||||
}
|
||||
}
|
||||
if (!converged) /* If gmin-stepping worked... move out */
|
||||
return (0);
|
||||
|
||||
/* ... otherwise try stepping sources ...
|
||||
* now, we'll try source stepping - we scale the sources
|
||||
* to 0, converge, then start stepping them up until they
|
||||
* are at their normal values
|
||||
*/
|
||||
|
||||
if (ckt->CKTnumSrcSteps >= 1){
|
||||
if (ckt->CKTnumSrcSteps == 1)
|
||||
converged = gillespie_src(ckt, firstmode, continuemode, iterlim);
|
||||
else
|
||||
converged = spice3_src(ckt, firstmode, continuemode, iterlim);
|
||||
}
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||
#endif
|
||||
|
||||
}
|
||||
return (converged);
|
||||
|
||||
if(ckt->CKTnumGminSteps ==1) {
|
||||
|
||||
double OldGmin, gtarget, factor;
|
||||
int success, failed;
|
||||
|
||||
ckt->CKTmode = firstmode;
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"trying dynamic Gmin stepping",(IFuid *)NULL);
|
||||
NumNodes=0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
NumNodes++;
|
||||
};
|
||||
OldRhsOld=(double *)MALLOC((NumNodes+1)*sizeof(double));
|
||||
OldCKTstate0=(double *)
|
||||
MALLOC((ckt->CKTnumStates+1)*sizeof(double));
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
*(ckt->CKTrhsOld+n->number)=0;
|
||||
};
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(ckt->CKTstate0+i) = 0;
|
||||
};
|
||||
factor = ckt->CKTgminFactor;
|
||||
OldGmin = 1e-2;
|
||||
ckt->CKTdiagGmin = OldGmin / factor;
|
||||
gtarget = MAX(ckt->CKTgmin,ckt->CKTgshunt);
|
||||
success = failed = 0;
|
||||
|
||||
while ( (!success) && (!failed) ) {
|
||||
fprintf(stderr, "\rTrying gmin = %12.4E ", ckt->CKTdiagGmin);
|
||||
ckt->CKTnoncon =1;
|
||||
iters = ckt->CKTstat->STATnumIter;
|
||||
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
|
||||
iters = (ckt->CKTstat->STATnumIter)-iters;
|
||||
if(converged == 0) {
|
||||
ckt->CKTmode=continuemode;
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"One successful Gmin step",(IFuid *)NULL);
|
||||
if (ckt->CKTdiagGmin <= gtarget) {
|
||||
success = 1;
|
||||
} else {
|
||||
i=0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
OldRhsOld[i]=*(ckt->CKTrhsOld+n->number);
|
||||
i++;
|
||||
};
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(OldCKTstate0+i) = *(ckt->CKTstate0+i);
|
||||
};
|
||||
if (iters <= (ckt->CKTdcTrcvMaxIter/4)) {
|
||||
factor *= sqrt(factor);
|
||||
if (factor > ckt->CKTgminFactor)
|
||||
factor = ckt->CKTgminFactor;
|
||||
};
|
||||
if (iters > (3*ckt->CKTdcTrcvMaxIter/4)) {
|
||||
factor = sqrt(factor);
|
||||
};
|
||||
OldGmin = ckt->CKTdiagGmin;
|
||||
if ((ckt->CKTdiagGmin) < (factor*gtarget)) {
|
||||
factor = ckt->CKTdiagGmin / gtarget;
|
||||
ckt->CKTdiagGmin = gtarget;
|
||||
} else {
|
||||
ckt->CKTdiagGmin /= factor;
|
||||
};
|
||||
};
|
||||
} else {
|
||||
if (factor < 1.00005) {
|
||||
failed = 1;
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"last gmin step failed",(IFuid *)NULL);
|
||||
} else {
|
||||
factor=sqrt(sqrt(factor));
|
||||
ckt->CKTdiagGmin = OldGmin / factor;
|
||||
i=0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
*(ckt->CKTrhsOld+n->number)=OldRhsOld[i];
|
||||
i++;
|
||||
};
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(ckt->CKTstate0+i) = *(OldCKTstate0+i);
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
ckt->CKTdiagGmin=ckt->CKTgshunt;
|
||||
FREE(OldRhsOld);
|
||||
FREE(OldCKTstate0);
|
||||
converged = NIiter(ckt,iterlim);
|
||||
if (converged!=0) {
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"dynamic gmin stepping failed",(IFuid *)NULL);
|
||||
} else {
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"Dynamic gmin stepping completed",(IFuid *)NULL);
|
||||
return(0);
|
||||
};
|
||||
|
||||
} else if(ckt->CKTnumGminSteps >1) {
|
||||
|
||||
ckt->CKTmode = firstmode;
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"starting Gmin stepping",(IFuid *)NULL);
|
||||
|
||||
if (ckt->CKTgshunt==0) {
|
||||
ckt->CKTdiagGmin = ckt->CKTgmin;
|
||||
} else {
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
};
|
||||
|
||||
|
||||
for(i=0;i<ckt->CKTnumGminSteps;i++) {
|
||||
ckt->CKTdiagGmin *= ckt->CKTgminFactor;
|
||||
|
||||
|
||||
}
|
||||
for(i=0;i<=ckt->CKTnumGminSteps;i++) {
|
||||
fprintf(stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
|
||||
ckt->CKTnoncon =1;
|
||||
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
|
||||
if(converged != 0) {
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"Gmin step failed",(IFuid *)NULL);
|
||||
break;
|
||||
}
|
||||
ckt->CKTdiagGmin /= ckt->CKTgminFactor;
|
||||
ckt->CKTmode=continuemode;
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"One successful Gmin step",(IFuid *)NULL);
|
||||
}
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
converged = NIiter(ckt,iterlim);
|
||||
if(converged == 0) {
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"Gmin stepping completed",(IFuid *)NULL);
|
||||
return(0);
|
||||
}
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"Gmin stepping failed",(IFuid *)NULL);
|
||||
|
||||
}
|
||||
/* now, we'll try source stepping - we scale the sources
|
||||
* to 0, converge, then start stepping them up until they
|
||||
* are at their normal values
|
||||
*
|
||||
* note that no path out of this code allows ckt->CKTsrcFact to be
|
||||
* anything but 1.000000000
|
||||
*/
|
||||
|
||||
|
||||
if(ckt->CKTnumSrcSteps >=1) {
|
||||
ckt->CKTmode = firstmode;
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"starting source stepping",(IFuid *)NULL);
|
||||
if(ckt->CKTnumSrcSteps==1) {
|
||||
ckt->CKTsrcFact=0; raise=0.001; ConvFact=0;
|
||||
NumNodes=0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
NumNodes++;
|
||||
};
|
||||
OldRhsOld=(double *)MALLOC((NumNodes+1)*sizeof(double));
|
||||
OldCKTstate0=(double *)
|
||||
MALLOC((ckt->CKTnumStates+1)*sizeof(double));
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
*(ckt->CKTrhsOld+n->number)=0;
|
||||
};
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(ckt->CKTstate0+i) = 0;
|
||||
};
|
||||
|
||||
/* First, try a straight solution with all sources at zero */
|
||||
|
||||
fprintf(stderr, "\rSupplies reduced to %8.4f%% ",
|
||||
ckt->CKTsrcFact*100);
|
||||
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
|
||||
|
||||
/* If this doesn't work, try gmin stepping as well for the first solution */
|
||||
|
||||
if(converged != 0) {
|
||||
fprintf(stderr, "\n");
|
||||
if (ckt->CKTgshunt<=0) {
|
||||
ckt->CKTdiagGmin = ckt->CKTgmin;
|
||||
} else {
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
};
|
||||
for(i=0;i<10;i++) {
|
||||
ckt->CKTdiagGmin *= 10;
|
||||
}
|
||||
for(i=0;i<=10;i++) {
|
||||
fprintf(stderr, "Trying gmin = %12.4E ",
|
||||
ckt->CKTdiagGmin);
|
||||
ckt->CKTnoncon =1;
|
||||
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
|
||||
if(converged != 0) {
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"Gmin step failed",(IFuid *)NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
ckt->CKTdiagGmin /= 10;
|
||||
ckt->CKTmode=continuemode;
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"One successful Gmin step",(IFuid *)NULL);
|
||||
}
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
};
|
||||
|
||||
/* If we've got convergence, then try stepping up the sources */
|
||||
|
||||
if(converged == 0) {
|
||||
i=0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
OldRhsOld[i]=*(ckt->CKTrhsOld+n->number);
|
||||
i++;
|
||||
};
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(OldCKTstate0+i) = *(ckt->CKTstate0+i);
|
||||
};
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"One successful source step",(IFuid *)NULL);
|
||||
ckt->CKTsrcFact=ConvFact+raise;
|
||||
};
|
||||
|
||||
if(converged == 0) do {
|
||||
fprintf(stderr, "\rSupplies reduced to %8.4f%% ",
|
||||
ckt->CKTsrcFact*100);
|
||||
|
||||
iters = ckt->CKTstat->STATnumIter;
|
||||
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
|
||||
iters = (ckt->CKTstat->STATnumIter)-iters;
|
||||
|
||||
ckt->CKTmode = continuemode;
|
||||
if (converged == 0) {
|
||||
ConvFact=ckt->CKTsrcFact;
|
||||
i=0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
OldRhsOld[i]=*(ckt->CKTrhsOld+n->number);
|
||||
i++;
|
||||
};
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(OldCKTstate0+i) = *(ckt->CKTstate0+i);
|
||||
};
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"One successful source step",(IFuid *)NULL);
|
||||
ckt->CKTsrcFact=ConvFact+raise;
|
||||
if (iters <= (ckt->CKTdcTrcvMaxIter/4)) {
|
||||
raise=raise*1.5;
|
||||
};
|
||||
if (iters > (3*ckt->CKTdcTrcvMaxIter/4)) {
|
||||
raise=raise*0.5;
|
||||
};
|
||||
/* if (raise>0.01) raise=0.01; */
|
||||
} else {
|
||||
if ((ckt->CKTsrcFact-ConvFact)<1e-8) break;
|
||||
raise=raise/10;
|
||||
if (raise>0.01) raise=0.01;
|
||||
ckt->CKTsrcFact=ConvFact;
|
||||
i=0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
*(ckt->CKTrhsOld+n->number)=OldRhsOld[i];
|
||||
i++;
|
||||
};
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(ckt->CKTstate0+i) = *(OldCKTstate0+i);
|
||||
};
|
||||
};
|
||||
if ((ckt->CKTsrcFact)>1) ckt->CKTsrcFact=1;
|
||||
} while ((raise>=1e-7) && (ConvFact<1));
|
||||
|
||||
FREE(OldRhsOld);
|
||||
FREE(OldCKTstate0);
|
||||
ckt->CKTsrcFact = 1;
|
||||
if (ConvFact!=1) {
|
||||
ckt->CKTsrcFact = 1;
|
||||
ckt->CKTcurrentAnalysis = DOING_TRAN;
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"source stepping failed",(IFuid *)NULL);
|
||||
return(E_ITERLIM);
|
||||
} else {
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"Source stepping completed",(IFuid *)NULL);
|
||||
return(0);
|
||||
};
|
||||
} else {
|
||||
for(i=0;i<=ckt->CKTnumSrcSteps;i++) {
|
||||
ckt->CKTsrcFact = ((double)i)/((double)ckt->CKTnumSrcSteps);
|
||||
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
|
||||
ckt->CKTmode = continuemode;
|
||||
if(converged != 0) {
|
||||
ckt->CKTsrcFact = 1;
|
||||
ckt->CKTcurrentAnalysis = DOING_TRAN;
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"source stepping failed",(IFuid *)NULL);
|
||||
return(converged);
|
||||
}
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"One successful source step",(IFuid *)NULL);
|
||||
}
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"Source stepping completed",(IFuid *)NULL);
|
||||
ckt->CKTsrcFact = 1;
|
||||
return(0);
|
||||
};
|
||||
} else {
|
||||
return(converged);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CKTconvTest(ckt)
|
||||
* this is a driver program to iterate through all the various
|
||||
* convTest functions provided for the circuit elements in the
|
||||
|
|
@ -351,43 +87,550 @@ CKTop(CKTcircuit *ckt, long int firstmode, long int continuemode, int iterlim)
|
|||
*/
|
||||
|
||||
int
|
||||
CKTconvTest(CKTcircuit *ckt)
|
||||
CKTconvTest (CKTcircuit * ckt)
|
||||
{
|
||||
extern SPICEdev **DEVices;
|
||||
int i;
|
||||
int error = OK;
|
||||
extern SPICEdev **DEVices;
|
||||
int i;
|
||||
int error = OK;
|
||||
#ifdef PARALLEL_ARCH
|
||||
int ibuf[2];
|
||||
long type = MT_CONV, length = 2;
|
||||
int ibuf[2];
|
||||
long type = MT_CONV, length = 2;
|
||||
#endif /* PARALLEL_ARCH */
|
||||
|
||||
for (i=0;i<DEVmaxnum;i++) {
|
||||
if (((*DEVices[i]).DEVconvTest != NULL) && (ckt->CKThead[i] != NULL)) {
|
||||
error = (*((*DEVices[i]).DEVconvTest))(ckt->CKThead[i],ckt);
|
||||
}
|
||||
for (i = 0; i < DEVmaxnum; i++)
|
||||
{
|
||||
if (((*DEVices[i]).DEVconvTest != NULL) && (ckt->CKThead[i] != NULL))
|
||||
{
|
||||
error = (*((*DEVices[i]).DEVconvTest)) (ckt->CKThead[i], ckt);
|
||||
}
|
||||
#ifdef PARALLEL_ARCH
|
||||
if (error || ckt->CKTnoncon) goto combine;
|
||||
if (error || ckt->CKTnoncon)
|
||||
goto combine;
|
||||
#else
|
||||
if (error) return(error);
|
||||
if (ckt->CKTnoncon) {
|
||||
/* printf("convTest: device %s failed\n",
|
||||
(*DEVices[i]).DEVpublic.name); */
|
||||
return(OK);
|
||||
}
|
||||
if (error)
|
||||
return (error);
|
||||
if (ckt->CKTnoncon)
|
||||
{
|
||||
/* printf("convTest: device %s failed\n",
|
||||
* (*DEVices[i]).DEVpublic.name); */
|
||||
return (OK);
|
||||
}
|
||||
#endif /* PARALLEL_ARCH */
|
||||
}
|
||||
#ifdef PARALLEL_ARCH
|
||||
combine:
|
||||
/* See if any of the DEVconvTest functions bailed. If not, proceed. */
|
||||
ibuf[0] = error;
|
||||
ibuf[1] = ckt->CKTnoncon;
|
||||
IGOP_( &type, ibuf, &length, "+" );
|
||||
ckt->CKTnoncon = ibuf[1];
|
||||
if ( ibuf[0] != error ) {
|
||||
error = E_MULTIERR;
|
||||
/* See if any of the DEVconvTest functions bailed. If not, proceed. */
|
||||
ibuf[0] = error;
|
||||
ibuf[1] = ckt->CKTnoncon;
|
||||
IGOP_ (&type, ibuf, &length, "+");
|
||||
ckt->CKTnoncon = ibuf[1];
|
||||
if (ibuf[0] != error)
|
||||
{
|
||||
error = E_MULTIERR;
|
||||
}
|
||||
return (error);
|
||||
return (error);
|
||||
#else
|
||||
return(OK);
|
||||
return (OK);
|
||||
#endif /* PARALLEL_ARCH */
|
||||
}
|
||||
|
||||
|
||||
/* Dynamic gmin stepping
|
||||
* Algorithm by Alan Gillespie
|
||||
* Modified 2005 - Paolo Nenzi (extracted from CKTop.c code)
|
||||
*
|
||||
* return value:
|
||||
* 0 -> method converged
|
||||
* 1 -> method failed
|
||||
*
|
||||
* Note that no path out of this code allows ckt->CKTdiagGmin to be
|
||||
* anything but CKTgshunt.
|
||||
*/
|
||||
|
||||
static int
|
||||
dynamic_gmin (CKTcircuit * ckt, long int firstmode,
|
||||
long int continuemode, int iterlim)
|
||||
{
|
||||
double OldGmin, gtarget, factor;
|
||||
int success, failed, converged;
|
||||
|
||||
int NumNodes, iters, i;
|
||||
double *OldRhsOld, *OldCKTstate0;
|
||||
CKTnode *n;
|
||||
|
||||
ckt->CKTmode = firstmode;
|
||||
(*(SPfrontEnd->IFerror)) (ERR_INFO,
|
||||
"starting dynamic Gmin stepping", (IFuid *) NULL);
|
||||
|
||||
NumNodes = 0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next)
|
||||
NumNodes++;
|
||||
|
||||
OldRhsOld = (double *) MALLOC ((NumNodes + 1) * sizeof (double));
|
||||
OldCKTstate0 =
|
||||
(double *) MALLOC ((ckt->CKTnumStates + 1) * sizeof (double));
|
||||
|
||||
for (n = ckt->CKTnodes; n; n = n->next)
|
||||
*(ckt->CKTrhsOld + n->number) = 0;
|
||||
|
||||
for (i = 0; i < ckt->CKTnumStates; i++)
|
||||
*(ckt->CKTstate0 + i) = 0;
|
||||
|
||||
factor = ckt->CKTgminFactor;
|
||||
OldGmin = 1e-2;
|
||||
ckt->CKTdiagGmin = OldGmin / factor;
|
||||
gtarget = MAX (ckt->CKTgmin, ckt->CKTgshunt);
|
||||
success = failed = 0;
|
||||
|
||||
while ((!success) && (!failed)){
|
||||
fprintf (stderr, "\rTrying gmin = %12.4E ", ckt->CKTdiagGmin);
|
||||
ckt->CKTnoncon = 1;
|
||||
iters = ckt->CKTstat->STATnumIter;
|
||||
|
||||
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
||||
iters = (ckt->CKTstat->STATnumIter) - iters;
|
||||
|
||||
if (converged == 0){
|
||||
ckt->CKTmode = continuemode;
|
||||
(*(SPfrontEnd->IFerror)) (ERR_INFO,
|
||||
"One successful Gmin step", (IFuid *) NULL);
|
||||
|
||||
if (ckt->CKTdiagGmin <= gtarget){
|
||||
success = 1;
|
||||
} else {
|
||||
i = 0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next){
|
||||
OldRhsOld[i] = *(ckt->CKTrhsOld + n->number);
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i = 0; i < ckt->CKTnumStates; i++){
|
||||
*(OldCKTstate0 + i) = *(ckt->CKTstate0 + i);
|
||||
}
|
||||
|
||||
if (iters <= (ckt->CKTdcTrcvMaxIter / 4)){
|
||||
factor *= sqrt (factor);
|
||||
if (factor > ckt->CKTgminFactor)
|
||||
factor = ckt->CKTgminFactor;
|
||||
}
|
||||
|
||||
if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4))
|
||||
factor = sqrt (factor);
|
||||
|
||||
OldGmin = ckt->CKTdiagGmin;
|
||||
|
||||
if ((ckt->CKTdiagGmin) < (factor * gtarget)){
|
||||
factor = ckt->CKTdiagGmin / gtarget;
|
||||
ckt->CKTdiagGmin = gtarget;
|
||||
} else {
|
||||
ckt->CKTdiagGmin /= factor;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
if (factor < 1.00005){
|
||||
failed = 1;
|
||||
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
|
||||
"Last gmin step failed",
|
||||
(IFuid *) NULL);
|
||||
} else {
|
||||
factor = sqrt (sqrt (factor));
|
||||
ckt->CKTdiagGmin = OldGmin / factor;
|
||||
i = 0;
|
||||
|
||||
for (n = ckt->CKTnodes; n; n = n->next){
|
||||
*(ckt->CKTrhsOld + n->number) = OldRhsOld[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i = 0; i < ckt->CKTnumStates; i++){
|
||||
*(ckt->CKTstate0 + i) = *(OldCKTstate0 + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
FREE (OldRhsOld);
|
||||
FREE (OldCKTstate0);
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||
if (ckt->CKTnumSrcSteps <= 0)
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
||||
else
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||
#endif
|
||||
|
||||
converged = NIiter (ckt, iterlim);
|
||||
|
||||
if (converged != 0){
|
||||
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
|
||||
"Dynamic Gmin stepping failed",
|
||||
(IFuid *) NULL);
|
||||
} else {
|
||||
(*(SPfrontEnd->IFerror)) (ERR_INFO,
|
||||
"Dynamic Gmin stepping completed",
|
||||
(IFuid *) NULL);
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||
#endif
|
||||
}
|
||||
|
||||
return (converged);
|
||||
}
|
||||
|
||||
|
||||
/* Spice3 gmin stepping
|
||||
* Modified 2000 - Alan Gillespie (added gshunt)
|
||||
* Modified 2005 - Paolo Nenzi (extracted from CKTop.c code)
|
||||
*
|
||||
* return value:
|
||||
* 0 -> method converged
|
||||
* 1 -> method failed
|
||||
*
|
||||
* Note that no path out of this code allows ckt->CKTdiagGmin to be
|
||||
* anything but CKTgshunt.
|
||||
*/
|
||||
|
||||
static int
|
||||
spice3_gmin (CKTcircuit * ckt, long int firstmode,
|
||||
long int continuemode, int iterlim)
|
||||
{
|
||||
|
||||
int converged, i;
|
||||
|
||||
ckt->CKTmode = firstmode;
|
||||
(*(SPfrontEnd->IFerror)) (ERR_INFO,
|
||||
"starting Gmin stepping", (IFuid *) NULL);
|
||||
|
||||
if (ckt->CKTgshunt == 0)
|
||||
ckt->CKTdiagGmin = ckt->CKTgmin;
|
||||
else
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
|
||||
for (i = 0; i < ckt->CKTnumGminSteps; i++)
|
||||
ckt->CKTdiagGmin *= ckt->CKTgminFactor;
|
||||
|
||||
|
||||
for (i = 0; i <= ckt->CKTnumGminSteps; i++){
|
||||
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
|
||||
ckt->CKTnoncon = 1;
|
||||
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
||||
|
||||
if (converged != 0){
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
|
||||
"Gmin step failed", (IFuid *) NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
ckt->CKTdiagGmin /= ckt->CKTgminFactor;
|
||||
ckt->CKTmode = continuemode;
|
||||
|
||||
(*(SPfrontEnd->IFerror)) (ERR_INFO,
|
||||
"One successful Gmin step", (IFuid *) NULL);
|
||||
}
|
||||
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||
if (ckt->CKTnumSrcSteps <= 0)
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
||||
else
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||
#endif
|
||||
|
||||
converged = NIiter (ckt, iterlim);
|
||||
|
||||
if (converged == 0){
|
||||
(*(SPfrontEnd->IFerror)) (ERR_INFO,
|
||||
"Gmin stepping completed", (IFuid *) NULL);
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||
#endif
|
||||
|
||||
} else {
|
||||
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
|
||||
"Gmin stepping failed", (IFuid *) NULL);
|
||||
}
|
||||
|
||||
return (converged);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Gillespie's Source stepping
|
||||
* Modified 2005 - Paolo Nenzi (extracted from CKTop.c code)
|
||||
*
|
||||
* return value:
|
||||
* 0 -> method converged
|
||||
* 1 -> method failed
|
||||
*
|
||||
* Note that no path out of this code allows ckt->CKTsrcFact to be
|
||||
* anything but 1.00000.
|
||||
*/
|
||||
static int
|
||||
gillespie_src (CKTcircuit * ckt, long int firstmode,
|
||||
long int continuemode, int iterlim)
|
||||
{
|
||||
|
||||
int converged, NumNodes, i, iters;
|
||||
double raise, ConvFact;
|
||||
double *OldRhsOld, *OldCKTstate0;
|
||||
CKTnode *n;
|
||||
|
||||
ckt->CKTmode = firstmode;
|
||||
(*(SPfrontEnd->IFerror)) (ERR_INFO,
|
||||
"starting source stepping", (IFuid *) NULL);
|
||||
|
||||
ckt->CKTsrcFact = 0;
|
||||
raise = 0.001;
|
||||
ConvFact = 0;
|
||||
|
||||
NumNodes = 0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next){
|
||||
NumNodes++;
|
||||
}
|
||||
|
||||
OldRhsOld = (double *) MALLOC ((NumNodes + 1) * sizeof (double));
|
||||
OldCKTstate0 =
|
||||
(double *) MALLOC ((ckt->CKTnumStates + 1) * sizeof (double));
|
||||
|
||||
for (n = ckt->CKTnodes; n; n = n->next)
|
||||
*(ckt->CKTrhsOld + n->number) = 0;
|
||||
|
||||
for (i = 0; i < ckt->CKTnumStates; i++)
|
||||
*(ckt->CKTstate0 + i) = 0;
|
||||
|
||||
/* First, try a straight solution with all sources at zero */
|
||||
|
||||
fprintf (stderr, "\rSupplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
|
||||
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
||||
|
||||
/* If this doesn't work, try gmin stepping as well for the first solution */
|
||||
|
||||
if (converged != 0){
|
||||
fprintf (stderr, "\n");
|
||||
if (ckt->CKTgshunt <= 0){
|
||||
ckt->CKTdiagGmin = ckt->CKTgmin;
|
||||
} else {
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
ckt->CKTdiagGmin *= 10;
|
||||
|
||||
for (i = 0; i <= 10; i++){
|
||||
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
|
||||
ckt->CKTnoncon = 1;
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||
#endif
|
||||
|
||||
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
||||
|
||||
if (converged != 0){
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
|
||||
"Gmin step failed", (IFuid *) NULL);
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
ckt->CKTdiagGmin /= 10;
|
||||
ckt->CKTmode = continuemode;
|
||||
(*(SPfrontEnd->IFerror)) (ERR_INFO,
|
||||
"One successful Gmin step",
|
||||
(IFuid *) NULL);
|
||||
}
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
}
|
||||
|
||||
/* If we've got convergence, then try stepping up the sources */
|
||||
|
||||
if (converged == 0){
|
||||
i = 0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next){
|
||||
OldRhsOld[i] = *(ckt->CKTrhsOld + n->number);
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i = 0; i < ckt->CKTnumStates; i++)
|
||||
*(OldCKTstate0 + i) = *(ckt->CKTstate0 + i);
|
||||
|
||||
|
||||
(*(SPfrontEnd->IFerror)) (ERR_INFO,
|
||||
"One successful source step", (IFuid *) NULL);
|
||||
ckt->CKTsrcFact = ConvFact + raise;
|
||||
}
|
||||
|
||||
|
||||
if (converged == 0)
|
||||
do {
|
||||
fprintf (stderr,
|
||||
"\rSupplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
|
||||
|
||||
iters = ckt->CKTstat->STATnumIter;
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||
#endif
|
||||
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
||||
|
||||
iters = (ckt->CKTstat->STATnumIter) - iters;
|
||||
|
||||
ckt->CKTmode = continuemode;
|
||||
|
||||
if (converged == 0){
|
||||
ConvFact = ckt->CKTsrcFact;
|
||||
i = 0;
|
||||
|
||||
for (n = ckt->CKTnodes; n; n = n->next){
|
||||
OldRhsOld[i] = *(ckt->CKTrhsOld + n->number);
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i = 0; i < ckt->CKTnumStates; i++)
|
||||
*(OldCKTstate0 + i) = *(ckt->CKTstate0 + i);
|
||||
|
||||
(*(SPfrontEnd->IFerror)) (ERR_INFO,
|
||||
"One successful source step",
|
||||
(IFuid *) NULL);
|
||||
|
||||
ckt->CKTsrcFact = ConvFact + raise;
|
||||
|
||||
if (iters <= (ckt->CKTdcTrcvMaxIter / 4)){
|
||||
raise = raise * 1.5;
|
||||
}
|
||||
|
||||
if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4)){
|
||||
raise = raise * 0.5;
|
||||
}
|
||||
|
||||
/* if (raise>0.01) raise=0.01; */
|
||||
|
||||
} else {
|
||||
|
||||
if ((ckt->CKTsrcFact - ConvFact) < 1e-8)
|
||||
break;
|
||||
|
||||
raise = raise / 10;
|
||||
|
||||
if (raise > 0.01)
|
||||
raise = 0.01;
|
||||
|
||||
ckt->CKTsrcFact = ConvFact;
|
||||
i = 0;
|
||||
|
||||
for (n = ckt->CKTnodes; n; n = n->next){
|
||||
*(ckt->CKTrhsOld + n->number) = OldRhsOld[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i = 0; i < ckt->CKTnumStates; i++)
|
||||
*(ckt->CKTstate0 + i) = *(OldCKTstate0 + i);
|
||||
|
||||
}
|
||||
|
||||
if ((ckt->CKTsrcFact) > 1)
|
||||
ckt->CKTsrcFact = 1;
|
||||
|
||||
}
|
||||
while ((raise >= 1e-7) && (ConvFact < 1));
|
||||
|
||||
FREE (OldRhsOld);
|
||||
FREE (OldCKTstate0);
|
||||
ckt->CKTsrcFact = 1;
|
||||
|
||||
if (ConvFact != 1)
|
||||
{
|
||||
ckt->CKTsrcFact = 1;
|
||||
ckt->CKTcurrentAnalysis = DOING_TRAN;
|
||||
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
|
||||
"source stepping failed", (IFuid *) NULL);
|
||||
return (E_ITERLIM);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*(SPfrontEnd->IFerror)) (ERR_INFO,
|
||||
"Source stepping completed", (IFuid *) NULL);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Spice3 Source stepping
|
||||
* Modified 2005 - Paolo Nenzi (extracted from CKTop.c code)
|
||||
*
|
||||
* return value:
|
||||
* 0 -> method converged
|
||||
* 1 -> method failed
|
||||
*
|
||||
* Note that no path out of this code allows ckt->CKTsrcFact to be
|
||||
* anything but 1.00000.
|
||||
*/
|
||||
static int
|
||||
spice3_src (CKTcircuit * ckt, long int firstmode,
|
||||
long int continuemode, int iterlim)
|
||||
{
|
||||
|
||||
int converged, i;
|
||||
|
||||
ckt->CKTmode = firstmode;
|
||||
(*(SPfrontEnd->IFerror)) (ERR_INFO,
|
||||
"starting source stepping", (IFuid *) NULL);
|
||||
|
||||
for (i = 0; i <= ckt->CKTnumSrcSteps; i++)
|
||||
{
|
||||
ckt->CKTsrcFact = ((double) i) / ((double) ckt->CKTnumSrcSteps);
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
|
||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||
#endif
|
||||
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
|
||||
ckt->CKTmode = continuemode;
|
||||
if (converged != 0)
|
||||
{
|
||||
ckt->CKTsrcFact = 1;
|
||||
ckt->CKTcurrentAnalysis = DOING_TRAN;
|
||||
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
|
||||
"source stepping failed", (IFuid *) NULL);
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||
#endif
|
||||
return (converged);
|
||||
}
|
||||
(*(SPfrontEnd->IFerror)) (ERR_INFO,
|
||||
"One successful source step", (IFuid *) NULL);
|
||||
}
|
||||
(*(SPfrontEnd->IFerror)) (ERR_INFO,
|
||||
"Source stepping completed", (IFuid *) NULL);
|
||||
ckt->CKTsrcFact = 1;
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - add convergence problem reporting flags */
|
||||
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
|
||||
/* gtri - end - wbk - add convergence problem reporting flags */
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,14 @@ Modified: 2000 AlansFixes
|
|||
#include "sperror.h"
|
||||
#include "ifsim.h"
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 12/19/90 - Add headers */
|
||||
#include "mif.h"
|
||||
#include "evt.h"
|
||||
#include "evtproto.h"
|
||||
#include "ipctiein.h"
|
||||
/* gtri - end - wbk */
|
||||
#endif
|
||||
|
||||
int
|
||||
DCop(CKTcircuit *ckt, int notused)
|
||||
|
|
@ -19,7 +27,21 @@ DCop(CKTcircuit *ckt, int notused)
|
|||
IFuid *nameList; /* va: tmalloc'ed list */
|
||||
int numNames;
|
||||
void *plot = NULL;
|
||||
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 12/19/90 - Add IPC stuff and initialize anal_init and anal_type */
|
||||
|
||||
/* Tell the beginPlot routine what mode we're in */
|
||||
g_ipc.anal_type = IPC_ANAL_DCOP;
|
||||
|
||||
/* 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);
|
||||
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
|
||||
|
|
@ -28,10 +50,28 @@ DCop(CKTcircuit *ckt, int notused)
|
|||
tfree(nameList); /* va: nameList not used any longer, it was a memory leak */
|
||||
if(error) return(error);
|
||||
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - 6/10/91 - Call EVTop if event-driven instances exist */
|
||||
if(ckt->evt->counts.num_insts != 0) {
|
||||
/* use new DCOP algorithm */
|
||||
converged = EVTop(ckt,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
|
||||
ckt->CKTdcMaxIter,
|
||||
MIF_TRUE);
|
||||
EVTdump(ckt, IPC_ANAL_DCOP, 0.0);
|
||||
|
||||
EVTop_save(ckt, MIF_TRUE, 0.0);
|
||||
/* gtri - end - wbk - 6/10/91 - Call EVTop if event-driven instances exist */
|
||||
} else
|
||||
/* If no event-driven instances, do what SPICE normally does */
|
||||
#endif
|
||||
converged = CKTop(ckt,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
|
||||
ckt->CKTdcMaxIter);
|
||||
|
||||
if(converged != 0) {
|
||||
fprintf(stdout,"\nDC solution failed -\n");
|
||||
CKTncDump(ckt);
|
||||
|
|
@ -63,14 +103,15 @@ DCop(CKTcircuit *ckt, int notused)
|
|||
fprintf(stdout," *");
|
||||
}
|
||||
fprintf(stdout,"\n");
|
||||
};
|
||||
}
|
||||
i++;
|
||||
};
|
||||
}
|
||||
fprintf(stdout,"\n");
|
||||
(*(SPfrontEnd->OUTendPlot))(plot); */
|
||||
|
||||
return(converged);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
|
||||
|
||||
|
|
@ -96,11 +137,25 @@ DCop(CKTcircuit *ckt, int notused)
|
|||
}
|
||||
#endif
|
||||
converged = CKTload(ckt);
|
||||
#ifdef XSPICE
|
||||
/* gtri - modify - wbk - 12/19/90 - Send IPC data delimiters */
|
||||
|
||||
if(g_ipc.enabled)
|
||||
ipc_send_dcop_prefix();
|
||||
|
||||
CKTdump(ckt,(double)0,plot);
|
||||
|
||||
if(g_ipc.enabled)
|
||||
ipc_send_dcop_suffix();
|
||||
|
||||
/* gtri - end - wbk */
|
||||
#else
|
||||
if(converged == 0) {
|
||||
CKTdump(ckt,(double)0,plot);
|
||||
} else {
|
||||
fprintf(stderr,"error: circuit reload failed.\n");
|
||||
};
|
||||
}
|
||||
#endif
|
||||
(*(SPfrontEnd->OUTendPlot))(plot);
|
||||
return(converged);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,17 @@ DCtran(CKTcircuit *ckt,
|
|||
*(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 */
|
||||
|
||||
|
|
@ -507,6 +517,15 @@ resume:
|
|||
#endif
|
||||
ckt->CKTdelta =
|
||||
MIN(ckt->CKTdelta,ckt->CKTmaxStep);
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - Cut integration order if first timepoint after breakpoint */
|
||||
if(ckt->CKTtime == g_mif_info.breakpoint.last)
|
||||
ckt->CKTorder = 1;
|
||||
/* gtri - end - wbk - Cut integration order if first timepoint after breakpoint */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* are we at a breakpoint, or indistinguishably close? */
|
||||
if ((ckt->CKTtime == *(ckt->CKTbreaks)) || (*(ckt->CKTbreaks) -
|
||||
(ckt->CKTtime) <= ckt->CKTdelmin)) {
|
||||
|
|
@ -536,6 +555,43 @@ resume:
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef XSPICE
|
||||
}
|
||||
|
||||
/* gtri - begin - wbk - Add Breakpoint stuff */
|
||||
|
||||
if(ckt->CKTtime + ckt->CKTdelta >= g_mif_info.breakpoint.current) {
|
||||
/* If next time > temporary breakpoint, force it to the breakpoint */
|
||||
/* And mark that timestep was set by temporary breakpoint */
|
||||
ckt->CKTsaveDelta = ckt->CKTdelta;
|
||||
ckt->CKTdelta = g_mif_info.breakpoint.current - ckt->CKTtime;
|
||||
g_mif_info.breakpoint.last = ckt->CKTtime + ckt->CKTdelta;
|
||||
}
|
||||
else {
|
||||
/* Else, mark that timestep was not set by temporary breakpoint */
|
||||
g_mif_info.breakpoint.last = 1.0e30;
|
||||
}
|
||||
|
||||
/* gtri - end - wbk - Add Breakpoint stuff */
|
||||
|
||||
/* gtri - begin - wbk - Modify Breakpoint stuff */
|
||||
/* Throw out any permanent breakpoint times <= current time */
|
||||
while(1) {
|
||||
if(*(ckt->CKTbreaks) <= (ckt->CKTtime + ckt->CKTminBreak))
|
||||
CKTclrBreak(ckt);
|
||||
else
|
||||
break;
|
||||
}
|
||||
/* Force the breakpoint if appropriate */
|
||||
if((ckt->CKTtime + ckt->CKTdelta) > *(ckt->CKTbreaks)) {
|
||||
ckt->CKTbreak = 1;
|
||||
ckt->CKTsaveDelta = ckt->CKTdelta;
|
||||
ckt->CKTdelta = *(ckt->CKTbreaks) - ckt->CKTtime;
|
||||
}
|
||||
|
||||
/* gtri - end - wbk - Modify Breakpoint stuff */
|
||||
#else /* !XSPICE */
|
||||
|
||||
/* don't want to get below delmin for no reason */
|
||||
ckt->CKTdelta = MAX(ckt->CKTdelta, ckt->CKTdelmin*2.0);
|
||||
}
|
||||
|
|
@ -557,6 +613,9 @@ resume:
|
|||
#ifdef PARALLEL_ARCH
|
||||
DGOP_( &type, &(ckt->CKTdelta), &length, "min" );
|
||||
#endif /* PARALLEL_ARCH */
|
||||
|
||||
#endif /* XSPICE */
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - Do event solution */
|
||||
|
||||
|
|
@ -707,6 +766,24 @@ resume:
|
|||
ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN;
|
||||
}
|
||||
ckt->CKTorder = 1;
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - Add Breakpoint stuff */
|
||||
|
||||
/* Force backup if temporary breakpoint is < current time */
|
||||
} else if(g_mif_info.breakpoint.current < ckt->CKTtime) {
|
||||
ckt->CKTsaveDelta = ckt->CKTdelta;
|
||||
ckt->CKTtime -= ckt->CKTdelta;
|
||||
ckt->CKTdelta = g_mif_info.breakpoint.current - ckt->CKTtime;
|
||||
g_mif_info.breakpoint.last = ckt->CKTtime + ckt->CKTdelta;
|
||||
if(firsttime) {
|
||||
ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN;
|
||||
}
|
||||
ckt->CKTorder = 1;
|
||||
|
||||
/* gtri - end - wbk - Add Breakpoint stuff */
|
||||
#endif
|
||||
|
||||
} else {
|
||||
if (firsttime) {
|
||||
#ifdef WANT_SENSE2
|
||||
|
|
|
|||
|
|
@ -14,6 +14,14 @@ Modified: 1999 Paolo Nenzi
|
|||
#include "const.h"
|
||||
#include "sperror.h"
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 12/19/90 - Add headers */
|
||||
#include "mif.h"
|
||||
#include "evtproto.h"
|
||||
#include "ipctiein.h"
|
||||
/* gtri - end - wbk */
|
||||
#endif
|
||||
|
||||
#include <devdefs.h>
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
|
|
@ -151,7 +159,21 @@ DCtrCurv(CKTcircuit *ckt, int restart)
|
|||
|
||||
found:;
|
||||
}
|
||||
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */
|
||||
|
||||
/* Tell the beginPlot routine what mode we're in */
|
||||
g_ipc.anal_type = IPC_ANAL_DCTRCURVE;
|
||||
|
||||
/* 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
|
||||
|
||||
i--; /* PN: This seems to do nothing ??? */
|
||||
|
||||
error = CKTnames(ckt,&numNames,&nameList);
|
||||
|
|
@ -292,6 +314,11 @@ resume:
|
|||
ckt->CKTstate0 = temp;
|
||||
|
||||
/* do operation */
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - wbk - Do EVTop if event instances exist */
|
||||
if(ckt->evt->counts.num_insts == 0) {
|
||||
/* If no event-driven instances, do what SPICE normally does */
|
||||
#endif
|
||||
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
|
||||
if(converged != 0) {
|
||||
converged = CKTop(ckt,
|
||||
|
|
@ -302,6 +329,59 @@ resume:
|
|||
return(converged);
|
||||
}
|
||||
}
|
||||
#ifdef XSPICE
|
||||
}
|
||||
else {
|
||||
/* else do new algorithm */
|
||||
|
||||
/* first get the current step in the analysis */
|
||||
if(cv->TRCVvType[0] == vcode) {
|
||||
g_mif_info.circuit.evt_step = ((VSRCinstance *)(cv->TRCVvElt[i]))
|
||||
->VSRCdcValue ;
|
||||
} else if(cv->TRCVvType[0] == icode) {
|
||||
g_mif_info.circuit.evt_step = ((ISRCinstance *)(cv->TRCVvElt[i]))
|
||||
->ISRCdcValue ;
|
||||
} else if(cv->TRCVvType[0] == rcode) {
|
||||
g_mif_info.circuit.evt_step = ((RESinstance*)(cv->TRCVvElt[i]->GENmodPtr))
|
||||
->RESresist;
|
||||
} else if(cv->TRCVvType[0] == TEMP_CODE) {
|
||||
g_mif_info.circuit.evt_step = ckt->CKTtemp - CONSTCtoK;
|
||||
}
|
||||
|
||||
/* if first time through, call EVTop immediately and save event results */
|
||||
if(firstTime) {
|
||||
converged = EVTop(ckt,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCTRANCURVE | MODEINITJCT,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCTRANCURVE | MODEINITFLOAT,
|
||||
ckt->CKTdcMaxIter,
|
||||
MIF_TRUE);
|
||||
EVTdump(ckt, IPC_ANAL_DCOP, g_mif_info.circuit.evt_step);
|
||||
EVTop_save(ckt, MIF_FALSE, g_mif_info.circuit.evt_step);
|
||||
if(converged != 0)
|
||||
return(converged);
|
||||
}
|
||||
/* else, call NIiter first with mode = MODEINITPRED */
|
||||
/* to attempt quick analog solution. Then call all hybrids and call */
|
||||
/* EVTop only if event outputs have changed, or if non-converged */
|
||||
else {
|
||||
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
|
||||
EVTcall_hybrids(ckt);
|
||||
if((converged != 0) || (ckt->evt->queue.output.num_changed != 0)) {
|
||||
converged = EVTop(ckt,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCTRANCURVE | MODEINITJCT,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCTRANCURVE | MODEINITFLOAT,
|
||||
ckt->CKTdcMaxIter,
|
||||
MIF_FALSE);
|
||||
EVTdump(ckt, IPC_ANAL_DCTRCURVE, g_mif_info.circuit.evt_step);
|
||||
EVTop_save(ckt, MIF_FALSE, g_mif_info.circuit.evt_step);
|
||||
if(converged != 0)
|
||||
return(converged);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* gtri - end - wbk - Do EVTop if event instances exist */
|
||||
#endif
|
||||
|
||||
ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODEDCTRANCURVE | MODEINITPRED ;
|
||||
if(cv->TRCVvType[0] == vcode) {
|
||||
ckt->CKTtime = ((VSRCinstance *)(cv->TRCVvElt[i]))
|
||||
|
|
@ -318,6 +398,22 @@ resume:
|
|||
{
|
||||
ckt->CKTtime = ckt->CKTtemp - CONSTCtoK ;
|
||||
}
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 12/19/90 - Add IPC stuff */
|
||||
|
||||
/* If first time through, call CKTdump to output Operating Point info */
|
||||
/* for Mspice compatibility */
|
||||
|
||||
if(g_ipc.enabled && firstTime) {
|
||||
ipc_send_dcop_prefix();
|
||||
CKTdump(ckt,(double) 0,plot);
|
||||
ipc_send_dcop_suffix();
|
||||
}
|
||||
|
||||
/* gtri - end - wbk */
|
||||
#endif
|
||||
|
||||
#ifdef WANT_SENSE2
|
||||
/*
|
||||
if(!ckt->CKTsenInfo) printf("sensitivity structure does not exist\n");
|
||||
|
|
@ -355,8 +451,22 @@ resume:
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - modify - wbk - 12/19/90 - Send IPC delimiters */
|
||||
|
||||
if(g_ipc.enabled)
|
||||
ipc_send_data_prefix(ckt->CKTtime);
|
||||
#endif
|
||||
|
||||
CKTdump(ckt,ckt->CKTtime,plot);
|
||||
|
||||
#ifdef XSPICE
|
||||
if(g_ipc.enabled)
|
||||
ipc_send_data_suffix();
|
||||
|
||||
/* gtri - end - wbk */
|
||||
#endif
|
||||
|
||||
if(firstTime) {
|
||||
firstTime=0;
|
||||
bcopy((char *)ckt->CKTstate0,(char *)ckt->CKTstate1,
|
||||
|
|
|
|||
Loading…
Reference in New Issue