|
|
|
@ -6,11 +6,11 @@ Modified: 2000 AlansFixes |
|
|
|
/* |
|
|
|
*/ |
|
|
|
|
|
|
|
/* CKTload(ckt) |
|
|
|
* this is a driver program to iterate through all the various |
|
|
|
* load functions provided for the circuit elements in the |
|
|
|
* given circuit |
|
|
|
*/ |
|
|
|
/* CKTload(ckt) |
|
|
|
* this is a driver program to iterate through all the various |
|
|
|
* load functions provided for the circuit elements in the |
|
|
|
* given circuit |
|
|
|
*/ |
|
|
|
|
|
|
|
#include "ngspice/ngspice.h" |
|
|
|
#include "ngspice/smpdefs.h" |
|
|
|
@ -43,7 +43,7 @@ CKTload(CKTcircuit *ckt) |
|
|
|
#endif /* STEPDEBUG */ |
|
|
|
|
|
|
|
#ifdef XSPICE |
|
|
|
/* gtri - begin - Put resistors to ground at all nodes */ |
|
|
|
/* gtri - begin - Put resistors to ground at all nodes */ |
|
|
|
/* SMPmatrix *matrix; maschmann : deleted , because unused */ |
|
|
|
|
|
|
|
double gshunt; |
|
|
|
@ -54,37 +54,37 @@ CKTload(CKTcircuit *ckt) |
|
|
|
|
|
|
|
startTime = SPfrontEnd->IFseconds(); |
|
|
|
size = SMPmatSize(ckt->CKTmatrix); |
|
|
|
for (i=0;i<=size;i++) { |
|
|
|
*(ckt->CKTrhs+i)=0; |
|
|
|
for (i = 0; i <= size; i++) { |
|
|
|
*(ckt->CKTrhs+i) = 0; |
|
|
|
} |
|
|
|
SMPclear(ckt->CKTmatrix); |
|
|
|
#ifdef STEPDEBUG |
|
|
|
noncon = ckt->CKTnoncon; |
|
|
|
#endif /* STEPDEBUG */ |
|
|
|
|
|
|
|
for (i=0;i<DEVmaxnum;i++) { |
|
|
|
if ( DEVices[i] && DEVices[i]->DEVload && ckt->CKThead[i] ) { |
|
|
|
for (i = 0; i < DEVmaxnum; i++) { |
|
|
|
if (DEVices[i] && DEVices[i]->DEVload && ckt->CKThead[i]) { |
|
|
|
error = DEVices[i]->DEVload (ckt->CKThead[i], ckt); |
|
|
|
if (ckt->CKTnoncon) |
|
|
|
ckt->CKTtroubleNode = 0; |
|
|
|
if (ckt->CKTnoncon) |
|
|
|
ckt->CKTtroubleNode = 0; |
|
|
|
#ifdef STEPDEBUG |
|
|
|
if(noncon != ckt->CKTnoncon) { |
|
|
|
if (noncon != ckt->CKTnoncon) { |
|
|
|
printf("device type %s nonconvergence\n", |
|
|
|
DEVices[i]->DEVpublic.name); |
|
|
|
DEVices[i]->DEVpublic.name); |
|
|
|
noncon = ckt->CKTnoncon; |
|
|
|
} |
|
|
|
#endif /* STEPDEBUG */ |
|
|
|
#ifdef PARALLEL_ARCH |
|
|
|
if (error) goto combine; |
|
|
|
if (error) goto combine; |
|
|
|
#else |
|
|
|
if(error) return(error); |
|
|
|
if (error) return(error); |
|
|
|
#endif /* PARALLEL_ARCH */ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef XSPICE |
|
|
|
/* gtri - add - wbk - 11/26/90 - reset the MIF init flags */ |
|
|
|
/* 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; |
|
|
|
@ -98,97 +98,95 @@ CKTload(CKTcircuit *ckt) |
|
|
|
/* gtri - begin - Put resistors to ground at all nodes. */ |
|
|
|
/* Value of resistor is set by new "rshunt" option. */ |
|
|
|
|
|
|
|
if(ckt->enh->rshunt_data.enabled) { |
|
|
|
gshunt = ckt->enh->rshunt_data.gshunt; |
|
|
|
num_nodes = ckt->enh->rshunt_data.num_nodes; |
|
|
|
for(i = 0; i < num_nodes; i++) { |
|
|
|
*(ckt->enh->rshunt_data.diag[i]) += gshunt; |
|
|
|
} |
|
|
|
if (ckt->enh->rshunt_data.enabled) { |
|
|
|
gshunt = ckt->enh->rshunt_data.gshunt; |
|
|
|
num_nodes = ckt->enh->rshunt_data.num_nodes; |
|
|
|
for (i = 0; i < num_nodes; i++) { |
|
|
|
*(ckt->enh->rshunt_data.diag[i]) += gshunt; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* gtri - end - Put resistors to ground at all nodes */ |
|
|
|
/* gtri - end - Put resistors to ground at all nodes */ |
|
|
|
#endif |
|
|
|
|
|
|
|
if(ckt->CKTmode & MODEDC) { |
|
|
|
if (ckt->CKTmode & MODEDC) { |
|
|
|
/* consider doing nodeset & ic assignments */ |
|
|
|
if(ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) { |
|
|
|
if (ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) { |
|
|
|
/* do nodesets */ |
|
|
|
for(node=ckt->CKTnodes;node;node=node->next) { |
|
|
|
if(node->nsGiven) { |
|
|
|
if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes, |
|
|
|
node->number)) |
|
|
|
{ |
|
|
|
*(ckt->CKTrhs+node->number) = 1.0e10 * node->nodeset * |
|
|
|
ckt->CKTsrcFact; |
|
|
|
*(node->ptr) = 1e10; |
|
|
|
} else { |
|
|
|
*(ckt->CKTrhs+node->number) = node->nodeset * |
|
|
|
ckt->CKTsrcFact; |
|
|
|
*(node->ptr) = 1; |
|
|
|
} |
|
|
|
/* DAG: Original CIDER fix. If above fix doesn't work, |
|
|
|
* revert to this. |
|
|
|
*/ |
|
|
|
/* |
|
|
|
*(ckt->CKTrhs+node->number) += 1.0e10 * node->nodeset; |
|
|
|
*(node->ptr) += 1.0e10; |
|
|
|
*/ |
|
|
|
} |
|
|
|
for (node = ckt->CKTnodes; node; node = node->next) { |
|
|
|
if (node->nsGiven) { |
|
|
|
if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes, |
|
|
|
node->number)) { |
|
|
|
*(ckt->CKTrhs+node->number) = 1.0e10 * node->nodeset * |
|
|
|
ckt->CKTsrcFact; |
|
|
|
*(node->ptr) = 1e10; |
|
|
|
} else { |
|
|
|
*(ckt->CKTrhs+node->number) = node->nodeset * |
|
|
|
ckt->CKTsrcFact; |
|
|
|
*(node->ptr) = 1; |
|
|
|
} |
|
|
|
/* DAG: Original CIDER fix. If above fix doesn't work, |
|
|
|
* revert to this. |
|
|
|
*/ |
|
|
|
/* |
|
|
|
* *(ckt->CKTrhs+node->number) += 1.0e10 * node->nodeset; |
|
|
|
* *(node->ptr) += 1.0e10; |
|
|
|
*/ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if( (ckt->CKTmode & MODETRANOP) && (!(ckt->CKTmode & MODEUIC))) { |
|
|
|
for(node=ckt->CKTnodes;node;node=node->next) { |
|
|
|
if(node->icGiven) { |
|
|
|
if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes, |
|
|
|
node->number)) |
|
|
|
{ |
|
|
|
/* Original code: |
|
|
|
*(ckt->CKTrhs+node->number) += 1.0e10 * node->ic; |
|
|
|
*/ |
|
|
|
*(ckt->CKTrhs+node->number) = 1.0e10 * node->ic * |
|
|
|
ckt->CKTsrcFact; |
|
|
|
*(node->ptr) += 1.0e10; |
|
|
|
} else { |
|
|
|
/* Original code: |
|
|
|
*(ckt->CKTrhs+node->number) = node->ic; |
|
|
|
*/ |
|
|
|
*(ckt->CKTrhs+node->number) = node->ic*ckt->CKTsrcFact; /* AlansFixes */ |
|
|
|
*(node->ptr) = 1; |
|
|
|
} |
|
|
|
/* DAG: Original CIDER fix. If above fix doesn't work, |
|
|
|
* revert to this. |
|
|
|
*/ |
|
|
|
/* |
|
|
|
*(ckt->CKTrhs+node->number) += 1.0e10 * node->ic; |
|
|
|
*(node->ptr) += 1.0e10; |
|
|
|
*/ |
|
|
|
if ((ckt->CKTmode & MODETRANOP) && (!(ckt->CKTmode & MODEUIC))) { |
|
|
|
for (node = ckt->CKTnodes; node; node = node->next) { |
|
|
|
if (node->icGiven) { |
|
|
|
if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes, |
|
|
|
node->number)) { |
|
|
|
/* Original code: |
|
|
|
*(ckt->CKTrhs+node->number) += 1.0e10 * node->ic; |
|
|
|
*/ |
|
|
|
*(ckt->CKTrhs+node->number) = 1.0e10 * node->ic * |
|
|
|
ckt->CKTsrcFact; |
|
|
|
*(node->ptr) += 1.0e10; |
|
|
|
} else { |
|
|
|
/* Original code: |
|
|
|
*(ckt->CKTrhs+node->number) = node->ic; |
|
|
|
*/ |
|
|
|
*(ckt->CKTrhs+node->number) = node->ic*ckt->CKTsrcFact; /* AlansFixes */ |
|
|
|
*(node->ptr) = 1; |
|
|
|
} |
|
|
|
/* DAG: Original CIDER fix. If above fix doesn't work, |
|
|
|
* revert to this. |
|
|
|
*/ |
|
|
|
/* |
|
|
|
* *(ckt->CKTrhs+node->number) += 1.0e10 * node->ic; |
|
|
|
* *(node->ptr) += 1.0e10; |
|
|
|
*/ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
/* SMPprint(ckt->CKTmatrix, stdout); if you want to debug, this is a |
|
|
|
good place to start ... */ |
|
|
|
good place to start ... */ |
|
|
|
|
|
|
|
#ifdef PARALLEL_ARCH |
|
|
|
combine: |
|
|
|
ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds() - startTime; |
|
|
|
startTime = SPfrontEnd->IFseconds(); |
|
|
|
startTime = SPfrontEnd->IFseconds(); |
|
|
|
/* See if any of the DEVload functions bailed. If not, proceed. */ |
|
|
|
ibuf[0] = error; |
|
|
|
ibuf[1] = ckt->CKTnoncon; |
|
|
|
IGOP_( &type, ibuf, &length, "+" ); |
|
|
|
IGOP_(&type, ibuf, &length, "+"); |
|
|
|
ckt->CKTnoncon = ibuf[1]; |
|
|
|
ckt->CKTstat->STATsyncTime += SPfrontEnd->IFseconds() - startTime; |
|
|
|
if (ibuf[0] == OK) { |
|
|
|
startTime = SPfrontEnd->IFseconds(); |
|
|
|
SMPcombine( ckt->CKTmatrix, ckt->CKTrhs, ckt->CKTrhsSpare ); |
|
|
|
ckt->CKTstat->STATcombineTime += SPfrontEnd->IFseconds() - startTime; |
|
|
|
return(OK); |
|
|
|
startTime = SPfrontEnd->IFseconds(); |
|
|
|
SMPcombine(ckt->CKTmatrix, ckt->CKTrhs, ckt->CKTrhsSpare); |
|
|
|
ckt->CKTstat->STATcombineTime += SPfrontEnd->IFseconds() - startTime; |
|
|
|
return(OK); |
|
|
|
} else { |
|
|
|
if ( ibuf[0] != error ) { |
|
|
|
error = E_MULTIERR; |
|
|
|
} |
|
|
|
return(error); |
|
|
|
if (ibuf[0] != error) { |
|
|
|
error = E_MULTIERR; |
|
|
|
} |
|
|
|
return(error); |
|
|
|
} |
|
|
|
#else |
|
|
|
ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds()-startTime; |
|
|
|
@ -199,19 +197,20 @@ combine: |
|
|
|
static int |
|
|
|
ZeroNoncurRow(SMPmatrix *matrix, CKTnode *nodes, int rownum) |
|
|
|
{ |
|
|
|
CKTnode *n; |
|
|
|
double *x; |
|
|
|
int currents; |
|
|
|
|
|
|
|
currents = 0; |
|
|
|
for (n = nodes; n; n = n->next) { |
|
|
|
x = (double *) SMPfindElt(matrix, rownum, n->number, 0); |
|
|
|
if (x) { |
|
|
|
if (n->type == SP_CURRENT) |
|
|
|
currents = 1; |
|
|
|
else |
|
|
|
*x = 0.0; |
|
|
|
} |
|
|
|
} |
|
|
|
return currents; |
|
|
|
CKTnode *n; |
|
|
|
double *x; |
|
|
|
int currents; |
|
|
|
|
|
|
|
currents = 0; |
|
|
|
for (n = nodes; n; n = n->next) { |
|
|
|
x = (double *) SMPfindElt(matrix, rownum, n->number, 0); |
|
|
|
if (x) { |
|
|
|
if (n->type == SP_CURRENT) |
|
|
|
currents = 1; |
|
|
|
else |
|
|
|
*x = 0.0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return currents; |
|
|
|
} |