#include <stdio.h>
#include <math.h>
#include "pi.h"
#include "type.h"

/* structure which saves line parameters */

typedef struct {
  float length;	/* length of line in km */
  int gauge;	/* AWG gauge */
} LINE;

extern FILE *fdata;

/**********************************************************************

			line()

************************************************************************

Function computes the ABCD matrix of a uniform transmission line

Inputs: pointer to the data structure for the twoport and the frequency
Output: ABCD matrix for the twoport
*/

ABCD line(current,f)
TWOPORT *current; 	/* twoport being modelled */
double f;		/* frequency */

{
  ABCD tmsect;
  COMPLEX gamma,z0;
  POINTER calloc();
  LINE *param;

/* the first time this function is called we simply read the parameters
   of the line from the input line */

  if(current->line != NULL) {

/* allocate storage for the line parameters -- this
   function may be called for many lines so it has to
   be unique */

    if((current->param = calloc(1,sizeof(LINE))) == NULL)
    error_alloc();

    param = (LINE *) current->param;

    if(sscanf(current->line,"line%f%d",&param->length,&param->gauge) != 2) {
      fprintf(stderr,"line(): cannot read parameters on line\n%s\n",current->line);
      exit(1);
    }

    fprintf(fdata,"Transmission line %f km long with gauge AWG%d\n",param->length,param->gauge);
  }

/* every other time this function is called we calculate the ABCD matrix */

  else 	{
    param = (LINE *) current->param;

/* determine char imped and prop const for line */
	
    gi(param->gauge,f,&gamma,&z0);

/* multiply the prop constant by the cable length */
    gamma.real *= param->length;
    gamma.imag *= param->length;

/* calculate elements of ABCD matrix -- A and D are cosh(gamma)  */
    tmsect.a.real = tmsect.d.real
	= cosh(gamma.real)*cos(gamma.imag);
    tmsect.a.imag = tmsect.d.imag
	= sinh(gamma.real)*sin(gamma.imag);
/* B and C start with sinh(gamma) */
    tmsect.b.real = tmsect.c.real
	= sinh(gamma.real)*cos(gamma.imag);
    tmsect.b.imag = tmsect.c.imag
	= cosh(gamma.real)*sin(gamma.imag);
    tmsect.b = cmpy(tmsect.b,z0);
    tmsect.c = cdiv(tmsect.c,z0);
  }

  return(tmsect);
}

/******************************************************************

			gi()

*******************************************************************

Function returns the propagation constant of the cable at a given
frequency for a given gauge
*/

void gi(gauge,f,pgamma,pimped)
int gauge;
double f;
COMPLEX *pgamma,*pimped;

{
  double r,c,l,g;
  COMPLEX x,y;

/* calculate the primary constants */

  primary(gauge,f,&r,&c,&l,&g);

/* determine the propagation constant */

  x.real = r;
  x.imag = 2.*PI*f*l;
  y.real = g;
  y.imag = 2.*PI*f*c;

  *pgamma = csqrt(cmpy(x,y));

/* finally the characteristic impedance */

  *pimped = csqrt(cdiv(x,y));

  return;
}

/********************************************************************

		primary()

*********************************************************************

Function calculates the primary parameters of a line using a
fourth order polynomial approximation (in frequency)

Models for AWG 24 and 26, as well as DW10 and DW8, are included
*/

void primary(gauge,f,pr,pc,pl,pg)
int gauge;
double f;
double *pr,*pl,*pc,*pg;

{
 
  double dummy;
  if (f==0)
    f+=1e-20;
  switch (gauge){
 
  case 5:                       /*Category 5 twisted pair*/
    dummy = pow(f*3.070310101e-5,.705);
    *pc = 4.855e-8;
    *pg = 1.47653e-9*pow(f,0.91);
    *pl = (1090.8e-6 + 504.5e-6*dummy)/(1+dummy);
    *pr = pow(9.726638987e8+5.00079494e-2*f*f,0.25);
    break;

  case 24:			/* 24-gauge = 0.5mm, T1E1/98-117R13 */
    dummy = pow(f*1.805836e-6,1.1529766);
    *pc = 50e-9;
    *pg = 234.87476e-15*pow(f,1.38);
    *pl = (617.29539e-6 + 478.97099e-6*dummy)/(1+dummy);
    *pr = pow(9.284698103e8+0.053073481*f*f,0.25);
    break;

  case 26:			/* 26-gauge = 0.4mm, T1E1/98-117R13 */
    dummy = pow(f*1.240173747e-6,.92930728);
    *pc = 49e-9;
    *pg = 43e-9*pow(f,.7);
    *pl = (675.36888e-6 + 488.95186e-6*dummy)/(1+dummy);
    *pr = pow(6.707049334e9+0.14769620*f*f,0.25);
    break;

  case 110:			/* DW10, aka TP3, T1E1/98-117R13 */
    dummy = pow(f*1.391037269e-6,0.75577086);
    *pc = 5.1e-8+6.38e-8*pow(f,-0.11584622);
    *pg = 8.9e-8*pow(f,0.856);
    *pl = (728.87e-6 + 543.43e-6*dummy)/(1+dummy);
    *pr = pow(1.07e9+0.0497223*f*f,0.25);
    break;

  case 108:			/* DW8, aka FP, T1E1/98-117R13 */
    dummy = pow(f*5.740528e-6,1.195);
    *pc = 2.268e-8+3.178e-8*pow(f,-0.1109);
    *pg = 5.3e-8*pow(f,0.88);
    *pl = (1000e-6 + 911e-6*dummy)/(1+dummy);
    *pr = pow(2.870129314e6+1.218e-3*f*f,0.25);
    break;
    
  default:
    fprintf(stderr,"Gauge %d not modeled\n",gauge);
    exit(3);
    break;
  }
  return;
}

























