Browse Source
evtshared.c, prepare node data for transfer via shared ngspice interface
pre-master-46
evtshared.c, prepare node data for transfer via shared ngspice interface
pre-master-46
committed by
Holger Vogt
3 changed files with 244 additions and 1 deletions
@ -0,0 +1,241 @@ |
|||||
|
/*============================================================================ |
||||
|
FILE EVTshared.c |
||||
|
|
||||
|
MEMBER OF process XSPICE |
||||
|
|
||||
|
This code is in the public domain |
||||
|
|
||||
|
AUTHORS |
||||
|
|
||||
|
5/12/17 Holger Vogt |
||||
|
|
||||
|
MODIFICATIONS |
||||
|
|
||||
|
|
||||
|
|
||||
|
SUMMARY |
||||
|
|
||||
|
This file function to prepare event node data for transfer over the |
||||
|
shared ngspice interface. |
||||
|
|
||||
|
INTERFACES |
||||
|
|
||||
|
void EVTprint(wordlist *wl) |
||||
|
|
||||
|
REFERENCED FILES |
||||
|
|
||||
|
None. |
||||
|
|
||||
|
NON-STANDARD FEATURES |
||||
|
|
||||
|
None. |
||||
|
|
||||
|
============================================================================*/ |
||||
|
|
||||
|
#include "ngspice/ngspice.h" |
||||
|
|
||||
|
#include "ngspice/cpstd.h" |
||||
|
#include "ngspice/cpextern.h" |
||||
|
#include "ngspice/fteext.h" |
||||
|
|
||||
|
#include "ngspice/mif.h" |
||||
|
#include "ngspice/evt.h" |
||||
|
#include "ngspice/evtudn.h" |
||||
|
|
||||
|
#include "ngspice/evtproto.h" |
||||
|
|
||||
|
#include <time.h> |
||||
|
|
||||
|
|
||||
|
static int get_index(char *node_name); |
||||
|
|
||||
|
struct evt_data { |
||||
|
Mif_Boolean_t dcop; |
||||
|
double step; |
||||
|
char *node_value; |
||||
|
}; |
||||
|
|
||||
|
struct evt_shared_data { |
||||
|
struct evt_data *evt_dect; |
||||
|
int num_steps; |
||||
|
}; |
||||
|
|
||||
|
struct evt_data *return_node; |
||||
|
struct evt_shared_data *return_all; |
||||
|
|
||||
|
|
||||
|
struct evt_shared_data |
||||
|
*EVTshareddata( |
||||
|
char *node_name) /* The command line called by ngGet_EVT_Info(char* nodename) */ |
||||
|
{ |
||||
|
|
||||
|
int i; |
||||
|
int nodes; |
||||
|
|
||||
|
int node_index; |
||||
|
int udn_index; |
||||
|
Evt_Node_t *node_data, *count_data; |
||||
|
char *node_value; |
||||
|
|
||||
|
CKTcircuit *ckt; |
||||
|
|
||||
|
Evt_Node_Info_t **node_table; |
||||
|
|
||||
|
Mif_Boolean_t more; |
||||
|
Mif_Boolean_t dcop; |
||||
|
|
||||
|
double step = 0.0; |
||||
|
double next_step; |
||||
|
double this_step; |
||||
|
|
||||
|
char *value; |
||||
|
|
||||
|
/* Get needed pointers */ |
||||
|
ckt = g_mif_info.ckt; |
||||
|
if (!ckt) { |
||||
|
fprintf(cp_err, "Error: no circuit loaded.\n"); |
||||
|
return NULL; |
||||
|
} |
||||
|
node_table = ckt->evt->info.node_table; |
||||
|
|
||||
|
/* Get data for the node */ |
||||
|
node_index = get_index(node_name); |
||||
|
if(node_index < 0) { |
||||
|
fprintf(cp_err, "ERROR - Node %s is not an event node.\n", node_name); |
||||
|
return NULL; |
||||
|
} |
||||
|
udn_index = node_table[node_index]->udn_index; |
||||
|
if (ckt->evt->data.node) |
||||
|
node_data = ckt->evt->data.node->head[node_index]; |
||||
|
else { |
||||
|
fprintf(cp_err, "ERROR - No node data: simulation not yet run?\n"); |
||||
|
return NULL; |
||||
|
} |
||||
|
node_value = ""; |
||||
|
|
||||
|
/* Scan the node data and determine if the first vector */ |
||||
|
/* is for a DCOP analysis or the first step in a swept DC */ |
||||
|
/* or transient analysis. Also, determine if there is */ |
||||
|
/* more data following it and if so, what the next step */ |
||||
|
/* is. */ |
||||
|
more = MIF_FALSE; |
||||
|
dcop = MIF_FALSE; |
||||
|
next_step = 1e30; |
||||
|
|
||||
|
if(node_data->op) |
||||
|
dcop = MIF_TRUE; |
||||
|
else |
||||
|
step = node_data->step; |
||||
|
(*(g_evt_udn_info[udn_index]->print_val)) |
||||
|
(node_data->node_value, "all", &value); |
||||
|
node_value = value; |
||||
|
node_data = node_data->next; |
||||
|
if(node_data) { |
||||
|
more = MIF_TRUE; |
||||
|
if(node_data->step < next_step) |
||||
|
next_step = node_data->step; |
||||
|
} |
||||
|
|
||||
|
/* Count the neumber of node data */ |
||||
|
count_data = node_data; |
||||
|
nodes = 0; |
||||
|
while (count_data) { |
||||
|
nodes++; |
||||
|
count_data = count_data->next; |
||||
|
} |
||||
|
|
||||
|
/* Store the data */ |
||||
|
return_node = TMALLOC(struct evt_data, nodes); |
||||
|
return_node[0].dcop = dcop; |
||||
|
return_node[0].node_value = copy(value); |
||||
|
return_node[0].step = step; |
||||
|
|
||||
|
/* While there is more data, get the next values and print */ |
||||
|
i = 1; |
||||
|
while(more) { |
||||
|
|
||||
|
more = MIF_FALSE; |
||||
|
this_step = next_step; |
||||
|
next_step = 1e30; |
||||
|
|
||||
|
if(node_data) { |
||||
|
if(node_data->step == this_step) { |
||||
|
(*(g_evt_udn_info[udn_index]->print_val)) |
||||
|
(node_data->node_value, "all", &value); |
||||
|
node_value = value; |
||||
|
node_data = node_data->next; |
||||
|
} |
||||
|
if(node_data) { |
||||
|
more = MIF_TRUE; |
||||
|
if(node_data->step < next_step) |
||||
|
next_step = node_data->step; |
||||
|
} |
||||
|
|
||||
|
} /* end if node_data not NULL */ |
||||
|
|
||||
|
return_node[i].dcop = dcop; |
||||
|
return_node[i].node_value = copy(value); |
||||
|
return_node[i].step = this_step; |
||||
|
i++; |
||||
|
} /* end while there is more data */ |
||||
|
return_all = TMALLOC(struct evt_shared_data, 1); |
||||
|
return_all->evt_dect = return_node; |
||||
|
return_all->num_steps = i; |
||||
|
return return_all; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
/* |
||||
|
get_index |
||||
|
|
||||
|
This function determines the index of a specified event-driven node. |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
static int get_index( |
||||
|
char *node_name /* The name of the node to search for */ |
||||
|
) |
||||
|
{ |
||||
|
|
||||
|
/* Get the event-driven node index for the specified name */ |
||||
|
|
||||
|
int index; |
||||
|
|
||||
|
Mif_Boolean_t found; |
||||
|
Evt_Node_Info_t *node; |
||||
|
CKTcircuit *ckt; |
||||
|
|
||||
|
|
||||
|
/* Scan list of nodes in event structure to see if there */ |
||||
|
|
||||
|
found = MIF_FALSE; |
||||
|
index = 0; |
||||
|
|
||||
|
ckt = g_mif_info.ckt; |
||||
|
if (!ckt) { |
||||
|
fprintf(cp_err, "Error: no circuit loaded.\n"); |
||||
|
return(-1); |
||||
|
} |
||||
|
node = ckt->evt->info.node_list; |
||||
|
|
||||
|
while(node) { |
||||
|
if(strcmp(node_name, node->name) == 0) { |
||||
|
found = MIF_TRUE; |
||||
|
break; |
||||
|
} |
||||
|
else { |
||||
|
index++; |
||||
|
node = node->next; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* Return the index or -1 if not found */ |
||||
|
if(! found) |
||||
|
return(-1); |
||||
|
else |
||||
|
return(index); |
||||
|
} |
||||
|
|
||||
|
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue