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

📄 cm.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ===========================================================================FILE    CM.cMEMBER OF process XSPICECopyright 1991Georgia Tech Research CorporationAtlanta, Georgia 30332All Rights ReservedPROJECT A-8503AUTHORS    9/12/91  Bill KuhnMODIFICATIONS    <date> <person name> <nature of modifications>SUMMARY    This file contains functions callable from user code models.INTERFACES    cm_analog_alloc()    cm_analog_get_ptr()    cm_analog_integrate()    cm_analog_converge()    cm_analog_set_temp_bkpt()    cm_analog_set_perm_bkpt()    cm_analog_ramp_factor()    cm_analog_not_converged()    cm_analog_auto_partial()    cm_message_get_errmsg()    cm_message_send()REFERENCED FILES    None.NON-STANDARD FEATURES    None.=========================================================================== */#include "ngspice.h"#include "cm.h"#include "mif.h"#include "cktdefs.h"//#include "util.h"static void cm_static_integrate(int byte_index,                                double integrand,                                double *integral,                                double *partial);/*cm_analog_alloc()This function is called from code model C functions to allocatestate storage for a particular instance.  It computes the numberof doubles that need to be allocated in SPICE's state storagevectors from the number of bytes specified in it's argument andthen allocates space for the states.  An index into the SPICEstate-vectors is stored in the instance's data structure alongwith a ``tag'' variable supplied by the caller so that the locationof the state storage area can be found by cm_analog_get_ptr().*/void *cm_analog_alloc(    int tag,            /* The user-specified tag for this block of memory */    int bytes)          /* The number of bytes to allocate */{    MIFinstance *here;    CKTcircuit  *ckt;    Mif_State_t *state;    int         doubles_needed;    int         i;    /* Get the address of the ckt and instance structs from g_mif_info */    here = g_mif_info.instance;    ckt  = g_mif_info.ckt;    /* Scan states in instance struct and see if tag has already been used */    for(i = 0; i < here->num_state; i++) {        if(tag == here->state[i].tag) {            g_mif_info.errmsg = "ERROR - cm_analog_alloc() - Tag already used in previous call\n";            return(NULL);        }    }    /* Compute number of doubles needed and allocate space in ckt->CKTstates[i] */    doubles_needed = bytes / sizeof(double) + 1;    /* Allocate space in instance struct for this state descriptor */    if(here->num_state == 0) {        here->num_state = 1;        here->state = (void *) MALLOC(sizeof(Mif_State_t));    }    else {        here->num_state++;        here->state = (void *) REALLOC(here->state,                                       here->num_state * sizeof(Mif_State_t));    }    /* Fill in the members of the state descriptor struct */    state = &(here->state[here->num_state - 1]);    state->tag = tag;    state->index = ckt->CKTnumStates;    state->doubles = doubles_needed;    state->bytes = bytes;    /* Add the states to the ckt->CKTstates vectors */    ckt->CKTnumStates += doubles_needed;    for(i=0;i<=ckt->CKTmaxOrder+1;i++) {        if(ckt->CKTnumStates == doubles_needed)            ckt->CKTstates[i] = (double *) MALLOC(ckt->CKTnumStates * sizeof(double));        else            ckt->CKTstates[i] = (double *) REALLOC(ckt->CKTstates[i],                                            ckt->CKTnumStates * sizeof(double));    }    /* Return pointer to the allocated space in state 0 */    return( (void *) (ckt->CKTstates[0] + (ckt->CKTnumStates - doubles_needed)));}/*cm_analog_get_ptr()This function is called from code model C functions to return apointer to state storage allocated with cm_analog_alloc().  A tagspecified in its argument list is used to locate the state inquestion.  A second argument specifies whether the desired stateis for the current timestep or from a preceding timestep.  Thelocation of the state in memory is then computed and returned.*/void *cm_analog_get_ptr(    int tag,            /* The user-specified tag for this block of memory */    int timepoint)      /* The timepoint of interest - 0=current 1=previous */{    MIFinstance *here;    CKTcircuit  *ckt;    Mif_State_t *state=NULL;    Mif_Boolean_t  got_tag;    int         i;    /* Get the address of the ckt and instance structs from g_mif_info */    here = g_mif_info.instance;    ckt  = g_mif_info.ckt;    /* Scan states in instance struct and see if tag exists */    for(got_tag = MIF_FALSE, i = 0; i < here->num_state; i++) {        if(tag == here->state[i].tag) {            state = &(here->state[i]);            got_tag = MIF_TRUE;            break;        }    }    /* Return error if tag not found */    if(! got_tag) {        g_mif_info.errmsg = "ERROR - cm_analog_get_ptr() - Bad tag\n";        return(NULL);    }    /* Return error if timepoint is not 0 or 1 */    if((timepoint < 0) || (timepoint > 1)) {        g_mif_info.errmsg = "ERROR - cm_analog_get_ptr() - Bad timepoint\n";        return(NULL);    }    /* Return address of requested state in ckt->CKTstates[timepoint] vector */    return( (void *) (ckt->CKTstates[timepoint] + state->index) );}/*cm_analog_integrate()This function performs a numerical integration on the statesupplied in its argument list according to the integrand alsosupplied in the argument list.  The next value of the integraland the partial derivative with respect to the integrand input isreturned.  The integral argument must be a pointer to memorypreviously allocated through a call to cm_analog_alloc().  If this isthe first call to cm_analog_integrate(), information is entered into theinstance structure to mark that the integral should be processedby MIFtrunc and MIFconvTest.*/int  cm_analog_integrate(    double integrand,      /* The integrand */    double *integral,      /* The current and returned value of integral */    double *partial)       /* The partial derivative of integral wrt integrand */{    MIFinstance *here;    CKTcircuit  *ckt;    Mif_Intgr_t  *intgr;    Mif_Boolean_t got_index;    char        *char_state0;    char        *char_state;    int         byte_index;    int         i;    /* Get the address of the ckt and instance structs from g_mif_info */    here = g_mif_info.instance;    ckt  = g_mif_info.ckt;    /* Check to be sure we're in transient analysis */    if(g_mif_info.circuit.anal_type != MIF_TRAN) {        g_mif_info.errmsg =        "ERROR - cm_analog_integrate() - Called in non-transient analysis\n";        *partial  = 0.0;        return(MIF_ERROR);    }    /* Preliminary check to be sure argument was allocated by cm_analog_alloc() */    if(ckt->CKTnumStates <= 0) {        g_mif_info.errmsg =        "ERROR - cm_analog_integrate() - Integral must be memory allocated by cm_analog_alloc()\n";        *partial  = 0.0;        return(MIF_ERROR);    }    /* Compute byte offset from start of state0 vector */    char_state0 = (char *) ckt->CKTstate0;    char_state  = (char *) integral;    byte_index  = char_state - char_state0;    /* Check to be sure argument address is in range of state0 vector */    if((byte_index < 0) ||        (byte_index > ((ckt->CKTnumStates - 1) * sizeof(double)) ) ) {        g_mif_info.errmsg =        "ERROR - cm_analog_integrate() - Argument must be in state vector 0\n";        *partial  = 0.0;        return(MIF_ERROR);    }    /* Scan the intgr array in the instance struct to see if already exists */    for(got_index = MIF_FALSE, i = 0; i < here->num_intgr; i++) {        if(here->intgr[i].byte_index == byte_index) {            got_index = MIF_TRUE;        }    }    /* Report error if not found and this is not the first load pass in tran analysis */    if((! got_index) && (! g_mif_info.circuit.anal_init)) {        g_mif_info.errmsg =        "ERROR - cm_analog_integrate() - New integral and not initialization pass\n";        *partial  = 0.0;        return(MIF_ERROR);    }    /* If new integral state, allocate space in instance */    /* struct for this intgr descriptor and register it with */    /* the cm_analog_converge() function */    if(! got_index) {        if(here->num_intgr == 0) {            here->num_intgr = 1;            here->intgr = (void *) MALLOC(sizeof(Mif_Intgr_t));        }        else {            here->num_intgr++;            here->intgr = (void *) REALLOC(here->intgr,                                           here->num_intgr * sizeof(Mif_Intgr_t));        }        intgr = &(here->intgr[here->num_intgr - 1]);        intgr->byte_index = byte_index;        if(cm_analog_converge(integral)) {            printf("%s\n",g_mif_info.errmsg);            g_mif_info.errmsg = "ERROR - cm_analog_integrate() - Failure in cm_analog_converge() call\n";            return(MIF_ERROR);        }    }    /* Compute the new integral and the partial */    cm_static_integrate(byte_index, integrand, integral, partial);    return(MIF_OK);}/*cm_analog_converge()This function registers a state variable allocated withcm_analog_alloc() to be subjected to a convergence test at the end ofeach iteration.  The state variable must be a double. Information is entered into the instance structure to mark thatthe state variable should be processed by MIFconvTest.*/int  cm_analog_converge(    double *state)       /* The state to be converged */{    MIFinstance *here;    CKTcircuit  *ckt;    Mif_Conv_t  *conv;    char        *char_state0;    char        *char_state;    int         byte_index;    int         i;    /* Get the address of the ckt and instance structs from g_mif_info */    here = g_mif_info.instance;    ckt  = g_mif_info.ckt;    /* Preliminary check to be sure argument was allocated by cm_analog_alloc() */    if(ckt->CKTnumStates <= 0) {        g_mif_info.errmsg =        "ERROR - cm_analog_converge() - Argument must be memory allocated by cm_analog_alloc()\n";        return(MIF_ERROR);    }    /* Compute byte offset from start of state0 vector */    char_state0 = (char *) ckt->CKTstate0;    char_state  = (char *) state;    byte_index  = char_state - char_state0;    /* Check to be sure argument address is in range of state0 vector */    if((byte_index < 0) ||

⌨️ 快捷键说明

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