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

📄 cfunc.mod

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 MOD
字号:
/* $Id: cfunc.mod,v 1.2 2003/08/05 17:20:33 pnenzi Exp $ *//*.......1.........2.........3.........4.........5.........6.........7.........8================================================================================FILE hyst/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 hyst code model.INTERFACES           FILE                 ROUTINE CALLED         CMutil.c             void cm_smooth_corner();                                  CM.c                 void *cm_analog_alloc()                         void *cm_analog_get_ptr()REFERENCED FILES    Inputs from and outputs to ARGS structure.                     NON-STANDARD FEATURES    NONE===============================================================================*//*=== INCLUDE FILES ====================*/#include "cm_hyst.h"			                                      /*=== CONSTANTS ========================*//*=== MACROS ===========================*/  /*=== LOCAL VARIABLES & TYPEDEFS =======*/                                        /*=== FUNCTION PROTOTYPE DEFINITIONS ===*/                   /*==============================================================================FUNCTION void hyst()AUTHORS                           2 Oct 1991     Jeffrey P. MurrayMODIFICATIONS       NONESUMMARY    This function implements the hyst code model.INTERFACES           FILE                 ROUTINE CALLED         CMutil.c             void cm_smooth_corner();     CM.c                 void *cm_analog_alloc()                         void *cm_analog_get_ptr()RETURNED VALUE        Returns inputs and outputs via ARGS structure.GLOBAL VARIABLES        NONENON-STANDARD FEATURES    NONE==============================================================================*//*=== CM_HYST ROUTINE ===*//**************************************************************************                 BEHAVIOR OF HYSTERESIS:                                **        out               hyst         hyst                             **         ^             ____/\_____  ____/\_____                         **         |            /           \/           \                        **         |        x_fall_linear                  x_rise_zero            **  out_upper_limit- -  *----<-------------<------*------->               **         |           /|           /|           /|                       **         |          /            /in_high     /                         **         |         /  |         /  |         /  |                       **         |        /            /          __/                           **         |      |/_   |       /    |       /|   |                       **         |      /            /            /                             **         |     /      |     /      |     /      |                       **  <------O----/------------/------------/-----------------------> in    **         | | /          | /          | /                                **         |  /            /            /                                 **  <--------*------->----|---->-------* - - - - out_lower_limit          **       x_fall_zero    in_low     x_rise_linear                          **         V                                                              **                                                                        **  input_domain defines "in" increment below & above the "*" points      **     shown, within which smoothing of the d(out)/d(in) values           **     occurs...this prevents abrupt changes in d(out)/d(in) which        **     could prevent the simulator from reaching convergence during       **     a transient or DC analysis.                                        **                                                                        ***************************************************************************//**************************************************************************//*  Usage of cm_smooth_corner:                                                 *//*                                                                        *//*  void cm_smooth_corner(double x_input, double x_center, double y_center,    *//*                   double domain, double lower_slope,                   *//*                   double upper_slope,double *y_output, double *dy_dx)  *//*                                                                        *//**************************************************************************/                void cm_hyst(ARGS)  /* structure holding parms,                                        inputs, outputs, etc.     */{    double        in, /* input to hysteresis block      */                 out, /* output from hysteresis block   */              in_low, /* lower input value for hyst=0 at which                          the transfer curve changes from constant                          to linear                               */             in_high, /* upper input value for hyst=0 at which                          the transfer curve changes from constant                          to linear                               */                hyst, /* the hysteresis value (see above diagram)    */     out_lower_limit, /* the minimum output value from the block */     out_upper_limit, /* the maximum output value from the block */        input_domain, /* the delta value of the input above and                         below in_low and in_high within which                         smoothing will be applied to the output                          in order to maintain continuous first partial                         derivatives.                                  */               slope, /* calculated rise and fall slope for the block  */            pout_pin, /* partial derivative of output w.r.t. input */       x_rise_linear, /* = in_low + hyst                           */         x_rise_zero, /* = in_high + hyst                          */       x_fall_linear, /* = in_high - hyst                          */         x_fall_zero; /* = in_low - hyst                           */    Boolean_t     *hyst_state, /* TRUE => input is on lower leg of                                   hysteresis curve, between -infinity                                  and in_high + hyst.                                  FALSE => input is on upper leg                                  of hysteresis curve, between                                   in_low - hyst and +infinity      */              *old_hyst_state; /* previous value of *hyst_state    */    Mif_Complex_t     ac_gain; /* AC gain */                                                       /** Retrieve frequently used parameters... **/    in_low = PARAM(in_low);    in_high = PARAM(in_high);    hyst = PARAM(hyst);    out_lower_limit = PARAM(out_lower_limit);    out_upper_limit = PARAM(out_upper_limit);                             input_domain = PARAM(input_domain);                            /** Calculate Hysteresis Linear Region Slopes & Derived Values **/    /* Define slope of rise and fall lines when not being smoothed */    slope = (out_upper_limit - out_lower_limit)/(in_high - in_low);      x_rise_linear = in_low + hyst;    /* Breakpoint - x rising to                                              linear region */    x_rise_zero = in_high + hyst;     /* Breakpoint - x rising to                                              zero-slope (out_upper_limit) */    x_fall_linear = in_high - hyst;   /* Breakpoint - x falling to                                              linear region */    x_fall_zero = in_low - hyst;      /* Breakpoint - x falling to                                              zero-slope (out_lower_limit) */                                            if (PARAM(fraction) == MIF_TRUE)        /* Set range to absolute value */        input_domain = input_domain * (in_high - in_low);                                              /** Retrieve frequently used inputs... **/    in = INPUT(in);    /** Test for INIT; if so, allocate storage, otherwise, retrieve                               previous timepoint value for output...     **/    if (INIT==1) {  /* First pass...allocate storage for previous state.   */                    /* Also, calculate roughly where the current output    */                    /* will be and use this value to define current state. */        hyst_state = cm_analog_alloc(TRUE,sizeof(Boolean_t));           old_hyst_state = cm_analog_get_ptr(TRUE,1);        if (in < x_rise_zero + input_domain) { /* Set state to X_RISING */            *old_hyst_state = X_RISING;           }        else {                                     *old_hyst_state = X_FALLING;          }    }    else {          /* Allocation not necessary...retrieve previous values */        hyst_state = cm_analog_get_ptr(TRUE,0);  /* Set out pointer to current                                                             time storage */            old_hyst_state = cm_analog_get_ptr(TRUE,1);  /* Set old-output-state pointer                                                    to previous time storage */        }                       /** Set *hyst_out = *old_hyst_out, unless changed below...          we don't need the last iteration value of *hyst_state.  **/    *hyst_state = *old_hyst_state;    /*** Calculate value of hyst_state, pout_pin.... ***/    if (*old_hyst_state == X_RISING) { /* Assume calculations on lower  */                                       /* hysteresis section (x rising) */        if ( in <= x_rise_linear - input_domain ) { /* Output @ lower limit */            out = out_lower_limit;            pout_pin = 0.0;        }        else {            if ( in <= x_rise_linear + input_domain ) { /* lower smoothing region */                cm_smooth_corner(in,x_rise_linear,out_lower_limit,input_domain,                             0.0,slope,&out,&pout_pin);            }            else {                if (in <= x_rise_zero - input_domain) { /* Rising linear region */                     out = (in - x_rise_linear)*slope + out_lower_limit;                    pout_pin = slope;                }                else {                    if (in <= x_rise_zero + input_domain) { /* Upper smoothing region */                         cm_smooth_corner(in,x_rise_zero,out_upper_limit,input_domain,                                    slope,0.0,&out,&pout_pin);                    }                    else { /* input has transitioned to X_FALLING region... */                        out = out_upper_limit;                        pout_pin = 0.0;                        *hyst_state = X_FALLING;                    }                }            }        }    }    else {    /* Assume calculations on upper hysteresis section (x falling) */        if ( in >= x_fall_linear + input_domain ) { /* Output @ upper limit */            out = out_upper_limit;            pout_pin = 0.0;        }        else {            if ( in >= x_fall_linear - input_domain ) { /* Upper smoothing region */                cm_smooth_corner(in,x_fall_linear,out_upper_limit,input_domain,                             slope,0.0,&out,&pout_pin);            }            else {                if (in >= x_fall_zero + input_domain) { /* Falling linear region */                     out = (in - x_fall_zero)*slope + out_lower_limit;                    pout_pin = slope;                }                else {                    if (in >= x_fall_zero - input_domain) { /* Lower smoothing region */                         cm_smooth_corner(in,x_fall_zero,out_lower_limit,input_domain,                                    0.0,slope,&out,&pout_pin);                    }                    else { /* input has transitioned to X_RISING region... */                        out = out_lower_limit;                        pout_pin = 0.0;                        *hyst_state = X_RISING;                    }                }            }        }    }    if (ANALYSIS != MIF_AC) {     /* DC & Transient Analyses */        OUTPUT(out) = out;                  PARTIAL(out,in) = pout_pin;     }    else {                        /* AC Analysis */        ac_gain.real = pout_pin;        ac_gain.imag= 0.0;        AC_GAIN(out,in) = ac_gain;    }}

⌨️ 快捷键说明

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