📄 evtbackup.c
字号:
/*============================================================================FILE EVTbackup.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 a function that resets the queues and data structures to their state at the new analog simulation time specified following the rejection of an analog timestep by the DCtran routine.INTERFACES void EVTbackup(CKTcircuit *ckt, double new_time)REFERENCED FILES None.NON-STANDARD FEATURES None.============================================================================*//*=== INCLUDE FILES ===*/#include <stdio.h>#include "ngspice.h"#include "cktdefs.h"//#include "util.h"#include "mif.h"#include "evt.h"#include "evtproto.h"/*=== FUNCTION PROTOTYPES ===*/static void EVTbackup_node_data(CKTcircuit *ckt, double new_time);static void EVTbackup_state_data(CKTcircuit *ckt, double new_time);static void EVTbackup_msg_data(CKTcircuit *ckt, double new_time);static void EVTbackup_inst_queue(CKTcircuit *ckt, double new_time);static void EVTbackup_output_queue(CKTcircuit *ckt, double new_time);/*EVTbackup()This function resets the queues and data structures to their stateat the new analog simulation time specified. The algorithms in this fileassume the following timestep coordination betweenanalog and event-driven algorithms: while(not end of analysis) { while (next event time <= next analog time) { do event solution with call_type = event_driven if any instance set analog breakpoint < next analog time set next analog time to breakpoint } do analog timestep solution with call_type = analog call all hybrid models with call_type = event_driven if(analog solution doesn't converge) Call EVTbackup else Call EVTaccept }*/void EVTbackup( CKTcircuit *ckt, /* the main circuit structure */ double new_time) /* the time to backup to */{ /* Backup the node data */ EVTbackup_node_data(ckt, new_time); /* Backup the state data */ EVTbackup_state_data(ckt, new_time); /* Backup the msg data */ EVTbackup_msg_data(ckt, new_time); /* Backup the inst queue */ EVTbackup_inst_queue(ckt, new_time); /* Backup the output queue */ EVTbackup_output_queue(ckt, new_time); /* Record statistics */ (ckt->evt->data.statistics->tran_time_backups)++;} /* EVTbackup *//*EVTbackup_node_data()Reset the node structure data.*/static void EVTbackup_node_data( CKTcircuit *ckt, /* the main circuit structure */ double new_time) /* the time to backup to */{ int i; int j; int num_modified; int node_index; Evt_Node_Info_t **node_table; Evt_Node_Data_t *node_data; Evt_Node_t **node_ptr; Evt_Node_t *node; Evt_Node_t *from_node; Evt_Node_t *to_node; Evt_Node_t *head; Evt_Node_t *tail; Evt_Node_t *free_head; /* Get pointers for quick access */ node_data = ckt->evt->data.node; node_table = ckt->evt->info.node_table; /* Loop through list of indexes modified since last accepted timepoint */ num_modified = node_data->num_modified; for(i = 0; i < num_modified; i++) { /* Get the needed node and udn indexes */ node_index = node_data->modified_index[i]; /* Scan data for this node from last_step to determine new setting */ /* for tail, and splice later data into the free list */ node_ptr = node_data->last_step[node_index]; node = *node_ptr; while(1) { if((node->next == NULL) || (node->next->step > new_time)) { /* Splice rest of list, if any, into free list */ head = node->next; if(head) { tail = *(node_data->tail[node_index]); free_head = node_data->free[node_index]; node_data->free[node_index] = head; tail->next = free_head; } /* Set the tail */ node_data->tail[node_index] = node_ptr; node->next = NULL; break; } node_ptr = &(node->next); node = node->next; } /* Copy data from the location at tail to rhs and rhsold */ from_node = *(node_data->tail[node_index]); to_node = &(node_data->rhs[node_index]); EVTnode_copy(ckt, node_index, from_node, &to_node); to_node = &(node_data->rhsold[node_index]); EVTnode_copy(ckt, node_index, from_node, &to_node); } /* end for number modified */ /* Update/compact the modified list */ for(i = 0, j = 0; i < num_modified; i++) { node_index = node_data->modified_index[i]; /* If nothing after last_step, remove this index from the modified list */ if((*(node_data->last_step[node_index]))->next == NULL) { node_data->modified[node_index] = MIF_FALSE; (node_data->num_modified)--; } /* else, keep the index */ else { node_data->modified_index[j] = node_data->modified_index[i]; j++; } }} /* EVTbackup_node_data *//*EVTbackup_state_data()Reset the state structure data.*/static void EVTbackup_state_data( CKTcircuit *ckt, /* the main circuit structure */ double new_time) /* the time to backup to */{ int i; int j; int num_modified; int inst_index; Evt_State_Data_t *state_data; Evt_State_t **state_ptr; Evt_State_t *state; Evt_State_t *head; Evt_State_t *tail; Evt_State_t *free_head; /* Get pointers for quick access */ state_data = ckt->evt->data.state; /* Loop through list of indexes modified since last accepted timepoint */ num_modified = state_data->num_modified; for(i = 0; i < num_modified; i++) { /* Get the inst index */ inst_index = state_data->modified_index[i]; /* Scan data for this inst from last_step to determine new setting */ /* for tail, and splice later data into the free list */ state_ptr = state_data->last_step[inst_index]; state = *state_ptr; while(1) { if((state->next == NULL) || (state->next->step > new_time)) { /* Splice rest of list, if any, into free list */ head = state->next; if(head) { tail = *(state_data->tail[inst_index]); free_head = state_data->free[inst_index]; state_data->free[inst_index] = head; tail->next = free_head; } /* Set the tail */ state_data->tail[inst_index] = state_ptr; state->next = NULL; break; } state_ptr = &(state->next); state = state->next; } } /* end for number modified */ /* Update/compact the modified list */ for(i = 0, j = 0; i < num_modified; i++) { inst_index = state_data->modified_index[i]; /* If nothing after last_step, remove this index from the modified list */ if((*(state_data->last_step[inst_index]))->next == NULL) { state_data->modified[inst_index] = MIF_FALSE; (state_data->num_modified)--; } /* else, keep the index */ else { state_data->modified_index[j] = state_data->modified_index[i]; j++; } }} /* EVTbackup_state_data *//*EVTbackup_msg_data()Backup the message data.*/static void EVTbackup_msg_data( CKTcircuit *ckt, /* the main circuit structure */ double new_time) /* the time to backup to */{ int i; int j; int num_modified; int port_index; Evt_Msg_Data_t *msg_data; Evt_Msg_t **msg_ptr; Evt_Msg_t *msg; Evt_Msg_t *head; Evt_Msg_t *tail; Evt_Msg_t *free_head; /* Get pointers for quick access */ msg_data = ckt->evt->data.msg;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -