📄 mifload.c
字号:
/*============================================================================FILE MIFload.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 the driver function for calling code model evaluation functions. This is one of the most important, complex, and often called functions in the model interface package. It iterates through all models and all instances of a specified code model device type, fills in the inputs for the model, calls the model, and then uses the outputs and partials returned by the model to load the matrix.INTERFACES MIFload()REFERENCED FILES None.NON-STANDARD FEATURES None.============================================================================*//* #include "prefix.h" */#include "ngspice.h"#include <stdio.h>#include <math.h>#include "cktdefs.h"#include "devdefs.h"#include "sperror.h"#include "mifproto.h"#include "mifparse.h"#include "mifdefs.h"#include "mifcmdat.h"#include "mif.h"#include "enh.h"#include "cm.h"/* #include "suffix.h" */extern SPICEdev **DEVices; /* info about all device types */static void MIFauto_partial( MIFinstance *here, void (*cm_func)(), Mif_Private_t *cm_data);/*MIFloadThis function is called by the CKTload() driver function to callthe C function for each instance of a code model type. It loopsthrough all models of that type and all instances of each model.For each instance, it prepares the structure that is passed tothe code model by filling it with the input values for thatinstance. The code model's C function is then called, and theoutputs and partial derivatives computed by the C function areused to fill the matrix for the next solution attempt.*/intMIFload( GENmodel *inModel, /* The head of the model list */ CKTcircuit *ckt) /* The circuit structure */{ MIFmodel *model; MIFinstance *here; Mif_Private_t cm_data; /* data to be passed to/from code model */ Mif_Port_Type_t type; Mif_Port_Data_t *fast; Mif_Smp_Ptr_t *smp_data_out; Mif_Port_Ptr_t *smp_ptr; Mif_Port_Type_t in_type; Mif_Port_Type_t out_type; Mif_Boolean_t is_input; Mif_Boolean_t is_output; Mif_Cntl_Src_Type_t cntl_src_type; Mif_Analysis_t anal_type; Mif_Complex_t czero; Mif_Complex_t ac_gain; int mod_type; int num_conn; int num_port; int num_port_k; int i; int j; int k; int l; /*int tag;*/ double *rhs; double *rhsOld; double partial; double temp; double *double_ptr0; double *double_ptr1; /*double *input;*/ /* double *oldinput;*/ char *byte_ptr0; char *byte_ptr1; double last_input; double conv_limit; double cntl_input; Evt_Node_Data_t *node_data; /* Prepare a zero complex number for AC gain initializations */ czero.real = 0.0; czero.imag = 0.0; /* Setup for access into MIF specific model data */ model = (MIFmodel *) inModel; mod_type = model->MIFmodType; /* Setup pointers for fast access to rhs and rhsOld elements of ckt struct */ rhs = ckt->CKTrhs; rhsOld = ckt->CKTrhsOld; node_data = ckt->evt->data.node; /* *********************************************************************** */ /* Setup the circuit data in the structure to be passed to the code models */ /* *********************************************************************** */ /* anal_init is set if this is the first iteration at any step in */ /* an analysis */ if(!(ckt->CKTmode & MODEINITFLOAT)) g_mif_info.circuit.anal_init = MIF_TRUE; cm_data.circuit.anal_init = g_mif_info.circuit.anal_init; /* anal_type is determined by CKTload */ anal_type = g_mif_info.circuit.anal_type; cm_data.circuit.anal_type = anal_type; /* get the analysis freq from the ckt struct if this is an AC analysis */ /* otherwise, set the freq to zero */ if(anal_type == MIF_AC) cm_data.circuit.frequency = ckt->CKTomega; else cm_data.circuit.frequency = 0.0; /* get the analysis times from the ckt struct if this is a transient analysis */ /* otherwise, set the times to zero */ if(anal_type == MIF_TRAN) { cm_data.circuit.time = ckt->CKTtime; cm_data.circuit.t[0] = ckt->CKTtime; for(i = 1; i < 8; i++) { cm_data.circuit.t[i] = cm_data.circuit.t[i-1] - ckt->CKTdeltaOld[i-1]; if(cm_data.circuit.t[i] < 0.0) cm_data.circuit.t[i] = 0.0; } } else { cm_data.circuit.time = 0.0; for(i = 0; i < 8; i++) { cm_data.circuit.t[i] = 0.0; } } cm_data.circuit.call_type = MIF_ANALOG; cm_data.circuit.temperature = ckt->CKTtemp - 273.15; g_mif_info.circuit.call_type = MIF_ANALOG; g_mif_info.ckt = ckt; /* ***************************************************************** */ /* loop through all models of this type */ /* ***************************************************************** */ for( ; model != NULL; model = model->MIFnextModel) { /* If not an analog or hybrid model, continue to next */ if(! model->analog) continue; /* ***************************************************************** */ /* loop through all instances of this model */ /* ***************************************************************** */ for(here = model->MIFinstances; here != NULL; here = here->MIFnextInstance) { /* If not an analog or hybrid instance, continue to next */ if(! here->analog) continue; /* ***************************************************************** */ /* Prepare the data needed by the cm_.. functions */ /* ***************************************************************** */ g_mif_info.instance = here; g_mif_info.errmsg = ""; if(here->initialized) { cm_data.circuit.init = MIF_FALSE; g_mif_info.circuit.init = MIF_FALSE; } else { cm_data.circuit.init = MIF_TRUE; g_mif_info.circuit.init = MIF_TRUE; } /* ***************************************************************** */ /* if tran analysis and anal_init is true, copy state 1 to state 0 */ /* Otherwise the data in state 0 would be invalid */ /* ***************************************************************** */ if((anal_type == MIF_TRAN) && g_mif_info.circuit.anal_init) { for(i = 0; i < here->num_state; i++) { double_ptr0 = ckt->CKTstate0 + here->state[i].index; double_ptr1 = ckt->CKTstate1 + here->state[i].index; byte_ptr0 = (char *) double_ptr0; byte_ptr1 = (char *) double_ptr1; for(j = 0; j < here->state[i].bytes; j++) byte_ptr0[j] = byte_ptr1[j]; } } /* ***************************************************************** */ /* If not AC analysis, loop through all connections on this instance */ /* and load the input values for each input port of each connection */ /* ***************************************************************** */ num_conn = here->num_conn; for(i = 0; i < num_conn; i++) { /* If AC analysis, skip getting input values. The input values */ /* should stay the same as they were at the last iteration of */ /* the operating point analysis */ if(anal_type == MIF_AC) break; /* if the connection is null, skip to next connection */ if(here->conn[i]->is_null) continue; /* if this connection is not an input, skip to next connection */ if(! here->conn[i]->is_input) continue; /* Get number of ports on this connection */ num_port = here->conn[i]->size; /* loop through all ports on this connection */ for(j = 0; j < num_port; j++) { /*setup a pointer for fast access to port data */ fast = here->conn[i]->port[j];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -