#include <stdio.h>
#include <math.h>
#include "pi.h"
#include "type.h"
/* function prototypes for functions declared in line.c */
void gi(int gauge,double f,COMPLEX *pgamma,COMPLEX *pimped);
void primary(int gauge,double f,double *pr,double *pc,double *pl,double *pg);
ABCD line(current,f);
/* 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;
  switch (gauge){

  case 24:			/* 24-gauge = 0.5mm, T1E1/95-117R4 */
    dummy = pow(f*1e-6,1.2);
    *pc = 5.5e-8+1e-9*pow(f+1e-20,-0.1);
    *pg = 5e-10*pow(f,1.033)+1e-20;
    *pl = (695e-6 + 585e-6*dummy)/(1+dummy);
    *pr = pow(1026625681+0.03589*f*f,0.25);
    break;

  case 26:			/* 26-gauge = 0.4mm, T1E1/95-117R4 */
    *pc = 5.1585e-8;
/* my fit using T1E1/95-117R4, with weight on low freq. */
    *pg = -1.5591e-07+sqrt(f)*(5.8837e-09-2.2625e-15*f-7.5784e-26*f*f)+f*(2.5250e-11+1.6485e-19*f);
    *pr =  268.9113+sqrt(f)*(2.7528e-2-9.9825e-08*f-3.6318e-19*f*f)+f*(3.6437e-04+9.3970e-12*f);
    *pl =  6.1658e-04+sqrt(f)*(-1.1181e-07+7.9624e-16*f-2.0857e-25*f*f)+f*(2.1739e-11-4.2140e-19*f);
    break;

  case 110:			/* DW10, aka TP3, T1E1/95-117R4 */
    dummy = pow(f*1e-6,0.75577086);
    *pc = 5.1e-8+6.38e-8*pow(f+1e-20,-0.11584622);
    *pg = 8.9e-8*pow(f,0.856)+1e-20;
    *pl = (728.87e-6 + 540.43e-6*dummy)/(1+dummy);
    *pr = pow(1.071623756e9+0.03589*f*f,0.25);
    break;

  case 108:			/* DW8, aka FP, T1E1/95-117R4 */
    dummy = pow(f*1e-5,1.195);
    *pc = 2.268e-8+3.178e-8*pow(f+1e-20,-0.1109);
    *pg = 5.3e-8*pow(f,0.88)+1e-20;
    *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;
}

























