Imported Upstream version 4.6.0
[debian/atlc] / src / non_gui / convert_create_bmp_for_coupled_microstrip_dimensions_to_integers.c
1 /* atlc - arbitrary transmission line calculator, for the analysis of
2 transmission lines are directional couplers. 
3
4 Copyright (C) 2002. Dr. David Kirkby, PhD (G8WRB).
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either package_version 2
9 of the License, or (at your option) any later package_version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
19 USA.
20
21 Dr. David Kirkby, e-mail drkirkby at ntlworld.com 
22
23 */
24
25 #include "config.h"
26
27 #ifdef HAVE_STRING_H
28 #include <string.h>
29 #endif
30
31 #ifdef HAVE_STRINGS_H
32 #include <strings.h>
33 #endif
34
35 #ifdef HAVE_STDLIB_H
36 #include <stdlib.h>
37 #endif  
38
39 #include "definitions.h"
40 #include "exit_codes.h"
41
42 extern double Er1, Er2;
43 extern double Ers[];
44 extern int colours[];
45
46 void convert_create_create_bmp_for_coupled_microstrip_dimensions_to_integers(struct transmission_line_properties *pcb)
47 {
48    /* A number of paramters are set to -1, as otherwise the compiler   
49    complains they may be used unitialised. It is wise to check they
50    are not -1 before assining a variable to their contents, 
51    but I can't be bothered. */
52    int best_W=-1, best_H=-1, best_w=-1, best_s=-1, best_g=-1;
53    int best_h=-1, best_t=-1;
54    int min, max, lowest =  2500, highest=10000;
55    int i;
56    double max_gridsize, min_gridsize;
57    double error, error_min=VERY_LARGE, gridsize=-1, best_grid_size=-1;
58
59
60    /* scale grid size,  according to a command line option */
61    lowest*=(int) 0.5+pow(2.0,(double)pcb->bmp_size);
62    highest*=(int) 0.5+pow(2.0,(double)pcb->bmp_size);
63
64    max_gridsize=sqrt(pcb->WW*pcb->HH/(double )lowest);  /* minimum dimension in m */
65    min_gridsize=sqrt(pcb->WW*pcb->HH/(double )highest);
66    if(pcb->WW>=pcb->HH)
67    {
68       min=pcb->WW/max_gridsize;
69       max=pcb->WW/min_gridsize;
70    }
71    else
72    {
73       min=pcb->HH/max_gridsize;
74       max=pcb->HH/min_gridsize;
75    }
76    if (pcb->verbose_level >= 2)
77      printf("WW=%f HH=%f lowest=%d higherst = %d min=%d max=%d\n",pcb->WW,pcb->HH,lowest, highest, min, max);
78    for(i=min;i<=max;++i)
79    {
80       /* Try various combinations for  H,a,b,c, etc */
81       if(pcb->W>pcb->H)
82          gridsize=pcb->WW/i;
83       else
84          gridsize=pcb->HH/i;
85       pcb->W=(int)(pcb->WW/gridsize + 0.5);
86       pcb->H=(int)(pcb->HH/gridsize + 0.5);
87       pcb->w=(int)(pcb->ww/gridsize + 0.5);
88       pcb->s=(int)(pcb->ss/gridsize + 0.5);
89       pcb->g=(int)(pcb->gg/gridsize + 0.5);
90       pcb->h=(int)(pcb->hh/gridsize + 0.5);
91       pcb->t=(int)(pcb->tt/gridsize + 0.5);
92       error=0.0;
93       /*error+=pow((pcb->WW-pcb->W*gridsize)/pcb->WW,2.0); */ /* relative error in W */
94       /*error+=pow((pcb->HH-pcb->H*gridsize)/pcb->HH,2.0); */ 
95       if(pcb->w>0)
96          error+=pow((pcb->ww-pcb->w*gridsize)/pcb->ww,2.0);
97       if(pcb->s>0)
98           error+=pow((pcb->ss-pcb->s*gridsize)/pcb->ss,2.0);
99       if(pcb->g>0)
100           error+=pow((pcb->gg-pcb->g*gridsize)/pcb->gg,2.0);
101       if(pcb->h>0)
102           error+=pow((pcb->hh-pcb->h*gridsize)/pcb->hh,2.0);
103       if(pcb->t>0)
104           error+=pow((pcb->tt-pcb->t*gridsize)/pcb->tt,2.0);
105       if(error < (error_min-TINY))
106       {
107           error_min=error;
108           best_W=pcb->W;
109           best_H=pcb->H;
110           best_w=pcb->w;
111           best_s=pcb->s;
112           best_g=pcb->g;
113           best_h=pcb->h;
114           best_t=pcb->t;
115           best_grid_size=gridsize;
116       }
117    }
118    pcb->W=best_W;
119    pcb->H=best_H;
120    pcb->w=best_w;
121    pcb->s=best_s;
122    pcb->g=best_g;
123    pcb->h=best_h;
124    pcb->t=best_t;
125    if(pcb->verbose_level > 0)
126    {
127       fprintf(stderr,"error_min=%.16f\n",error_min);
128       fprintf(stderr,"User requested: W=%f H=%f w=%f s=%f g=%f h=%f t=%f Er1=%f Er2=%f\n\n",pcb->WW,pcb->HH,pcb->ww,pcb->ss,pcb->gg,pcb->hh,pcb->tt,Er1,Er2);
129       fprintf(stderr,"Internally the program is using the following grid:\n");
130       fprintf(stderr,"W=%d H=%d w=%d s=%d g=%d h=%d t=%d\nThe  grid size is %f mm, inches or whatever\n\n", pcb->W, pcb->H, pcb->w, pcb->s, pcb->g,pcb->h, pcb->t,best_grid_size);
131       if(error_min > TINY)
132       {
133          fprintf(stderr,"This means we are simulating a transmission line with these dimensions:\n");
134          fprintf(stderr,"W=%f H=%f w=%f s=%f g=%f h=%f t=%f (mm, inches or whatever)\n",pcb->W*best_grid_size,pcb->H*best_grid_size,pcb->w*best_grid_size,pcb->s*best_grid_size,pcb->g*best_grid_size,pcb->h*best_grid_size,pcb->t*best_grid_size);
135          fprintf(stderr,"\nThese are slightly different to what you indicated on the command line,\n");
136          fprintf(stderr,"but they are the best approximation possible, given the grid size\n");
137       }
138    }
139    if(pcb->s == 0)
140    {
141       fprintf(stderr,"Error #12. The gap between the two conductors coupled lines (s) is too small. Either increase the bitmap size (-b option), or make s at least %f\n",gridsize);
142       exit_with_msg_and_exit_code("",GAP_BETWEEN_CONDUCTORS_TOO_SMALL);
143    }
144    if(pcb->g == 0)
145    {
146       fprintf(stderr,"Error #13. The gap between the groundplane (g) and coupled lines is too small. Either increase the bitmap size (-b option), or make g at least %f\n",gridsize);
147       exit_with_msg_and_exit_code("",GAP_BETWEEN_CONDUCTORS_TOO_SMALL);
148    }
149    if(pcb->h == 0)
150    {
151       fprintf(stderr,"Error #14. The thickness of the dielectric of Er2 (h) is too small. Either increase the bitmap size (-b option), or make h at least %f\n",gridsize);
152       exit_with_msg_and_exit_code("",GAP_BETWEEN_CONDUCTORS_TOO_SMALL);
153    }
154    check_error(pcb->WW,pcb->W,best_grid_size,"W");
155    check_error(pcb->HH,pcb->H,best_grid_size,"H");
156    check_error(pcb->ww,pcb->w,best_grid_size,"w");
157    check_error(pcb->ss,pcb->s,best_grid_size,"s");
158    check_error(pcb->gg,pcb->g,best_grid_size,"g");
159    check_error(pcb->hh,pcb->h,best_grid_size,"h");
160    check_error(pcb->tt,pcb->t,best_grid_size,"t");
161 }