Neew pswitch with patch 0001-pswitch-fix.patch from Jube 3rd, 21 at
https://sourceforge.net/p/ngspice/discussion/127605/thread/d55d2322f2/#c966/b802/4764/2540/3b3f/04a4/bc51/3a68 Input resistance, numerically computed derivatives with auto-partial, reasonable limits.
This commit is contained in:
parent
5cc5e351f1
commit
d36fcaf34c
|
|
@ -139,6 +139,7 @@ void cm_pswitch(ARGS) /* structure holding parms,
|
|||
double cntl_off; /* voltage below the switch has resistance roff */
|
||||
double r_on; /* on resistance */
|
||||
double r_off; /* off resistance */
|
||||
double r_cntl_in; /* input resistance for control terminal */
|
||||
double logmean; /* log-mean of resistor values */
|
||||
double logratio; /* log-ratio of resistor values */
|
||||
double cntl_mean; /* mean of control values */
|
||||
|
|
@ -153,7 +154,7 @@ void cm_pswitch(ARGS) /* structure holding parms,
|
|||
|
||||
Mif_Complex_t ac_gain;
|
||||
|
||||
char *cntl_error = "\n*****ERROR*****\nPSWITCH: CONTROL voltage delta less than 1.0e-12\n";
|
||||
|
||||
|
||||
Local_Data_t *loc; /* Pointer to local static data, not to be included
|
||||
in the state vector */
|
||||
|
|
@ -165,15 +166,19 @@ void cm_pswitch(ARGS) /* structure holding parms,
|
|||
cntl_off = PARAM(cntl_off);
|
||||
r_on = PARAM(r_on);
|
||||
r_off = PARAM(r_off);
|
||||
r_cntl_in = PARAM(r_cntl_in);
|
||||
|
||||
if( r_on < 1.0e-3 ) r_on = 1.0e-3; /* Set minimum 'ON' resistance */
|
||||
r_on = (r_on < 1.0e-3) ? 1.0e-3 : r_on; /* Set minimum 'ON' resistance */
|
||||
r_off = (r_off > 1.0e12) ? 1.0e12 : r_off; /* Set maximum 'OFF' resistance */
|
||||
|
||||
if( (fabs(cntl_on - cntl_off) < 1.0e-12) ) {
|
||||
cm_message_send(cntl_error);
|
||||
return;
|
||||
}
|
||||
|
||||
if(INIT == 1) { /* first time through, allocate memory, set static parameters */
|
||||
char *cntl_error = "\n*****ERROR*****\nPSWITCH: CONTROL voltage delta less than 1.0e-12\n";
|
||||
|
||||
if( (fabs(cntl_on - cntl_off) < 1.0e-12) ) {
|
||||
cm_message_send(cntl_error);
|
||||
return;
|
||||
}
|
||||
|
||||
CALLBACK = cm_pswitch_callback;
|
||||
|
||||
|
|
@ -182,13 +187,24 @@ void cm_pswitch(ARGS) /* structure holding parms,
|
|||
loc = STATIC_VAR (locdata);
|
||||
|
||||
if ( PARAM(log) == MIF_TRUE ) { /* Logarithmic Variation in 'R' */
|
||||
if (cntl_on > cntl_off)
|
||||
{
|
||||
cntl_on = 1;
|
||||
cntl_off = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cntl_on = 0;
|
||||
cntl_off = 1;
|
||||
}
|
||||
|
||||
loc->logmean = log(sqrt(r_on * r_off));
|
||||
loc->logratio = log(r_on / r_off);
|
||||
loc->cntl_mean = (cntl_on + cntl_off) / 2.;
|
||||
loc->cntl_mean = 0.5;
|
||||
loc->cntl_diff = cntl_on - cntl_off;
|
||||
loc->intermediate = loc->logratio / loc->cntl_diff;
|
||||
loc->c1 = 1.5 * loc->logratio / loc->cntl_diff;
|
||||
loc->c3 = 2. * loc->logratio / pow(loc->cntl_diff, 3);
|
||||
loc->c3 = 2. * loc->logratio / (loc->cntl_diff * loc->cntl_diff * loc->cntl_diff); //pow(loc->cntl_diff, 3);
|
||||
loc->c2 = 3 * loc->c3;
|
||||
} else {
|
||||
loc->cntl_diff = cntl_on - cntl_off;
|
||||
|
|
@ -204,37 +220,42 @@ void cm_pswitch(ARGS) /* structure holding parms,
|
|||
cntl_mean = loc->cntl_mean;
|
||||
cntl_diff = loc->cntl_diff;
|
||||
intermediate = loc->intermediate;
|
||||
double inmean = INPUT(cntl_in) - cntl_mean;
|
||||
if (cntl_on >= cntl_off) {
|
||||
if (INPUT(cntl_in) >= cntl_on) {
|
||||
double inmean;// = INPUT(cntl_in) - cntl_mean;
|
||||
int outOfLimit = 0;
|
||||
if (cntl_on > cntl_off) {
|
||||
inmean = ((INPUT(cntl_in) - PARAM(cntl_off)) / (PARAM(cntl_on) - PARAM(cntl_off))) - cntl_mean;
|
||||
if (INPUT(cntl_in) > cntl_on) {
|
||||
r = r_on;
|
||||
outOfLimit = 1;
|
||||
}
|
||||
else if (INPUT(cntl_in) <= cntl_off) {
|
||||
else if (INPUT(cntl_in) < cntl_off) {
|
||||
r = r_off;
|
||||
outOfLimit = 1;
|
||||
}
|
||||
else {
|
||||
r = exp(logmean + 3 * logratio * inmean / (2 * cntl_diff) - loc->c3 * pow(inmean, 3));
|
||||
r = exp(logmean + loc->c1 * inmean - loc->c3 * inmean * inmean * inmean);
|
||||
if(r<r_on) r=r_on;/* minimum resistance limiter */
|
||||
}
|
||||
} else {
|
||||
if (INPUT(cntl_in) <= cntl_on) {
|
||||
inmean = (PARAM(cntl_on) - (INPUT(cntl_in)) / (PARAM(cntl_off) - PARAM(cntl_on))) - cntl_mean;
|
||||
if (INPUT(cntl_in) < cntl_on) {
|
||||
r = r_on;
|
||||
outOfLimit = 1;
|
||||
}
|
||||
else if (INPUT(cntl_in) >= cntl_off) {
|
||||
else if (INPUT(cntl_in) > cntl_off) {
|
||||
r = r_off;
|
||||
outOfLimit = 1;
|
||||
}
|
||||
else {
|
||||
r = exp(logmean + 3 * logratio * inmean / (2 * cntl_diff) - loc->c3 * pow(inmean, 3));
|
||||
// r = exp(logmean + 3 * logratio * (INPUT(cntl_in) - cntl_mean) / (2 * cntl_diff) - 2 * logratio * pow((INPUT(cntl_in) - cntl_mean), 3) / pow(cntl_diff, 3));
|
||||
r = exp(logmean + loc->c1 * inmean - loc->c3 * inmean * inmean * inmean);
|
||||
if(r<r_on) r=r_on;/* minimum resistance limiter */
|
||||
}
|
||||
}
|
||||
|
||||
pi_pcntl = INPUT(out) / r * (loc->c2 * inmean * inmean - loc->c1);
|
||||
if(r == r_on)
|
||||
pi_pcntl = 0;
|
||||
if(r == r_off)
|
||||
if(1 == outOfLimit){
|
||||
pi_pcntl = 0;
|
||||
}
|
||||
pi_pvout = 1.0 / r;
|
||||
|
||||
}
|
||||
|
|
@ -249,10 +270,14 @@ void cm_pswitch(ARGS) /* structure holding parms,
|
|||
}
|
||||
|
||||
if(ANALYSIS != MIF_AC) { /* Output DC & Transient Values */
|
||||
OUTPUT(out) = INPUT(out) / r;
|
||||
PARTIAL(out,out) = pi_pvout;
|
||||
PARTIAL(out,cntl_in) = pi_pcntl;
|
||||
// cm_analog_auto_partial();
|
||||
OUTPUT(out) = INPUT(out) / r;
|
||||
OUTPUT(cntl_in) = INPUT(cntl_in) / r_cntl_in;
|
||||
// PARTIAL(out,out) = pi_pvout;
|
||||
// PARTIAL(out,cntl_in) = pi_pcntl;
|
||||
// PARTIAL(cntl_in,cntl_in) = 1 / r_cntl_in;
|
||||
// PARTIAL(cntl_in,out) = 0; /* cntl input resistance is
|
||||
// independent to out port */
|
||||
cm_analog_auto_partial();
|
||||
|
||||
/* Note that the minus signs are required because current is positive
|
||||
flowing INTO rather than OUT OF a component node. */
|
||||
|
|
|
|||
|
|
@ -30,11 +30,11 @@ PORT_TABLE:
|
|||
|
||||
Port_Name: cntl_in out
|
||||
Description: "input" "resistive output"
|
||||
Direction: in inout
|
||||
Default_Type: v gd
|
||||
Allowed_Types: [v,vd,i,id,vnam] [gd]
|
||||
Vector: no no
|
||||
Vector_Bounds: - -
|
||||
Direction: inout inout
|
||||
Default_Type: gd gd
|
||||
Allowed_Types: [g,gd] [gd]
|
||||
Vector: no no
|
||||
Vector_Bounds: - -
|
||||
Null_Allowed: no no
|
||||
|
||||
|
||||
|
|
@ -66,14 +66,14 @@ Null_Allowed: yes yes
|
|||
|
||||
PARAMETER_TABLE:
|
||||
|
||||
Parameter_Name: r_on
|
||||
Description: "on resistance"
|
||||
Data_Type: real
|
||||
Default_Value: 1.0
|
||||
Limits: -
|
||||
Vector: no
|
||||
Vector_Bounds: -
|
||||
Null_Allowed: yes
|
||||
Parameter_Name: r_on r_cntl_in
|
||||
Description: "on resistance" "input resistance for control terminal"
|
||||
Data_Type: real real
|
||||
Default_Value: 1.0 1.0e12
|
||||
Limits: - -
|
||||
Vector: no no
|
||||
Vector_Bounds: - -
|
||||
Null_Allowed: yes yes
|
||||
|
||||
|
||||
STATIC_VAR_TABLE:
|
||||
|
|
|
|||
Loading…
Reference in New Issue