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

📄 cluster.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
字号:
/* Spice hooks */#include <ngspice.h>#ifdef CLUSTER#include <inpdefs.h>#include "cluster.h"#include <cktdefs.h>#include <gendefs.h>/* Misc stuff */#include <pthread.h>#include <string.h>/*Network stuff*/#include <arpa/inet.h>#include <netinet/in.h>#include <sys/socket.h>#include <netdb.h>#include <unistd.h>struct input_pipe {  /*the names of the local and remote nodes*/  char remote[32];  char local[32];  int fd;  FILE *stream;  /* the data recieved */  double time;  double data;  /*resistance of this link*/  double res;  /* The value controled */  double *currentPtr;  /*The output it is linked to*/  struct output_pipe *link;  struct input_pipe *next;};struct output_pipe {  int fd;  FILE *stream;  /*the names of the local and remote nodes*/  char local[32];  char remote[32];  /* The index of the local node value in the ckt->CKTrhsOld array */  int outIndex;  /*Last values sent*/  double time,data;  struct input_pipe *link;  struct output_pipe *next;};static double lastTimeSent=0;static int time_sock=0;static FILE *time_outfile=NULL;static FILE *time_infile=NULL;static struct input_pipe* input_pipes=NULL;static struct output_pipe* output_pipes=NULL;/* sets up deamon which waits for connections  *and sets up input pipes as it recieves them */static void *start_listener(void *);/* Setup the output pipes*/static int setup_output(CKTcircuit *ckt);static int setup_input(CKTcircuit *ckt);static int setup_time();int CLUsetup(CKTcircuit *ckt){  pthread_t tid;  struct input_pipe *curr;  int i, connections=0;  GENmodel *mod;  GENinstance *inst;  /* count the number of connections expected */  i = INPtypelook("Isource");  for(mod = (GENmodel *)ckt->CKThead[i];      mod != NULL;      mod = mod->GENnextModel)    for (inst = mod->GENinstances;	 inst != NULL; 	 inst = inst->GENnextInstance)       if(strncmp("ipcx",inst->GENname,4) == 0)	connections++;    /* allocate the input connections */  for(i=0;i<connections;i++) {    curr = (struct input_pipe *)tmalloc(sizeof(struct input_pipe));    if(input_pipes)      curr->next = input_pipes;    else      curr->next = NULL;    input_pipes = curr;  }  pthread_create(&tid,NULL,start_listener,(void *)&connections);  setup_output(ckt);  pthread_join(tid,NULL);  setup_input(ckt);  setup_time();  return 0;}#include "../devices/isrc/isrcdefs.h"/*Connect to remote machine and find the data*/static int setup_output(CKTcircuit *ckt){  int type;  GENmodel *mod;  GENinstance *inst;  char hostname[64];    lastTimeSent = 0;  type = INPtypelook("Isource");  for(mod = (GENmodel *)ckt->CKThead[type];      mod != NULL;      mod = mod->GENnextModel)    for (inst = mod->GENinstances;	 inst != NULL; 	 inst = inst->GENnextInstance)       if(strncmp("ipcx",inst->GENname,4) == 0){	ISRCinstance *isrc = (ISRCinstance *)inst;	CKTnode *node;	struct output_pipe *curr;	struct sockaddr_in address;	struct hostent *host=NULL;	int sock,nodeNum,i;	/*Create the struct*/	curr = (struct output_pipe *)tmalloc(sizeof(struct output_pipe));	if(output_pipes)	  curr->next = output_pipes;	else	  curr->next = NULL;	output_pipes = curr;	/* The node names */	strcpy(curr->local,CKTnodName(ckt,isrc->ISRCnegNode));/*weird*/	strcpy(curr->remote,isrc->ISRCname);		/* extract remote node number */	nodeNum = /*Xcoord*/(curr->remote[4] - '0') * CLUSTER_WIDTH 	  + /*Ycoord*/(curr->remote[9] - '0');	sprintf(hostname,"n%d."DOMAIN_NAME,nodeNum);	/* network stuff */	host = gethostbyname(hostname);	if(!host){	  printf("Host not found in setup_output\n");	  exit(0);	}		if((sock = socket(PF_INET,SOCK_STREAM,0)) < 0){	  printf("Socket open in setup_output\n");	  exit(0);	}		address.sin_family = AF_INET;	address.sin_port = htons(PORT);	memcpy(&address.sin_addr,host->h_addr_list[0],	       sizeof(address.sin_addr));	printf("connecting to %s ...... ",hostname);	fflush(stdout);	while(connect(sock,(struct sockaddr *)&address,sizeof(address))){	  usleep(500);/*wait for the sever to start*/	}	printf("connected\n");		curr->fd = sock;	/* send stuff */	/* buffer */	i = (strlen(curr->remote) + strlen(curr->local) + 2)*sizeof(char);	setsockopt(sock,SOL_SOCKET,SO_SNDBUF,&i,sizeof(i));	curr->stream = fdopen(curr->fd,"w");	fwrite(curr->remote,sizeof(char),strlen(curr->remote),curr->stream);	fputc('\0',curr->stream);	fwrite(curr->local,sizeof(char),strlen(curr->local),curr->stream);	fputc('\0',curr->stream);	fflush(curr->stream);	/* buffer, what is done per time point */	i = sizeof(double)*2;	setsockopt(sock,SOL_SOCKET,SO_SNDBUF,&i,sizeof(i));		/* find the index in ckt->rhsOld which contains the local node */	i = 0;	for(node = ckt->CKTnodes->next;node;node = node->next){	  i++;	  if(strcmp(node->name,curr->local)==0){	    curr->outIndex = i;	    goto next;	  }	}	printf("Local node %s not found\n",curr->local);	exit(0);      next:	      }  return 0;}/*Processes the connections recieved by start_listener*/static int setup_input(CKTcircuit *ckt){  int type;  GENmodel *mod;  GENinstance *inst;  struct input_pipe *input;  type = INPtypelook("Isource");    for(input = input_pipes;input;input = input->next){    int i;    input->stream = fdopen(input->fd,"r");    /*Get the local and remote node names*/    i=0;    do {      while(fread(&input->local[i],sizeof(char),1,input->stream) != 1);    }while(input->local[i++] != '\0');        i=0;    do {      while(fread(&input->remote[i],sizeof(char),1,input->stream) != 1);    }while(input->remote[i++] != '\0');    /* initilise */    input->time = -1;    /*Find the Isource to control*/    for(mod = (GENmodel *)ckt->CKThead[type];	mod != NULL;	mod = mod->GENnextModel)            for (inst = mod->GENinstances;	   inst != NULL; 	   inst = inst->GENnextInstance) 	if(strcmp(input->remote,&inst->GENname[11]) == 0){	  ISRCinstance *isrc = (ISRCinstance *)inst;	  input->res = isrc->ISRCdcValue;	  isrc->ISRCdcValue = 0;	  input->currentPtr = &isrc->ISRCdcValue;	  goto next;      }    /* We get here if no Isource matches */    printf("Current source %s not found\n",input->remote);    exit(0);      next:        /* Now find the corresponding output */    {      struct output_pipe *output;      for(output = output_pipes;output;output = output->next)	if(strcmp(&input->local[11],output->local)==0){	  input->link = output;	  output->link = input;	  goto next2;	}      printf("Parent to %s not found\n",&input->local[11]);      exit(0);    next2:      }   }  return 0;}/* This starts a server and waits for connections, number given by argument*/static void *start_listener(void *v){  int *connections = (int *)v;  int count=0;  struct sockaddr_in address;  int sock, conn,i;  size_t addrLength = sizeof(struct sockaddr_in);  struct input_pipe *curr;  if((sock = socket(PF_INET,SOCK_STREAM,0)) < 0){    printf("socket in start_listener\n");    exit(0);   }  /* Allow reuse of the socket */  i = 1;  setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));  /* port, inferface ..*/  address.sin_family = AF_INET;  address.sin_port = htons(PORT);  memset(&address.sin_addr,0,sizeof(address.sin_addr));  if(bind(sock, (struct sockaddr *)&address,sizeof(address))){    printf("bind in start_listener\n");    exit(0);   }  if(listen(sock,5)){    printf("listen in start_listener\n");    exit(0);  }    /* Loop till recieved all connections */  curr = input_pipes;  while (count < *connections){    if((conn = accept(sock, (struct sockaddr *)&address,&addrLength)) < 0){      printf("accept in start_listener\n");      exit(0);    }        curr->fd = conn;    /* will fill rest of structure later in setup_input*/    count ++;    curr = curr->next;  }  close(sock);  return NULL;}/*Writes data to remote computer*/int CLUoutput(CKTcircuit *ckt){  struct output_pipe *output;  lastTimeSent = ckt->CKTtime;  for(output = output_pipes;      output;      output = output->next){    output->time = ckt->CKTtime;    output->data = ckt->CKTrhsOld[output->outIndex];    fwrite(&output->time,sizeof(double),1,output->stream);    fwrite(&output->data,	   sizeof(double),1,output->stream);    fflush(output->stream);  }  return 0;}/*Maniputates the local circuit based on the links*/int CLUinput(CKTcircuit *ckt){  struct input_pipe *input;  double tmp;  for(input= input_pipes;input;input = input->next){    /*recieve data till we get a good time point*/    while (input->time < lastTimeSent){      while(fread(&input->time, sizeof(double), 1, input->stream) != 1){}      while(fread(&input->data, sizeof(double), 1, input->stream) != 1){}    }    tmp = (input->link->data - input->data) / input->res;    /*dampen out large currents*/    if(tmp > 0)	*input->currentPtr = 0.2 * (1 - exp(-tmp/0.2));    else	*input->currentPtr = -0.2 * (1 - exp(tmp/0.2));    /*GND is the posNode, local node is the negNode*/  }  return 0;}static int setup_time(){  struct sockaddr_in address;  struct hostent *host=NULL;  char *hostname = TIME_HOST;  int sock,i;  /* network stuff */  host = gethostbyname(hostname);  if(!host){    printf("Host not found in setup_time\n");    exit(0);  }  if((sock = socket(PF_INET,SOCK_STREAM,0)) < 0){    printf("Socket open in setup_time\n");    exit(0);  }  i = sizeof(double)*2;  setsockopt(sock,SOL_SOCKET,SO_SNDBUF ,&i,sizeof(i));   address.sin_family = AF_INET;  address.sin_port = htons(TIME_PORT);  memcpy(&address.sin_addr,host->h_addr_list[0],	 sizeof(address.sin_addr));  while(connect(sock,(struct sockaddr *)&address,sizeof(address))){    usleep(500);/*wait for the sever to start*/  }  time_sock=sock;  time_outfile=fdopen(sock,"w");  time_infile=fdopen(sock,"r");  return 0;}int CLUsync(double time,double *delta, int error){  double tmp;  if(error)    tmp = *delta * (-1);  else    tmp = *delta;  fwrite(&time,sizeof(double),1,time_outfile);  fwrite(&tmp,sizeof(double),1,time_outfile);  fflush(time_outfile);  while(fread(&tmp,sizeof(double),1,time_infile) != 1);  if(tmp < 0){    *delta = -tmp;    return 0;  } else {    *delta = tmp;    return 1;  }}#endif

⌨️ 快捷键说明

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