circuit

See circuit.h   circuit.cpp

These files contain an implementation of simple circuits. There is a circuit class that contains a list of circuit elements (devices) and a list of connections (nodes). The class device is an abstract class. There two concrete classes based on device: resistor and current source.

circuit.h


#pragma once
#include <assert.h>
#include <string>
using namespace std;


class device {
public:
	string name;
	string *nodes;
	int *ndx;
	double x, y;
	double orientation;
	double value;
	device() { };
	device(int n);
	virtual ~device();
	virtual int getNodeCount() const = 0;
	virtual string getType() const = 0;
	virtual string getCode() const = 0;
	void parse(string tok[], int ntokens);
	void parse_value(string tok);
};

class Resistor: public device {
public:
	Resistor(): device(2) { }
	int getNodeCount() const { return 2; }
	string getType() const { return "resistor"; }
	string getCode() const { return "R"; }
};

class CurrentSource: public device {
public:
	CurrentSource(): device(2) { }
	int getNodeCount() const { return 2; }
	string getType()const { return "current source"; }
	string getCode() const { return "I"; }
};


class circuit {
public:
	string *nodes;
	int ncount;
	device **element;
	int ndevices;
	circuit() {create(8,16); }
	~circuit();
	void create(int node_count, int device_count);
	void read(FILE *in);
	void list_nodes();
	void list_devices();
	void build_node_list();
	int add_node(string str);
};


circuit.cpp


//#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include "circuit.h"
using namespace std;


char *strtrm(char *str, char delimiter);
char *strtoken(char* &inp, char delimiter);


device::device(int n) 
{ 
	nodes = new string[n];
	ndx = new int[n];
	value = 0.0;
	x = y = orientation = 0.0;
}

 device::~device()
{
	if (nodes) delete [] nodes;
	nodes = 0;
}

const string suffix("afpnumkKMGT");
const double scales[] = {1e-18, 1e-15, 1e-12, 1e-9, 1e-6, 1e-3, 1e3, 1e3, 1e6, 1e9, 1e12};

void device::parse_value(string tok)
{
	char c=0;
	sscanf_s(tok.c_str(),"%lg%c",&value,&c);
	if (c) {
		size_t pos = suffix.find(c);
		if (pos>=0) value *= scales[pos];
	}
}




void device::parse(string tok[], int ntokens)
{
	int n = getNodeCount();
	assert(ntokens>n+2);
	name = tok[1];
	for (int j=0; j<n; j++) {
		nodes[j] = tok[2+j];
	}
	n += 2;
	parse_value(tok[n++]);
	if (ntokens<n+1) return;
	if (tok[n][0]=='[') {
		char c=0;
		sscanf_s(tok[n++].c_str()+1,"%lg",&x);
		sscanf_s(tok[n++].c_str(),"%lg%c",&y,&c);
		if (c==']') orientation = 0.0;
		else sscanf_s(tok[n++].c_str(),"%lg",&orientation);
	}
}

void circuit::create(int node_count, int device_count)
{
	nodes = new string[node_count];
	element = new device *[device_count];
	ncount = ndevices = 0;
}

circuit::~circuit()
{
	if (nodes) delete [] nodes;
	for (int i=0; i<ndevices; i++) delete element[i];
	if (element) delete [] element;
}

void circuit::read(FILE *in)
{
	char buf[512];
	char *inp, *token;
	bool done = false;
	int lines = 0;
	add_node(string("0"));
	while (!done) {
		fgets(buf,511,in);
		if (feof(in)) return;
		lines++;
		strtrm(buf,'\n'); // terminate at newline character
		printf("%2d:  %s\n",lines, buf);
		strtrm(buf,'%'); // terminate at comment character
		int ntokens=0;
		inp = buf;
		string tok[16];
		while ((token=strtoken(inp,' '))!=0) {
			tok[ntokens++] = token;
			//printf("token %d: %s\n",n,token);
		}
		if (ntokens==0) continue;
		device *dp;
		if (tok[0]=="R") {
			dp = new Resistor();
		}
		else if (tok[0]=="I") dp = new CurrentSource();
		else {
			printf("unrecognized device: %s\n",tok[0].c_str());
			continue;
		}
		dp->parse(tok,ntokens);
		element[ndevices++]=dp;		
	}
}

int circuit::add_node(string str)
{
	int i;
	for (i=0; i<ncount; i++) {
		if (nodes[i]==str) return i;
	}
	nodes[ncount] = string(str);
	return ncount++;
}

void circuit::build_node_list()
{
	int i, j;
	for (i=0; i<ndevices; i++) {
		device &dev = *element[i];
		for (j=0; j<dev.getNodeCount(); j++) dev.ndx[j] = add_node(dev.nodes[j]);
	}
}

void circuit::list_nodes()
{
	for (int i=0; i<ncount; i++) {
		cout << i << "  " << nodes[i] << endl;
	}
}

void circuit::list_devices()
{
	for (int i=0; i<ndevices; i++) {
		device &dev = *element[i];
		string s = dev.getCode() + " " + dev.name + " nodes ";
		printf("%s",s.c_str());
		for (int j=0; j<dev.getNodeCount(); j++) 
			//printf("%s ",dev.nodes[j].c_str());
			printf("%d ",dev.ndx[j]);
		printf("\tvalue %g",dev.value);
		printf("  loc[%g %g]",dev.x,dev.y);
		if (dev.orientation) printf(" rotate %g\n",dev.orientation);
		else printf("\n");
	}
}


Maintained by John Loomis, updated Sun Feb 04 16:05:09 2007