Physics and Astronomy |
Back to top
Example: the circit programPassive electrical circuitsIn the lecture we saw how to find the impedance of an electrical circuit consisting of series and parallel components. But of course we also need to be read in the data and to setup the circuit structures. Reading in a single componentThe following code will read in a single component: char *names[] = { "Resistor", "Capacitor", "Inductor"}; Component *newcomponent(void) { Component *c = malloc(sizeof *c); while(1) { printf("What type of component?\n"); for (int i = 0; i < 3; ++i) printf("%d\t%s\n", i, names[i]); scanf("%d", &c->type); switch(c->type) { case Resistor: case Capacitor: case Inductor: while( 1 ) { printf("Please enter the value of the %s\n", names[c->type]); scanf("%lg", &c->value); if ( c->value > 0) return c; printf("Please enter a positive value\n"); } default: printf("Sorry \"%d\" is not a valid option, please try again\n", c->type); } } return NULL; } Allowing for multiple componentsWe can allow for multiple coponents ina circuit by adding an extra option to the switch() statement that allocates an array of circuit pointers and recursively calls newcomponent() to fill it. This example uses the flexible array trick of having an empty array at the end of a structure and allocating anough space for the size of the array we want. case Series: case Parallel: while( 1 ) { printf("How many nodes are there?\n"); scanf("%ud", &n); if ( n > 0) break; printf("Please enter a positive value\n"); } c = xmalloc(sizeof *c + n * sizeof *c->nodes); c->n = n; for (n = 0; n < c->n; ++n) c->nodes[n] = newcomponent(); return c; The whole program// // Find the impedance of an electrical circuit // #include <stdio.h> #include <complex.h> #include <stdlib.h> #define INFINITY 1e100 #define PI 3.14159265358979 typedef enum type { Resistor, Capacitor, Inductor, Series, Parallel } Type; typedef struct component { double value; Type type; unsigned int n; // If parallel or serial struct component *nodes[]; // If parallel or serial } Component; Component *newcomponent(void) { char *names[] = { "Resistor", "Capacitor", "Inductor", "Series", "Parallel", NULL }; Component *c = NULL; Type type; int n; while(1) { printf("What type of component?\n"); for (int i = 0; names[i] != NULL; ++i) printf("%d\t%s\n", i, names[i]); scanf("%d", &type); switch(type) { case Resistor: case Capacitor: case Inductor: c = xmalloc(sizeof *c); c->type = type; while( 1 ) { printf("Please enter the value of the %s\n", names[c->type]); scanf("%lg", &c->value); if ( c->value > 0) return c; printf("Please enter a positive value\n"); } case Series: case Parallel: while( 1 ) { printf("How many nodes are there?\n"); scanf("%ud", &n); if ( n > 0) break; printf("Please enter a positive value\n"); } c = xmalloc(sizeof *c + n * sizeof *c->nodes); c->n = n; for (n = 0; n < c->n; ++n) c->nodes[n] = newcomponent(); return c; default: printf("Sorry \"%d\" is not a valid option, please try again\n", c->type); } } } double complex impedance(Component *c, double freq) { double complex z = 0; double denom; switch (c->type) { case Resistor: return c->value; case Inductor: return 2 * PI * I * c->value * freq; case Capacitor: // Handle DC and v low frequencies denom = 2 * PI * c->value * freq; if ( denom < 1.0/INFINITY ) denom = 1.0/INFINITY; return 1.0/(I * denom); case Series: for (int n = 0; n < c->n; ++n) z += impedance(c->nodes[n], freq); return z; case Parallel: for (int n = 0; n < c->n; ++n) z += 1.0/impedance(c->nodes[n], freq); return 1.0/z; } } int main() { Component *c = NULL; double complex z; c = newcomponent(); z = impedance(c, 50000); printf("The impedance is:\n" "\tmodulus %g and phase %g\n", cabs(z), carg(z)); return 0; }(For an example of a cicuit this can't handle directly consider a pyramid with the corners as nodes and the vertices being the "wires" each with a component, as in this PDF courtesy of Charles Williams.) |