You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
6.2 KiB
201 lines
6.2 KiB
/**********
|
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
|
Author: 1985 Thomas L. Quarles
|
|
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
|
|
*/
|
|
|
|
#include "ngspice/ngspice.h"
|
|
#include "ngspice/smpdefs.h"
|
|
#include "ngspice/cktdefs.h"
|
|
#include "ngspice/devdefs.h"
|
|
#include "ngspice/sperror.h"
|
|
|
|
#ifdef XSPICE
|
|
#include "ngspice/enh.h"
|
|
/* gtri - add - wbk - 11/26/90 - add include for MIF global data */
|
|
#include "ngspice/mif.h"
|
|
/* gtri - end - wbk - 11/26/90 */
|
|
#endif
|
|
|
|
static int ZeroNoncurRow(SMPmatrix *matrix, CKTnode *nodes, int rownum);
|
|
|
|
// #define PER_DEVICE_STATS
|
|
int
|
|
CKTload(CKTcircuit *ckt)
|
|
{
|
|
int i;
|
|
int size;
|
|
double startTime, td0;
|
|
CKTnode *node;
|
|
int error;
|
|
#ifdef STEPDEBUG
|
|
int noncon;
|
|
#endif /* STEPDEBUG */
|
|
|
|
#ifdef XSPICE
|
|
/* gtri - begin - Put resistors to ground at all nodes */
|
|
/* SMPmatrix *matrix; maschmann : deleted , because unused */
|
|
|
|
double gshunt;
|
|
int num_nodes;
|
|
|
|
/* gtri - begin - Put resistors to ground at all nodes */
|
|
#endif
|
|
|
|
td0 = SPfrontEnd->IFseconds();
|
|
|
|
#ifdef PER_DEVICE_STATS
|
|
ckt->CKTstat->devTimes[DEVmaxnum] += SPfrontEnd->IFseconds() - td0;
|
|
ckt->CKTstat->devCounts[DEVmaxnum]++;
|
|
#endif
|
|
|
|
startTime = SPfrontEnd->IFseconds();
|
|
size = SMPmatSize(ckt->CKTmatrix);
|
|
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]) {
|
|
#ifdef PER_DEVICE_STATS
|
|
td0 = SPfrontEnd->IFseconds();
|
|
#endif
|
|
error = DEVices[i]->DEVload (ckt->CKThead[i], ckt);
|
|
#ifdef PER_DEVICE_STATS
|
|
ckt->CKTstat->devTimes[i] += SPfrontEnd->IFseconds() - td0;
|
|
ckt->CKTstat->devCounts[i]++;
|
|
#endif
|
|
if (ckt->CKTnoncon)
|
|
ckt->CKTtroubleNode = 0;
|
|
#ifdef STEPDEBUG
|
|
if (noncon != ckt->CKTnoncon) {
|
|
printf("device type %s nonconvergence\n",
|
|
DEVices[i]->DEVpublic.name);
|
|
noncon = ckt->CKTnoncon;
|
|
}
|
|
#endif /* STEPDEBUG */
|
|
if (error) return(error);
|
|
}
|
|
}
|
|
|
|
|
|
#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;
|
|
|
|
/* anal_init is set by CKTdoJob and is true for first call */
|
|
/* of a particular analysis type */
|
|
g_mif_info.circuit.anal_init = MIF_FALSE;
|
|
|
|
/* gtri - end - wbk - 11/26/90 */
|
|
|
|
/* 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;
|
|
}
|
|
}
|
|
|
|
/* gtri - end - Put resistors to ground at all nodes */
|
|
#endif
|
|
|
|
if (ckt->CKTmode & MODEDC) {
|
|
/* consider doing nodeset & ic assignments */
|
|
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;
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
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 ... */
|
|
|
|
ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds()-startTime;
|
|
return(OK);
|
|
}
|
|
|
|
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;
|
|
}
|