#include /* ATLC - Arbitrary Transmission Line Calculator. ver 1.0 */ #include /* By D. Kirkby G8WRB. Compiles okay with */ #include /* Microsoft Quick C, version 2.0 and GNU C. */ #define Imax 126 /* Voltage array size will be 0..Imax */ #define Jmax 126 /* ie v[0..Imax][[0..Jmax] */ float v[Imax+1][Jmax+1]; /* Declare an array to hold the voltages */ void arbitrary_transmission_line(int W, int H, int w, int h, int t); void main(int argc, char **argv) /* Read parameters from command line here */ { int W, H, w, h, t; /* integers for number of grid squares to use. */ if((argc!=6) ) /* Check the number of command line arguments are correct */ { printf("Usage: %s W(shield) H(shield) width height thickness\n", argv[0]); exit(1); /* Exit - program called with wrong number of arguments */ } W=atoi(argv[1]); /* Read shield width (in grid points) from command line. */ H=atoi(argv[2]); /* Read shield height (in grid points) from command line. */ w=atoi(argv[3]); /* Read strip width (in grid points) from command line. */ h=atoi(argv[4]); /* Read strip height (in grid points) from command line. */ t=atoi(argv[5]); /* Read strip thickness (in grid points) from command line. */ if((W>Imax)||(H>Jmax)||(h+t>H-1)||(w>W-2)||(h<0)||(t<0)||(W<0)||(H<0)) /* Basic checks */ { printf("Sorry - one of the arguments is silly - too big, too small ?\n"); exit(2); } arbitrary_transmission_line(W,H,w,h,t); /* Calculate L, C and Zo */ } void arbitrary_transmission_line(int W, int H, int w, int h, int t) { double Eo=8.854e-12, Er=1.0, mu=12.57e-7, c, l, Zo, vnew,r=1.5, c_old; int i, j, k=0, done=0; for(i=0;i<=W;i=i+1) /* Zero the voltage array. Its essential that the */ for(j=0;j<=H;j=j+1) /* outer is at 0V, but desirable for everywhere to */ v[i][j]=0.0; /* start at 0 V. */ for(i=(W-w)/2;i<=(W-w)/2+w;i=i+1) /* Put stripline in centre of x axis, */ for(j=h;j<=h+t;j=j+1) /* and between h and h+t on the y axis,*/ v[i][j]=1.0; /* then set stripline there to 1 V */ do{ /* Set up a relaxation loop, to find the voltage at every point */ k=k+1; /* increment the counter used to count the iterations */ for(i=1;i<=W-1;i=i+1) /* Data at i=0 must stay fixed at v=0 */ for(j=1;j<=H-1;j=j+1) /* as this is a 'boundary condition' */ if(v[i][j]!=1.0) /*ie. don't do this where the stripline is */ { vnew=r*(v[i+1][j]+v[i-1][j]+v[i][j+1]+v[i][j-1])/4+(1-r)*v[i][j]; v[i][j]=vnew; /* New voltage is calculated */ } if(k%10==0) /* Now we have v distribution we find C every 10 iterations */ { c_old=c; c=0.0; for(i=0;i<=W-1;i=i+1) /* Sum v over cross-section to get C, which */ for(j=0;j<=H-1;j=j+1) /* is easy for a rectangular cross section */ c=c+pow(v[i][j]-v[i+1][j+1],2.0)+pow(v[i+1][j]-v[i][j+1],2.0); c=c*Eo/2.0; /* Find capacitance - only correct if air-spaced */ l=mu*Eo/c; /* Calculate the line inductance - always correct */ c=c*Er; /* Correct the capacitance if line has a dielectric */ Zo=sqrt(l/c); /* Calculate the characteristic impedance */ printf("%5d c=%.2lfpF/m l=%.2lfnH/m Zo=%lf Ohms\n",k,c*1e12,l*1e9,Zo); if(fabs(c_old-c)/c < 0.00001) /* Until they differ by < 0.001 % */ done=1; /* Little change in calculated value of C - so we finish*/ else done=0; /* Large change in calculated value of C - lets continue */ } }while(done==0); /* Repeat for until the capacitance has converged */ } /* End line of program - line 66 */