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

📄 cfunc.mod

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 MOD
字号:
/* $Id: cfunc.mod,v 1.3 2004/07/09 18:37:56 pnenzi Exp $ *//*.......1.........2.........3.........4.........5.........6.........7.........8================================================================================FILE ilimit/cfunc.modCopyright 1991Georgia Tech Research Corporation, Atlanta, Ga. 30332All Rights ReservedPROJECT A-8503-405               AUTHORS                          6 Jun 1991     Jeffrey P. MurrayMODIFICATIONS        2 Oct 1991    Jeffrey P. Murray                                   SUMMARY    This file contains the model-specific routines used to    functionally describe the ilimit code model.INTERFACES           FILE                 ROUTINE CALLED         CMutil.c             void cm_smooth_corner();                          void cm_smooth_discontinuity();                         void cm_climit_fcn()REFERENCED FILES    Inputs from and outputs to ARGS structure.                     NON-STANDARD FEATURES    NONE===============================================================================*//*=== INCLUDE FILES ====================*/                                      /*=== CONSTANTS ========================*//*=== MACROS ===========================*/  /*=== LOCAL VARIABLES & TYPEDEFS =======*/                                        /*=== FUNCTION PROTOTYPE DEFINITIONS ===*/                   /*==============================================================================FUNCTION void cm_ilimit()AUTHORS                           6 Jun 1991     Jeffrey P. MurrayMODIFICATIONS        2 Oct 1991    Jeffrey P. MurraySUMMARY    This function implements the ilimit code model.INTERFACES           FILE                 ROUTINE CALLED         CMutil.c             void cm_smooth_corner();                          void cm_smooth_discontinuity();                         void cm_climit_fcn()RETURNED VALUE        Returns inputs and outputs via ARGS structure.GLOBAL VARIABLES        NONENON-STANDARD FEATURES    NONE==============================================================================*//*=== CM_ILIMIT ROUTINE ===*/void cm_ilimit(ARGS)  /* structure holding parms,                                        inputs, outputs, etc.     */{    double in_offset,gain,r_out_source,r_out_sink,i_limit_source,           i_limit_sink,v_pwr_range,i_source_range,i_sink_range,           r_out_domain,/*out_lower_limit,out_upper_limit,*/veq,pveq_pvin,           pveq_pvpos,pveq_pvneg,r_out,pr_out_px,i_out,i_threshold_lower,           i_threshold_upper,i_pos_pwr,pi_out_pvin,pi_pos_pvneg,           pi_pos_pvpos,pi_pos_pvout,i_neg_pwr,pi_neg_pvin,pi_neg_pvneg,           pi_neg_pvpos,pi_neg_pvout,vout,pi_out_plimit,pi_out_pvout,           pi_out_ppos_pwr,pi_out_pneg_pwr,pi_pos_pvin,pi_neg_plimit,           pi_pos_plimit,pos_pwr_in,neg_pwr_in;    Mif_Complex_t ac_gain;                                                       /* Retrieve frequently used parameters... */    in_offset = PARAM(in_offset);    gain = PARAM(gain);    r_out_source = PARAM(r_out_source);    r_out_sink = PARAM(r_out_sink);    i_limit_source = PARAM(i_limit_source);    i_limit_sink = PARAM(i_limit_sink);    v_pwr_range = PARAM(v_pwr_range);    i_source_range = PARAM(i_source_range);    i_sink_range = PARAM(i_sink_range);    r_out_domain = PARAM(r_out_domain);                                          /* Retrieve frequently used inputs... */    vout = INPUT(out);                        /* Test to see if pos_pwr or neg_pwr are connected...   */    /* if not, assign large voltage values to the variables */    /* pos_pwr andneg_pwr...                                */   if ( PORT_NULL(pos_pwr) ) {        pos_pwr_in = 1.0e6;      }    else {        pos_pwr_in = INPUT(pos_pwr);    }    if ( PORT_NULL(neg_pwr) ) {        neg_pwr_in = -1.0e6;      }    else {        neg_pwr_in = INPUT(neg_pwr);    }        /* Compute Veq plus derivatives using climit_fcn */    if(INIT != 1){     /* If reasonable power and voltage values exist (i.e., not INIT)... */    /* then calculate expected equivalent voltage values and derivs.    */	cm_climit_fcn(INPUT(in), in_offset, pos_pwr_in, neg_pwr_in,                       0.0, 0.0, v_pwr_range, gain, MIF_FALSE, &veq,                       &pveq_pvin, &pveq_pvneg, &pveq_pvpos);    }                                                                else {    /* Initialization pass...set nominal values */        veq = (pos_pwr_in - neg_pwr_in) / 2.0;        pveq_pvin = 0.0;        pveq_pvpos = 0.0;        pveq_pvneg = 0.0;    }    /* Calculate Rout */    if (r_out_source == r_out_sink) {      /* r_out constant => no calculation necessary */        r_out = r_out_source;        pr_out_px = 0.0;    }    else {    /* Interpolate smoothly between sourcing & sinking values */    cm_smooth_discontinuity(veq - vout, -r_out_domain, r_out_sink, r_out_domain,                   r_out_source, &r_out, &pr_out_px);    }                                                                              /* Calculate i_out & derivatives */                                                          i_threshold_lower = -i_limit_sink + i_sink_range;    i_threshold_upper = i_limit_source - i_source_range;    i_out = (veq - vout) / r_out;    pi_out_pvin = (pveq_pvin/r_out - veq*pr_out_px*pveq_pvin/                   (r_out*r_out));    pi_out_pvout = (-1.0/r_out - vout*pr_out_px/(r_out*r_out));    pi_out_ppos_pwr = (pveq_pvpos/r_out - veq*pr_out_px*pveq_pvpos/                       (r_out*r_out));    pi_out_pneg_pwr = (pveq_pvneg/r_out - veq*pr_out_px*pveq_pvneg/                       (r_out*r_out));                                                               /* Preset i_pos_pwr & i_neg_pwr & partials to 0.0 */    i_pos_pwr = 0.0;    pi_pos_pvin = 0.0;    pi_pos_pvneg = 0.0;    pi_pos_pvpos = 0.0;    pi_pos_pvout = 0.0;    i_neg_pwr = 0.0;    pi_neg_pvin = 0.0;    pi_neg_pvneg = 0.0;    pi_neg_pvpos = 0.0;    pi_neg_pvout = 0.0;    /* Determine operating point of i_out for limiting */    if (i_out < 0.0) {                         /* i_out sinking */        if (i_out < i_threshold_lower) {                 if (i_out < (-i_limit_sink-i_sink_range)) { /* i_out lower-limited */                i_out = -i_limit_sink;                i_neg_pwr = -i_out;                pi_out_pvin = 0.0;                pi_out_pvout = 0.0;                pi_out_ppos_pwr = 0.0;                pi_out_pneg_pwr = 0.0;            }            else {               /* i_out in lower smoothing region */                cm_smooth_corner(i_out,-i_limit_sink,-i_limit_sink,i_sink_range,                            0.0,1.0,&i_out,&pi_out_plimit);                pi_out_pvin = pi_out_pvin * pi_out_plimit;                pi_out_pvout = pi_out_pvout * pi_out_plimit;                pi_out_ppos_pwr = pi_out_ppos_pwr * pi_out_plimit;                pi_out_pneg_pwr = pi_out_pneg_pwr * pi_out_plimit;                i_neg_pwr = -i_out;                pi_neg_pvin = -pi_out_pvin;                pi_neg_pvneg = -pi_out_pneg_pwr;                pi_neg_pvpos = -pi_out_ppos_pwr;                pi_neg_pvout = -pi_out_pvout;            }         }        else {  /* i_out in lower linear region...calculate i_neg_pwr */            if (i_out > -2.0*i_sink_range) {  /* i_out near 0.0...smooth i_neg_pwr */                cm_smooth_corner(i_out,-i_sink_range,0.0,i_sink_range,1.0,0.0,                            &i_neg_pwr,&pi_neg_plimit);                i_neg_pwr = -i_neg_pwr;                pi_neg_pvin = -pi_out_pvin * pi_neg_plimit;                pi_neg_pvneg = -pi_out_pneg_pwr * pi_neg_plimit;                pi_neg_pvpos = -pi_out_ppos_pwr * pi_neg_plimit;                pi_neg_pvout = -pi_out_pvout * pi_neg_plimit;            }            else {                i_neg_pwr = -i_out;  /* Not near i_out=0.0 => i_neg_pwr=-i_out */                pi_neg_pvin = -pi_out_pvin;                pi_neg_pvneg = -pi_out_pneg_pwr;                pi_neg_pvpos = -pi_out_ppos_pwr;                pi_neg_pvout = -pi_out_pvout;            }        }    }    else {                                     /* i_out sourcing */        if (i_out > i_threshold_upper) {            if (i_out > (i_limit_source + i_source_range)) { /* i_out upper-limited */                i_out = i_limit_source;                i_pos_pwr = -i_out;                pi_out_pvin = 0.0;                pi_out_pvout = 0.0;                pi_out_ppos_pwr = 0.0;                pi_out_pneg_pwr = 0.0;            }            else {               /* i_out in upper smoothing region */                cm_smooth_corner(i_out,i_limit_source,i_limit_source,i_sink_range,                            1.0,0.0,&i_out,&pi_out_plimit);                pi_out_pvin = pi_out_pvin * pi_out_plimit;                pi_out_pvout = pi_out_pvout * pi_out_plimit;                pi_out_ppos_pwr = pi_out_ppos_pwr * pi_out_plimit;                pi_out_pneg_pwr = pi_out_pneg_pwr * pi_out_plimit;                i_pos_pwr = -i_out;                pi_pos_pvin = -pi_out_pvin;                pi_pos_pvneg = -pi_out_pneg_pwr;                pi_pos_pvpos = -pi_out_ppos_pwr;                pi_pos_pvout = -pi_out_pvout;            }        }        else {  /* i_out in upper linear region...calculate i_pos_pwr */            if (i_out < 2.0*i_source_range) { /* i_out near 0.0...smooth i_pos_pwr */                cm_smooth_corner(i_out,i_source_range,0.0,i_source_range,0.0,1.0,                            &i_pos_pwr,&pi_pos_plimit);                i_pos_pwr = -i_pos_pwr;                pi_pos_pvin = -pi_out_pvin * pi_pos_plimit;                pi_pos_pvneg = -pi_out_pneg_pwr * pi_pos_plimit;                pi_pos_pvpos = -pi_out_ppos_pwr * pi_pos_plimit;                pi_pos_pvout = -pi_out_pvout * pi_pos_plimit;            }            else {                   /* Not near i_out=0.0 => i_pos_pwr=-i_out */                i_pos_pwr = -i_out;                pi_pos_pvin = -pi_out_pvin;                pi_pos_pvneg = -pi_out_pneg_pwr;                pi_pos_pvpos = -pi_out_ppos_pwr;                pi_pos_pvout = -pi_out_pvout;            }        }    }        if (ANALYSIS != MIF_AC) {     /* DC & Transient Analyses */        /* Debug line...REMOVE FOR FINAL VERSION!!! */        /*OUTPUT(t1) = veq;        OUTPUT(t2) = r_out;        OUTPUT(t3) = pveq_pvin;        OUTPUT(t4) = pveq_pvpos;        OUTPUT(t5) = pveq_pvneg;*/        OUTPUT(out) = -i_out;                     /* Remember...current polarity must be    */        PARTIAL(out,in) = -pi_out_pvin;           /* reversed for SPICE...all previous code */        PARTIAL(out,out) = -pi_out_pvout;         /* assumes i_out positive when EXITING    */       											  /* the model and negative when entering.  */        										  /* SPICE assumes the opposite, so a       */                                                  /* minus sign is added to all currents    */                                                  /* and current partials to compensate for */                                                  /* this fact....                     JPM  */                                                                                                        if ( !PORT_NULL(neg_pwr) ) {            OUTPUT(neg_pwr) = -i_neg_pwr;                                                                     PARTIAL(neg_pwr,in) = -pi_neg_pvin;                                                               PARTIAL(neg_pwr,out) = -pi_neg_pvout;			if(!PORT_NULL(pos_pwr)){            	PARTIAL(neg_pwr,pos_pwr) = -pi_neg_pvpos;			}            PARTIAL(neg_pwr,neg_pwr) = -pi_neg_pvneg;        	PARTIAL(out,neg_pwr) = -pi_out_pneg_pwr;          }        if ( !PORT_NULL(pos_pwr) ) {            OUTPUT(pos_pwr) = -i_pos_pwr;            PARTIAL(pos_pwr,in) = -pi_pos_pvin;            PARTIAL(pos_pwr,out) = -pi_pos_pvout;            PARTIAL(pos_pwr,pos_pwr) = -pi_pos_pvpos;        	if ( !PORT_NULL(neg_pwr) ) {            	PARTIAL(pos_pwr,neg_pwr) = -pi_pos_pvneg;			}        	PARTIAL(out,pos_pwr) = -pi_out_ppos_pwr;          }    }    else {                        /* AC Analysis */        ac_gain.real = -pi_out_pvin;        ac_gain.imag= 0.0;        AC_GAIN(out,in) = ac_gain;        ac_gain.real = -pi_out_pvout;        ac_gain.imag= 0.0;        AC_GAIN(out,out) = ac_gain;        if ( !PORT_NULL(neg_pwr) ) {            ac_gain.real = -pi_neg_pvin;            ac_gain.imag= 0.0;            AC_GAIN(neg_pwr,in) = ac_gain;            ac_gain.real = -pi_out_pneg_pwr;            ac_gain.imag= 0.0;            AC_GAIN(out,neg_pwr) = ac_gain;            ac_gain.real = -pi_neg_pvout;            ac_gain.imag= 0.0;            AC_GAIN(neg_pwr,out) = ac_gain;                ac_gain.real = -pi_neg_pvpos;            ac_gain.imag= 0.0;            AC_GAIN(neg_pwr,pos_pwr) = ac_gain;            ac_gain.real = -pi_neg_pvneg;            ac_gain.imag= 0.0;            AC_GAIN(neg_pwr,neg_pwr) = ac_gain;        }        if ( !PORT_NULL(pos_pwr) ) {            ac_gain.real = -pi_pos_pvin;            ac_gain.imag= 0.0;            AC_GAIN(pos_pwr,in) = ac_gain;            ac_gain.real = -pi_out_ppos_pwr;            ac_gain.imag= 0.0;            AC_GAIN(out,pos_pwr) = ac_gain;            ac_gain.real = -pi_pos_pvout;            ac_gain.imag= 0.0;            AC_GAIN(pos_pwr,out) = ac_gain;            ac_gain.real = -pi_pos_pvpos;            ac_gain.imag= 0.0;            AC_GAIN(pos_pwr,pos_pwr) = ac_gain;                ac_gain.real = -pi_pos_pvneg;            ac_gain.imag= 0.0;            AC_GAIN(pos_pwr,neg_pwr) = ac_gain;        }    }}

⌨️ 快捷键说明

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