nec2++  1.7.0
nec_radiation_pattern.h
1 /*
2  Copyright (C) 2004-2015 Timothy C.A. Molteno
3  tim@molteno.net
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 #ifndef __nec_radiation_pattern__
20 #define __nec_radiation_pattern__
21 
22 #include "nec_results.h"
23 #include "math_util.h"
24 #include "nec_ground.h"
25 #include "c_plot_card.h"
26 
27 
28 
31 enum polarization_norm {
32  POL_MAJOR_AXIZ=1,
33  POL_MINOR_AXIS=2,
34  POL_VERTICAL=3,
35  POL_HORIZONTAL=4,
36  POL_TOTAL=5
37 };
38 
41 enum polarization_sense {
42  POL_LINEAR=0,
43  POL_RIGHT=1,
44  POL_LEFT=2
45 };
46 
47 class nec_context;
48 
50 {
51 public:
52  // Radiation Pattern
53  nec_radiation_pattern(int in_n_theta, int in_n_phi,
54  nec_float in_theta_start, nec_float in_phi_start,
55  nec_float in_delta_theta, nec_float in_delta_phi,
56  nec_float in_range,
57  nec_ground& in_ground,
58  int in_ifar, nec_float in_wavelength,
59  nec_float pinr, nec_float pnlr,
60  int in_rp_output_format, int in_rp_normalization, int in_rp_ipd, int in_rp_power_average,
61  nec_float in_gnor,
62  c_plot_card& in_plot_card);
63 
64  virtual void write_to_file(ostream& os) {
65  write_to_file_aux(os);
66  }
67 
68  virtual enum nec_result_type get_result_type() {
69  return RESULT_RADIATION_PATTERN;
70  }
71 
72  void analyze(nec_context* in_context);
73 
74  void write_gain_normalization() {
75  if (_ifar != 1) {
76  nec_float norm = get_maximum_gain_db();
77  printf("Max Gain: %f\n",norm);
78  }
79  }
80 
81 
82  /*Added for the python wrapping : some basic access functions...*/
83 
84  real_matrix get_gain() {
85  return _gain;
86  }
87 
88  real_array get_gain_vert() {
89  return _power_gain_vert;
90  }
91 
92  real_array get_gain_horiz() {
93  return _power_gain_horiz;
94  }
95 
96  real_array get_gain_tot() {
97  return _power_gain_tot;
98  }
99 
100  real_array get_pol_axial_ratio() {
101  return _polarization_axial_ratio;
102  }
103 
106  nec_float get_pol_axial_ratio(int theta_index, int phi_index) const {
107  return _polarization_axial_ratio(theta_index, phi_index);
108  }
109 
110  real_array get_pol_tilt() {
111  return _polarization_tilt;
112  }
113 
114  int_array get_pol_sense_index() {
115  return _polarization_sense_index;
116  }
117 
121  int get_pol_sense(int theta_index, int phi_index) const {
122  return _polarization_sense_index(theta_index, phi_index);
123  }
124 
127  nec_float get_etheta_magnitude(int theta_index, int phi_index) {
128  return abs(_e_theta(theta_index, phi_index));
129  }
130 
133  nec_float get_etheta_phase(int theta_index, int phi_index) {
134  return arg_degrees(_e_theta(theta_index, phi_index));
135  }
136 
140  return _e_theta;
141  }
142 
145  nec_float get_ephi_magnitude(int theta_index, int phi_index) {
146  return abs(_e_phi(theta_index, phi_index));
147  }
148 
151  nec_float get_ephi_phase(int theta_index, int phi_index) {
152  return arg_degrees(_e_phi(theta_index, phi_index));
153  }
154 
158  return _e_phi;
159  }
160 
161  complex_array get_e_r() {
162  return _e_r;
163  }
164 
165  nec_float get_normalization_factor() {
166  return get_gain_normalization_factor(m_rp_gnor);
167  }
168 
169  nec_float get_average_power_gain() {
170  return _average_power_gain;
171  }
172 
173  nec_float get_average_power_solid_angle() {
174  return _average_power_solid_angle;
175  }
176 
177  nec_ground get_ground() {
178  return m_ground;
179  }
180 
181  nec_float get_range() {
182  return m_range;
183  }
184 
185  nec_float get_wavelength() {
186  return _wavelength;
187  }
188 
191  real_array ret(n_theta);
192  for (int32_t i=0; i<n_theta; i++)
193  ret[i] = get_theta(i);
194  return ret;
195  }
196 
197  nec_float get_delta_theta() {
198  return delta_theta;
199  }
200 
201  nec_float get_theta_start() {
202  return m_theta_start;
203  }
204 
207  real_array ret(n_phi);
208  for (int32_t i=0; i<n_phi; i++)
209  ret[i] = get_phi(i);
210  return ret;
211  }
212 
213  nec_float get_delta_phi() {
214  return delta_phi;
215  }
216 
217  nec_float get_phi_start() {
218  return m_phi_start;
219  }
220 
221 
222  int get_ifar() {
223  return _ifar;
224  }
225 
226  int get_rp_normalization() {
227  return m_rp_normalization;
228  }
229 
230  int get_rp_output_format() {
231  return m_rp_output_format;
232  }
233 
234  int get_rp_power_average() {
235  return m_rp_power_average;
236  }
237 
238  int get_rp_ipd() {
239  return m_rp_ipd;
240  }
241 
242  /*End of access functions added for the wrapping*/
243 
244 
245  nec_float get_maximum_gain_db() {
246  return get_gain_normalization_factor(0);
247  }
248 
249  /****************** STATISTICS ********************/
250 
251 
252 private:
253  nec_float mean(const real_matrix& pattern) const {
254  nec_float sum = 0.0;
255  long rows = pattern.rows();
256  long cols = pattern.cols();
257  for (long i=0;i<rows;i++) {
258  for (long j=0;j<cols;j++) {
259  sum += pattern(i,j) * _averaging_scales(i,j);
260  }
261  }
262  long len = rows*cols;
263  return sum/(len*2.0 / pi());
264  }
265 
266  nec_float sd(const real_matrix& pattern, nec_float _mean) const {
267  nec_float sum = 0.0;
268  long rows = pattern.rows();
269  long cols = pattern.cols();
270 
271  for (long i=0;i<rows;i++) {
272  for (long j=0;j<cols;j++) {
273  nec_float diff = pattern(i,j) - _mean;
274  sum += diff*diff * _averaging_scales(i,j);
275  }
276  }
277  long len = rows*cols;
278  return std::sqrt(sum/(len*2.0 / pi()));
279  }
280 
281 
282 public:
283  nec_float get_gain_max() const {
284  return _power_gain_tot.maxCoeff();
285  }
286 
287  nec_float get_gain_min() const {
288  return _power_gain_tot.minCoeff();
289  }
290 
291  nec_float get_gain_mean() const {
292  return mean(_power_gain_tot);
293  }
294 
295  nec_float get_gain_sd() const {
296  nec_float _mean = get_gain_mean();
297  return sd(_power_gain_tot, _mean);
298  }
299 
300  /********************** RHCP ********************************/
301  nec_float get_gain_rhcp_max() const {
302  return _power_gain_rhcp.maxCoeff();
303  }
304 
305  nec_float get_gain_rhcp_min() const {
306  return _power_gain_rhcp.minCoeff();
307  }
308 
309  nec_float get_gain_rhcp_mean() const {
310  return mean(_power_gain_rhcp);
311  }
312 
313  nec_float get_gain_rhcp_sd() const {
314  nec_float _mean = get_gain_rhcp_mean();
315  return sd(_power_gain_rhcp, _mean);
316  }
317 
318  /********************** LHCP ********************************/
319  nec_float get_gain_lhcp_max() const {
320  return _power_gain_lhcp.maxCoeff();
321  }
322 
323  nec_float get_gain_lhcp_min() const {
324  return _power_gain_lhcp.minCoeff();
325  }
326 
327  nec_float get_gain_lhcp_mean() const {
328  return mean(_power_gain_lhcp);
329  }
330 
331  nec_float get_gain_lhcp_sd() const {
332  nec_float _mean = get_gain_lhcp_mean();
333  return sd(_power_gain_lhcp, _mean);
334  }
335 
336  /* End of Statistics functions for the C interface */
337 
338 
339 
342  nec_float get_theta(int theta_index) const {
343  return (m_theta_start + delta_theta*theta_index);
344  }
345 
348  int get_ntheta() const {
349  return (n_theta);
350  }
351 
354  nec_float get_phi(int phi_index) const {
355  return (m_phi_start + delta_phi*phi_index);
356  }
357 
360  int get_nphi() const {
361  return (n_phi);
362  }
363 
366  nec_float get_power_gain(int theta_index, int phi_index) const {
367  return _gain(theta_index, phi_index);
368  }
369 
372  nec_float get_power_gain_vert(int theta_index, int phi_index) const {
373  return _power_gain_vert(theta_index, phi_index);
374  }
375 
378  nec_float get_power_gain_horiz(int theta_index, int phi_index) const {
379  return _power_gain_horiz(theta_index, phi_index);
380  }
381 
384  nec_float get_power_gain_tot(int theta_index, int phi_index) const {
385  return _power_gain_tot(theta_index, phi_index);
386  }
387 
390  nec_float get_power_gain_rhcp(int theta_index, int phi_index) const {
391  nec_float a = get_pol_axial_ratio(theta_index, phi_index);
392  nec_float dbi = get_power_gain_tot(theta_index, phi_index);
393  if (get_pol_sense(theta_index, phi_index) == POL_RIGHT)
394  a = -a;
395 
396  nec_float f = (1-2*a+a*a)/(2*(1+a*a));
397  return dbi + 10*log10(f);
398  }
399 
402  nec_float get_power_gain_lhcp(int theta_index, int phi_index) const {
403  nec_float a = get_pol_axial_ratio(theta_index, phi_index);
404  nec_float dbi = get_power_gain_tot(theta_index, phi_index);
405  if (get_pol_sense(theta_index, phi_index) == POL_RIGHT)
406  a = -a;
407 
408  nec_float f = (1+2*a+a*a)/(2*(1+a*a));
409  return dbi + 10*log10(f);
410  }
411 
412 private:
413 
414  int get_index(int theta_index, int phi_index) const;
415 
416  bool m_analysis_done;
417 
418  int n_theta, n_phi;
419 
420  nec_float m_theta_start, delta_theta;
421  nec_float m_phi_start, delta_phi;
422 
423  int _ifar;
424 
425  nec_float m_range;
426 
427  nec_float _wavelength;
428  nec_float _pinr;
429  nec_float _pnlr;
430 
431  nec_float _average_power_gain;
432  nec_float _average_power_solid_angle;
433  nec_float _maximum_gain;
434 
435  int m_rp_normalization;
436  int m_rp_output_format;
437  int m_rp_power_average;
438  int m_rp_ipd;
439 
440  nec_float m_rp_gnor;
441 
442  real_matrix _gain;
443  real_matrix _power_gain_lhcp;
444  real_matrix _power_gain_rhcp;
445  real_matrix _power_gain_vert;
446  real_matrix _power_gain_horiz;
447  real_matrix _power_gain_tot;
448  real_matrix _polarization_axial_ratio;
449  real_matrix _polarization_tilt;
450  real_matrix _averaging_scales;
451  int_matrix _polarization_sense_index;
452 
453  complex_matrix _e_theta;
454  complex_matrix _e_phi;
455  complex_matrix _e_r;
456 
457  void write_to_file_aux(ostream& os);
458 
459  nec_float get_gain_normalization_factor(nec_float gnor);
460 
461  void write_normalized_gain(ostream& os);
462 
463  nec_ground m_ground;
464  c_plot_card m_plot_card;
465 };
466 
467 #endif /* __nec_radiation_pattern__ */
nec_float get_phi(int phi_index) const
Get the phi angle corresponding to the phi_index.
Definition: nec_radiation_pattern.h:354
nec_float get_power_gain_vert(int theta_index, int phi_index) const
Get a power gain (vertical) from the radiation pattern.
Definition: nec_radiation_pattern.h:372
nec_float get_ephi_magnitude(int theta_index, int phi_index)
Get the magnitude of E(PHI)
Definition: nec_radiation_pattern.h:145
nec_float get_etheta_magnitude(int theta_index, int phi_index)
Get the magnitude of E(THETA)
Definition: nec_radiation_pattern.h:127
real_array get_theta_angles() const
Definition: nec_radiation_pattern.h:190
nec_float get_ephi_phase(int theta_index, int phi_index)
Get the phase (in degrees) of E(PHI)
Definition: nec_radiation_pattern.h:151
nec_float get_theta(int theta_index) const
Get the theta angle corresponding to the theta_index.
Definition: nec_radiation_pattern.h:342
nec_float get_power_gain_horiz(int theta_index, int phi_index) const
Get a power gain (horizontal) from the radiation pattern.
Definition: nec_radiation_pattern.h:378
real_array get_phi_angles() const
Definition: nec_radiation_pattern.h:206
T minCoeff() const
return the largest element of the array
Definition: safe_array.h:148
nec_float get_power_gain(int theta_index, int phi_index) const
Get a total power gain from the radiation pattern.
Definition: nec_radiation_pattern.h:366
nec_float get_power_gain_lhcp(int theta_index, int phi_index) const
Get the power gain if the antenna were receiving LHCP signals.
Definition: nec_radiation_pattern.h:402
complex_array get_e_theta()
Return a complex array for the electric field E(THETA)
Definition: nec_radiation_pattern.h:139
T maxCoeff() const
return the largest element of the array
Definition: safe_array.h:134
Definition: c_plot_card.h:44
void analyze(nec_context *in_context)
Generate the data for the radiation pattern.
Definition: nec_radiation_pattern.cpp:229
nec_float get_power_gain_tot(int theta_index, int phi_index) const
Get a power gain (total dBi) from the radiation pattern.
Definition: nec_radiation_pattern.h:384
Definition: nec_radiation_pattern.h:49
int get_ntheta() const
Get the number of theta angles.
Definition: nec_radiation_pattern.h:348
nec_float get_etheta_phase(int theta_index, int phi_index)
Get the phase (in degrees) of E(THETA)
Definition: nec_radiation_pattern.h:133
complex_array get_e_phi()
Return a complex array for the electric field E(PHI)
Definition: nec_radiation_pattern.h:157
nec_float get_power_gain_rhcp(int theta_index, int phi_index) const
Get the power gain if the antenna were receiving RHCP signals.
Definition: nec_radiation_pattern.h:390
Definition: nec_results.h:230
int get_nphi() const
Get the number of phi angles.
Definition: nec_radiation_pattern.h:360
Container for an nec2++ simulation.
Definition: nec_context.h:60
nec_float get_pol_axial_ratio(int theta_index, int phi_index) const
Get the polarization axial ratio.
Definition: nec_radiation_pattern.h:106
int get_pol_sense(int theta_index, int phi_index) const
Get the polarization sense.
Definition: nec_radiation_pattern.h:121
Definition: nec_ground.h:59