~ubuntu-branches/ubuntu/precise/yagiuda/precise

« back to all changes in this revision

Viewing changes to src/gain.c

  • Committer: Bazaar Package Importer
  • Author(s): Joop Stakenborg
  • Date: 2005-08-22 20:20:13 UTC
  • Revision ID: james.westby@ubuntu.com-20050822202013-mhhxp4xirdxrdfx1
Tags: upstream-1.19
ImportĀ upstreamĀ versionĀ 1.19

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifdef HAVE_STDLIB_H
 
2
#include <stdlib.h>
 
3
#endif
 
4
#include <stdio.h>
 
5
#include <math.h>
 
6
#include <malloc.h>
 
7
#include <errno.h>
 
8
#include "yagi.h"
 
9
#define TINY 1e-10
 
10
 
 
11
extern int errno;
 
12
 
 
13
/* This function finds the gain both in the E plane (xz plane) and the
 
14
H plane (xy plane) at angle (theta, phi). The method used is as described
 
15
on page 1-12 of 'Yagi Antenna Design' by Dr. Lawson , ARRL */
 
16
 
 
17
void gain(double theta, double phi, double pin, double F, struct element_data *coordinates, struct FCOMPLEX *current, int elements, double *gain_E_plane, double *gain_H_plane, double actual_frequency, double design_frequency) 
 
18
{
 
19
        int i;
 
20
        double *r_E, *r_H, *g_E, *g_H,integer_bit;
 
21
        double length, x, y, lamda_design, lamda, tmp;
 
22
        struct FCOMPLEX temp_E, temp_H, e_gain, h_gain;
 
23
        /* need to allocate space for FCOMPLEX types. Since there is no Numerical 
 
24
        Recipes routine, I'll use the standard method. Since I've always used
 
25
        elements positions 1 to N, I'll just wast the extra location */
 
26
        r_E=dvector(1L,(long) elements); 
 
27
        r_H=dvector(1L,(long) elements);
 
28
        g_E=dvector(1L,(long) elements);
 
29
        g_H=dvector(1L,(long) elements);
 
30
        e_gain.r=0;   /* set to zero. Necessary as we sum into these */
 
31
        e_gain.i=0;
 
32
        h_gain.r=0;
 
33
        h_gain.i=0;
 
34
        /* convert theta and thi to radians from degrees */
 
35
        theta=theta*M_PI/180;
 
36
        phi=phi*M_PI/180;
 
37
        lamda_design=3e8/design_frequency;
 
38
        lamda=3e8/actual_frequency;
 
39
        for(i=1;i<=elements;++i) 
 
40
        {
 
41
                length=coordinates[i].length/lamda;
 
42
                x=coordinates[i].x/lamda_design;
 
43
                y=coordinates[i].y/lamda_design;
 
44
 
 
45
                /* for E -plane */
 
46
                r_E[i]=sin(theta)*x;
 
47
                if(fabs(theta) < TINY)    /* avoid division by zero if theta=0 */
 
48
                        g_E[i]=0;
 
49
                else
 
50
                        g_E[i]=(cos(M_PI*length*cos(theta))-cos(M_PI*length))/sin(theta);
 
51
 
 
52
                /* for H -plane */
 
53
                r_H[i]=x*cos(phi)+y*sin(phi);
 
54
                g_H[i]=1-cos(M_PI*length);
 
55
                /* printf("g_H[%d]=%.16lf \n", i, g_H[i]);               */
 
56
                temp_E.r=0;
 
57
                temp_E.i=2*M_PI*r_E[i]*F;
 
58
                temp_E=E_to_complex_power(temp_E); /* exp(j 2 pi r[i] F) */
 
59
 
 
60
                temp_H.r=0;
 
61
                temp_H.i=2*M_PI*r_H[i]*F;
 
62
                temp_H=E_to_complex_power(temp_H);
 
63
      /* printf("element %d temp_H.r=%f temp_H.i=%f\n",i, temp_H.r, temp_H.i); */
 
64
                /* get element currents */
 
65
                temp_E=Cmul(temp_E,current[i]);
 
66
                temp_H=Cmul(temp_H,current[i]);
 
67
                /* printf("element %d: current = %.10lf i%.10lf = %.10lf (mag) at %f degrees\n", i,current[i].r, current[i].i, sqrt(current[i].r*current[i].r+current[i].i*current[i].i), 180*atan2(current[i].i,current[i].r)/M_PI);         */
 
68
      /* printf("element %d I temp_H.r=%.10lf temp_H.i=%.10lf\n",i, temp_H.r, temp_H.i); */
 
69
                e_gain=Cadd(e_gain,RCmul(g_E[i],temp_E));
 
70
                h_gain=Cadd(h_gain,RCmul(g_H[i],temp_H));
 
71
                /* printf("h_gain=%.16lf + i %.16lf \n", h_gain.r, h_gain.i); */
 
72
        }
 
73
        /* there will be a divide  by zero in calculating
 
74
        equ 1.28, of Lawsons book, (see page 1-12)
 
75
        at theta=0,180,360 degree, infact anywhere where 
 
76
        sin(theta) is zero */
 
77
 
 
78
        if( modf(theta/M_PI,&integer_bit) < TINY || fabs(theta-M_PI)<TINY)
 
79
        {
 
80
                *gain_E_plane=-150.0;   /* a very very small number */
 
81
        }
 
82
        else
 
83
        {
 
84
                tmp=(Cabs(e_gain)*Cabs(e_gain)*60/pin);  
 
85
                *gain_E_plane=10*log10(tmp);  
 
86
#ifdef DEBUG
 
87
        if(errno)
 
88
        {
 
89
                fprintf(stderr,"Errno =%d in gain() of gain.c after E\n", errno);
 
90
                printf("tmp=%f pin=%f theta=%f gainE=%f\n", tmp, pin,theta,*gain_E_plane);
 
91
                exit(1);
 
92
        }
 
93
#endif
 
94
        }
 
95
        tmp=(Cabs(h_gain)*Cabs(h_gain)*60/pin);  
 
96
        *gain_H_plane=10*log10(tmp);  
 
97
 
 
98
#ifdef DEBUG
 
99
        if(errno)
 
100
        {
 
101
                fprintf(stderr,"Errno =%d in gain() of gain.c after H\n", errno);
 
102
                printf("tmp=%f pin=%f \n", tmp, pin);
 
103
                exit(1);
 
104
        }
 
105
#endif
 
106
        free_dvector(r_E,1L,(long) elements); 
 
107
        free_dvector(r_H,1L,(long) elements); 
 
108
        free_dvector(g_E,1L,(long) elements); 
 
109
        free_dvector(g_H,1L,(long) elements); 
 
110
 
 
111
#ifdef DEBUG
 
112
        if(errno)
 
113
        {
 
114
                fprintf(stderr,"Errno =%d in gain() of gain.c\n", errno);
 
115
                exit(1);
 
116
        }
 
117
#endif
 
118
}
 
119
 
 
120
struct FCOMPLEX E_to_complex_power(struct FCOMPLEX x)
 
121
{
 
122
        struct FCOMPLEX a, answer;
 
123
        double real;
 
124
 
 
125
        /* First real part */
 
126
        real=exp(x.r);
 
127
        /* now the imaginary part */
 
128
        /* Exp(i theta) = cos(theta) + i sin(theta) */
 
129
        a.r=cos(x.i);
 
130
        a.i=sin(x.i);
 
131
        answer=RCmul(real,a);
 
132
        return(answer);
 
133
}
 
134
#undef TINY