⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swload.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Gordon JacobsModified: 2001 Jon Engelbert**********/#include "ngspice.h"#include "cktdefs.h"#include "fteext.h"#include "swdefs.h"#include "trandefs.h"#include "sperror.h"#include "suffix.h"intSWload(GENmodel *inModel, CKTcircuit *ckt)        /* actually load the current values into the          * sparse matrix previously provided          */{    SWmodel *model = (SWmodel *) inModel;    SWinstance *here;    double g_now;    double v_ctrl;    double previous_state = -1;     double 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 HYST_OFF = 2, HYST_ON = 3;	// switch is on or off while control value is in hysteresis region.//    double previous_region = -1; //    double current_region = -1;    /*  loop through all the switch models */    for( ; model != NULL; model = model->SWnextModel ) {        /* loop through all the instances of the model */        for (here = model->SWinstances; here != NULL ;                here=here->SWnextInstance) {	    if (here->SWowner != ARCHme) continue;	     			old_current_state = *(ckt->CKTstates[0] + here->SWstate);			previous_state = *(ckt->CKTstates[1] + here->SWstate);			v_ctrl = *(ckt->CKTrhsOld + here->SWposCntrlNode)                         - *(ckt->CKTrhsOld + here->SWnegCntrlNode);		  		  /* decide the state of the switch */		              if(ckt->CKTmode & (MODEINITFIX|MODEINITJCT)) {                if(here->SWzero_stateGiven) {                        /* switch specified "on" */					if ((model->SWvHysteresis >= 0) && (v_ctrl > (model->SWvThreshold + model->SWvHysteresis))) 						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 {					if ((model->SWvHysteresis >= 0) && (v_ctrl < (model->SWvThreshold - model->SWvHysteresis))) 						current_state = REALLY_OFF;					else if ((model->SWvHysteresis < 0) && (v_ctrl < (model->SWvThreshold + model->SWvHysteresis))) 						current_state = REALLY_OFF;					else 						current_state = HYST_OFF;                }            } else if (ckt->CKTmode & (MODEINITSMSIG)) {                current_state = previous_state;            } else if (ckt->CKTmode & (MODEINITFLOAT)) {                /* use state0 since INITTRAN or INITPRED already called */				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 = old_current_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 {	// in hysteresis... change value if going from low to hysteresis, or from hi to hysteresis.						// if previous state was in hysteresis, then don't change the state..						if ((previous_state == HYST_OFF) || (previous_state == HYST_ON)) {							current_state = previous_state;						} else if (previous_state == REALLY_ON) {							current_state = HYST_OFF;						} else if (previous_state == REALLY_OFF) {							current_state = HYST_ON;						} 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;                }            } 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 {						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.// 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// 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// occurs before the convergence loop in transient processing.			*(ckt->CKTstates[0] + here->SWstate) = current_state;            if ((current_state == REALLY_ON) || (current_state == HYST_ON)) 				g_now = model->SWonConduct;			else 				g_now = model->SWoffConduct;            here->SWcond = g_now;            *(here->SWposPosptr) += g_now;            *(here->SWposNegptr) -= g_now;            *(here->SWnegPosptr) -= g_now;            *(here->SWnegNegptr) += g_now;        }    }    return(OK);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -