swload, swtrunc hasty cleanup
this is sort of whitespace changes, which is not meant to change functionality in any way.
This commit is contained in:
parent
878c9645c7
commit
1f2c63233e
|
|
@ -12,56 +12,51 @@ Modified: 2001 Jon Engelbert
|
||||||
#include "ngspice/sperror.h"
|
#include "ngspice/sperror.h"
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
SWload(GENmodel *inModel, CKTcircuit *ckt)
|
SWload(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
/* actually load the current values into the
|
|
||||||
* sparse matrix previously provided
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
SWmodel *model = (SWmodel *) inModel;
|
SWmodel *model = (SWmodel *) inModel;
|
||||||
SWinstance *here;
|
SWinstance *here;
|
||||||
double g_now;
|
double g_now;
|
||||||
double v_ctrl;
|
double v_ctrl;
|
||||||
double previous_state = -1;
|
double previous_state = -1;
|
||||||
double current_state = -1;
|
double current_state = -1;
|
||||||
double old_current_state = -1;
|
double old_current_state = -1;
|
||||||
double REALLY_OFF = 0, REALLY_ON = 1; // switch is on or off, not in hysteresis region.
|
double REALLY_OFF = 0, REALLY_ON = 1; // switch is on or off, not in hysteresis region.
|
||||||
double HYST_OFF = 2, HYST_ON = 3; // switch is on or off while control value is in hysteresis region.
|
double HYST_OFF = 2, HYST_ON = 3; // switch is on or off while control value is in hysteresis region.
|
||||||
// double previous_region = -1;
|
// double previous_region = -1;
|
||||||
// double current_region = -1;
|
// double current_region = -1;
|
||||||
|
|
||||||
/* loop through all the switch models */
|
for (; model; model = SWnextModel(model)) {
|
||||||
for( ; model != NULL; model = SWnextModel(model)) {
|
for (here = SWinstances(model); here; here=SWnextInstance(here)) {
|
||||||
|
|
||||||
/* loop through all the instances of the model */
|
old_current_state = ckt->CKTstates[0][here->SWstate + 0];
|
||||||
for (here = SWinstances(model); here != NULL ;
|
previous_state = ckt->CKTstates[1][here->SWstate + 0];
|
||||||
here=SWnextInstance(here)) {
|
|
||||||
|
|
||||||
old_current_state = *(ckt->CKTstates[0] + here->SWstate);
|
|
||||||
previous_state = *(ckt->CKTstates[1] + here->SWstate);
|
|
||||||
|
|
||||||
v_ctrl = *(ckt->CKTrhsOld + here->SWposCntrlNode)
|
v_ctrl =
|
||||||
- *(ckt->CKTrhsOld + here->SWnegCntrlNode);
|
ckt->CKTrhsOld [here->SWposCntrlNode] -
|
||||||
|
ckt->CKTrhsOld [here->SWnegCntrlNode];
|
||||||
/* decide the state of the switch */
|
|
||||||
|
|
||||||
if(ckt->CKTmode & (MODEINITFIX|MODEINITJCT)) {
|
|
||||||
|
|
||||||
if(here->SWzero_stateGiven) {
|
/* decide the state of the switch */
|
||||||
/* switch specified "on" */
|
|
||||||
if ((model->SWvHysteresis >= 0) && (v_ctrl > (model->SWvThreshold + model->SWvHysteresis)))
|
if (ckt->CKTmode & (MODEINITFIX | MODEINITJCT)) {
|
||||||
current_state = REALLY_ON;
|
|
||||||
else if ((model->SWvHysteresis < 0) && (v_ctrl > (model->SWvThreshold - model->SWvHysteresis)))
|
if (here->SWzero_stateGiven) {
|
||||||
current_state = REALLY_ON;
|
/* switch specified "on" */
|
||||||
else
|
if ((model->SWvHysteresis >= 0) && (v_ctrl > (model->SWvThreshold + model->SWvHysteresis)))
|
||||||
current_state = HYST_ON;
|
current_state = REALLY_ON;
|
||||||
|
else if ((model->SWvHysteresis < 0) && (v_ctrl > (model->SWvThreshold - model->SWvHysteresis)))
|
||||||
|
current_state = REALLY_ON;
|
||||||
|
else
|
||||||
|
current_state = HYST_ON;
|
||||||
} else {
|
} else {
|
||||||
if ((model->SWvHysteresis >= 0) && (v_ctrl < (model->SWvThreshold - model->SWvHysteresis)))
|
if ((model->SWvHysteresis >= 0) && (v_ctrl < (model->SWvThreshold - model->SWvHysteresis)))
|
||||||
current_state = REALLY_OFF;
|
current_state = REALLY_OFF;
|
||||||
else if ((model->SWvHysteresis < 0) && (v_ctrl < (model->SWvThreshold + model->SWvHysteresis)))
|
else if ((model->SWvHysteresis < 0) && (v_ctrl < (model->SWvThreshold + model->SWvHysteresis)))
|
||||||
current_state = REALLY_OFF;
|
current_state = REALLY_OFF;
|
||||||
else
|
else
|
||||||
current_state = HYST_OFF;
|
current_state = HYST_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (ckt->CKTmode & (MODEINITSMSIG)) {
|
} else if (ckt->CKTmode & (MODEINITSMSIG)) {
|
||||||
|
|
@ -71,79 +66,80 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
} else if (ckt->CKTmode & (MODEINITFLOAT)) {
|
} else if (ckt->CKTmode & (MODEINITFLOAT)) {
|
||||||
|
|
||||||
/* use state0 since INITTRAN or INITPRED already called */
|
/* use state0 since INITTRAN or INITPRED already called */
|
||||||
if (model->SWvHysteresis > 0) {
|
if (model->SWvHysteresis > 0) {
|
||||||
if (v_ctrl > (model->SWvThreshold + model->SWvHysteresis)) {
|
if (v_ctrl > (model->SWvThreshold + model->SWvHysteresis)) {
|
||||||
current_state = REALLY_ON;
|
current_state = REALLY_ON;
|
||||||
} else if (v_ctrl < (model->SWvThreshold - model->SWvHysteresis)) {
|
} else if (v_ctrl < (model->SWvThreshold - model->SWvHysteresis)) {
|
||||||
current_state = REALLY_OFF;
|
current_state = REALLY_OFF;
|
||||||
} else {
|
} else {
|
||||||
current_state = old_current_state;
|
current_state = old_current_state;
|
||||||
}
|
}
|
||||||
} else { // negative hysteresis case.
|
} else { // negative hysteresis case.
|
||||||
if (v_ctrl > (model->SWvThreshold - model->SWvHysteresis))
|
if (v_ctrl > (model->SWvThreshold - model->SWvHysteresis)) {
|
||||||
{
|
current_state = REALLY_ON;
|
||||||
current_state = REALLY_ON;
|
} else if (v_ctrl < (model->SWvThreshold + model->SWvHysteresis)) {
|
||||||
} else if (v_ctrl < (model->SWvThreshold + model->SWvHysteresis))
|
current_state = REALLY_OFF;
|
||||||
{
|
} else { // in hysteresis... change value if going from low to hysteresis, or from hi to hysteresis.
|
||||||
current_state = REALLY_OFF;
|
// if previous state was in hysteresis, then don't change the state..
|
||||||
} else { // in hysteresis... change value if going from low to hysteresis, or from hi to hysteresis.
|
if ((previous_state == HYST_OFF) || (previous_state == HYST_ON)) {
|
||||||
// if previous state was in hysteresis, then don't change the state..
|
current_state = previous_state;
|
||||||
if ((previous_state == HYST_OFF) || (previous_state == HYST_ON)) {
|
} else if (previous_state == REALLY_ON) {
|
||||||
current_state = previous_state;
|
current_state = HYST_OFF;
|
||||||
} else if (previous_state == REALLY_ON) {
|
} else if (previous_state == REALLY_OFF) {
|
||||||
current_state = HYST_OFF;
|
current_state = HYST_ON;
|
||||||
} else if (previous_state == REALLY_OFF) {
|
} else {
|
||||||
current_state = HYST_ON;
|
internalerror("bad value for previous state in swload");
|
||||||
} else
|
}
|
||||||
internalerror("bad value for previous state in swload");
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(current_state != old_current_state) {
|
|
||||||
ckt->CKTnoncon++; /* ensure one more iteration */
|
|
||||||
ckt->CKTtroubleElt = (GENinstance *) here;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (current_state != old_current_state) {
|
||||||
|
ckt->CKTnoncon++; /* ensure one more iteration */
|
||||||
|
ckt->CKTtroubleElt = (GENinstance *) here;
|
||||||
|
}
|
||||||
|
|
||||||
} else if(ckt->CKTmode & (MODEINITTRAN|MODEINITPRED) ) {
|
} else if (ckt->CKTmode & (MODEINITTRAN | MODEINITPRED)) {
|
||||||
|
|
||||||
|
if (model->SWvHysteresis > 0) {
|
||||||
|
if (v_ctrl > (model->SWvThreshold + model->SWvHysteresis))
|
||||||
|
current_state = REALLY_ON;
|
||||||
|
else if (v_ctrl < (model->SWvThreshold - model->SWvHysteresis))
|
||||||
|
current_state = REALLY_OFF;
|
||||||
|
else
|
||||||
|
current_state = previous_state;
|
||||||
|
} else { // negative hysteresis case.
|
||||||
|
if (v_ctrl > (model->SWvThreshold - model->SWvHysteresis))
|
||||||
|
current_state = REALLY_ON;
|
||||||
|
else if (v_ctrl < (model->SWvThreshold + model->SWvHysteresis))
|
||||||
|
current_state = REALLY_OFF;
|
||||||
|
else {
|
||||||
|
if ((previous_state == HYST_ON) || (previous_state == HYST_OFF))
|
||||||
|
current_state = previous_state;
|
||||||
|
else if (previous_state == REALLY_ON)
|
||||||
|
current_state = REALLY_OFF;
|
||||||
|
else if (previous_state == REALLY_OFF)
|
||||||
|
current_state = REALLY_ON;
|
||||||
|
else
|
||||||
|
current_state = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (model->SWvHysteresis > 0) {
|
|
||||||
if (v_ctrl > (model->SWvThreshold + model->SWvHysteresis))
|
|
||||||
current_state = REALLY_ON;
|
|
||||||
else if (v_ctrl < (model->SWvThreshold - model->SWvHysteresis))
|
|
||||||
current_state = REALLY_OFF;
|
|
||||||
else
|
|
||||||
current_state = previous_state;
|
|
||||||
} else { // negative hysteresis case.
|
|
||||||
if (v_ctrl > (model->SWvThreshold - model->SWvHysteresis))
|
|
||||||
current_state = REALLY_ON;
|
|
||||||
else if (v_ctrl < (model->SWvThreshold + model->SWvHysteresis))
|
|
||||||
current_state = REALLY_OFF;
|
|
||||||
else {
|
|
||||||
current_state = 0.0;
|
|
||||||
if ((previous_state == HYST_ON) || (previous_state == HYST_OFF)) {
|
|
||||||
current_state = previous_state;
|
|
||||||
} else if (previous_state == REALLY_ON) {
|
|
||||||
current_state = REALLY_OFF;
|
|
||||||
} else if (previous_state == REALLY_OFF) {
|
|
||||||
current_state = REALLY_ON;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// code added to force the state to be updated.
|
// code added to force the state to be updated.
|
||||||
// there is a possible problem. What if, during the transient analysis, the time is stepped
|
// there is a possible problem. What if, during the transient analysis, the time is stepped
|
||||||
// forward enough to change the switch's state, but that time point is rejected as being too
|
// forward enough to change the switch's state, but that time point is rejected as being too
|
||||||
// distant and then the time is pushed back to a time before the switch changed states.
|
// distant and then the time is pushed back to a time before the switch changed states.
|
||||||
// After analyzing the transient code, it seems that this is not a problem because state updating
|
// After analyzing the transient code, it seems that this is not a problem because state updating
|
||||||
// occurs before the convergence loop in transient processing.
|
// occurs before the convergence loop in transient processing.
|
||||||
*(ckt->CKTstates[0] + here->SWstate) = current_state;
|
|
||||||
*(ckt->CKTstates[0] + here->SWstate + 1) = v_ctrl;
|
|
||||||
|
|
||||||
if ((current_state == REALLY_ON) || (current_state == HYST_ON))
|
ckt->CKTstates[0][here->SWstate + 0] = current_state;
|
||||||
g_now = model->SWonConduct;
|
ckt->CKTstates[0][here->SWstate + 1] = v_ctrl;
|
||||||
else
|
|
||||||
g_now = model->SWoffConduct;
|
if ((current_state == REALLY_ON) || (current_state == HYST_ON))
|
||||||
|
g_now = model->SWonConduct;
|
||||||
|
else
|
||||||
|
g_now = model->SWoffConduct;
|
||||||
|
|
||||||
here->SWcond = g_now;
|
here->SWcond = g_now;
|
||||||
|
|
||||||
*(here->SWposPosPtr) += g_now;
|
*(here->SWposPosPtr) += g_now;
|
||||||
|
|
@ -152,5 +148,6 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
*(here->SWnegNegPtr) += g_now;
|
*(here->SWnegNegPtr) += g_now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(OK);
|
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1985 Thomas L. Quarles
|
Author: 1985 Thomas L. Quarles
|
||||||
Modified: 2000 AlansFixes
|
Modified: 2000 AlansFixes
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "ngspice/cktdefs.h"
|
#include "ngspice/cktdefs.h"
|
||||||
|
|
@ -12,36 +10,44 @@ Modified: 2000 AlansFixes
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
#include "swdefs.h"
|
#include "swdefs.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
SWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
|
SWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
|
||||||
{
|
{
|
||||||
SWmodel *model = (SWmodel*)inModel;
|
SWmodel *model = (SWmodel *) inModel;
|
||||||
SWinstance *here;
|
SWinstance *here;
|
||||||
double lastChange, maxChange, maxStep, ref;
|
double lastChange, maxChange, maxStep, ref;
|
||||||
|
|
||||||
for( ; model!= NULL; model = SWnextModel(model)) {
|
for (; model; model = SWnextModel(model)) {
|
||||||
for(here = SWinstances(model); here != NULL ;
|
for (here = SWinstances(model); here; here = SWnextInstance(here)) {
|
||||||
here = SWnextInstance(here)) {
|
lastChange =
|
||||||
lastChange = *(ckt->CKTstate0+(here->SWstate+1)) -
|
ckt->CKTstates[0][here->SWstate + 1] -
|
||||||
*(ckt->CKTstate1+(here->SWstate+1));
|
ckt->CKTstates[1][here->SWstate + 1];
|
||||||
if (*(ckt->CKTstate0+(here->SWstate))==0) {
|
if (ckt->CKTstates[0][here->SWstate + 0] == 0) {
|
||||||
ref = (model->SWvThreshold + model->SWvHysteresis);
|
ref = (model->SWvThreshold + model->SWvHysteresis);
|
||||||
if ((*(ckt->CKTstate0+(here->SWstate+1))<ref) && (lastChange>0)) {
|
if (ckt->CKTstates[0][here->SWstate + 1] < ref && lastChange > 0)
|
||||||
maxChange = (ref - *(ckt->CKTstate0+(here->SWstate+1))) *
|
{
|
||||||
0.75 + 0.05;
|
maxChange =
|
||||||
maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0];
|
(ref - ckt->CKTstates[0][here->SWstate + 1]) * 0.75
|
||||||
if (*timeStep > maxStep) { *timeStep = maxStep; }
|
+ 0.05;
|
||||||
}
|
maxStep = maxChange / lastChange * ckt->CKTdeltaOld[0];
|
||||||
|
if (*timeStep > maxStep)
|
||||||
|
*timeStep = maxStep;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ref = (model->SWvThreshold - model->SWvHysteresis);
|
ref = model->SWvThreshold - model->SWvHysteresis;
|
||||||
if ((*(ckt->CKTstate0+(here->SWstate+1))>ref) && (lastChange<0)) {
|
if (ckt->CKTstates[0][here->SWstate + 1] > ref && lastChange < 0)
|
||||||
maxChange = (ref - *(ckt->CKTstate0+(here->SWstate+1))) *
|
{
|
||||||
0.75 - 0.05;
|
maxChange =
|
||||||
maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0];
|
(ref - ckt->CKTstates[0][here->SWstate + 1]) * 0.75
|
||||||
if (*timeStep > maxStep) { *timeStep = maxStep; }
|
- 0.05;
|
||||||
}
|
maxStep = maxChange / lastChange * ckt->CKTdeltaOld[0];
|
||||||
|
if (*timeStep > maxStep)
|
||||||
|
*timeStep = maxStep;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(OK);
|
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue