Imported Upstream version 4.6.0
[debian/atlc] / docs / qex-december-1996 / ATLC.C
1 #include <stdio.h> /* ATLC - Arbitrary Transmission Line Calculator. ver 1.0 */\r
2 #include <math.h>        /* By D. Kirkby G8WRB.  Compiles okay with          */\r
3 #include <stdlib.h>      /* Microsoft  Quick C, version 2.0 and GNU C.       */\r
4 #define Imax 126         /* Voltage array size will be 0..Imax               */\r
5 #define Jmax 126         /* ie v[0..Imax][[0..Jmax]                          */\r
6 float v[Imax+1][Jmax+1]; /* Declare an array to hold the voltages            */\r
7 void arbitrary_transmission_line(int W, int H, int w, int h, int t);\r
8 \r
9 void main(int argc, char **argv) /* Read parameters from command line here   */\r
10 {\r
11          int W, H, w, h, t; /* integers for number of grid squares to use. */\r
12          if((argc!=6) ) /* Check the number of command line arguments are correct */\r
13          {\r
14                    printf("Usage: %s W(shield) H(shield) width height thickness\n", argv[0]);\r
15                    exit(1); /* Exit - program called with wrong number of arguments */\r
16          }\r
17          W=atoi(argv[1]); /* Read shield width (in grid points) from command line.    */\r
18          H=atoi(argv[2]); /* Read shield height (in grid points) from command line.   */\r
19          w=atoi(argv[3]); /* Read strip width (in grid points) from command line.     */\r
20          h=atoi(argv[4]); /* Read strip height (in grid points) from command line.    */\r
21          t=atoi(argv[5]); /* Read strip thickness (in grid points) from command line. */\r
22          if((W>Imax)||(H>Jmax)||(h+t>H-1)||(w>W-2)||(h<0)||(t<0)||(W<0)||(H<0)) /* Basic checks */\r
23          {\r
24                     printf("Sorry - one of the arguments is silly - too big, too small ?\n");\r
25                     exit(2);\r
26          }\r
27          arbitrary_transmission_line(W,H,w,h,t); /* Calculate L, C and Zo     */\r
28 }\r
29 \r
30 void arbitrary_transmission_line(int W, int H, int w, int h, int t)\r
31 {\r
32          double Eo=8.854e-12, Er=1.0, mu=12.57e-7, c, l, Zo, vnew,r=1.5, c_old;\r
33          int i, j, k=0, done=0; \r
34          for(i=0;i<=W;i=i+1)    /* Zero the voltage array. Its essential that the  */\r
35                    for(j=0;j<=H;j=j+1) /* outer is at 0V, but desirable for everywhere to */\r
36                             v[i][j]=0.0;     /* start at 0 V. */\r
37          for(i=(W-w)/2;i<=(W-w)/2+w;i=i+1) /* Put stripline in centre of x axis, */\r
38                    for(j=h;j<=h+t;j=j+1)          /* and between h and h+t on the y axis,*/\r
39                             v[i][j]=1.0;                /* then set stripline there to 1 V */\r
40          do{ /* Set up a relaxation loop, to find the voltage at every point */\r
41                    k=k+1; /* increment the counter used to count the iterations */   \r
42                    for(i=1;i<=W-1;i=i+1) /* Data at i=0 must stay fixed at v=0 */\r
43                             for(j=1;j<=H-1;j=j+1) /* as this is a 'boundary condition' */\r
44                                       if(v[i][j]!=1.0) /*ie. don't do this where the stripline is */\r
45                                       {\r
46                                          vnew=r*(v[i+1][j]+v[i-1][j]+v[i][j+1]+v[i][j-1])/4+(1-r)*v[i][j];\r
47                                                v[i][j]=vnew; /* New voltage is calculated */\r
48                                       }\r
49                    if(k%10==0) /* Now we have v distribution we find C every 10 iterations */\r
50                    {\r
51                             c_old=c; c=0.0; \r
52                             for(i=0;i<=W-1;i=i+1) /* Sum v over cross-section to get C, which  */\r
53                                   for(j=0;j<=H-1;j=j+1) /* is easy for a rectangular cross section */\r
54                                        c=c+pow(v[i][j]-v[i+1][j+1],2.0)+pow(v[i+1][j]-v[i][j+1],2.0);\r
55                             c=c*Eo/2.0; /* Find capacitance - only correct if air-spaced */\r
56                             l=mu*Eo/c;  /* Calculate the line inductance - always correct */\r
57                             c=c*Er;          /* Correct the capacitance if line has a dielectric */\r
58                             Zo=sqrt(l/c);    /* Calculate the characteristic impedance */\r
59                             printf("%5d c=%.2lfpF/m l=%.2lfnH/m Zo=%lf Ohms\n",k,c*1e12,l*1e9,Zo);\r
60                             if(fabs(c_old-c)/c < 0.00001) /* Until they differ by < 0.001 % */\r
61                                       done=1;  /* Little change in calculated value of C - so we finish*/\r
62                             else\r
63                                       done=0; /* Large change in calculated value of C - lets continue */\r
64                    }\r
65          }while(done==0); /* Repeat for until the capacitance has converged */\r
66 } /* End line of program - line 66 */\r