1 /*
2 * xnec2c - GTK2-based version of nec2c, the C translation of NEC2
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 /******* Translated to the C language by N. Kyriazis 20 Aug 2003 ******
20
21 Program NEC(input,tape5=input,output,tape11,tape12,tape13,tape14,
22 tape15,tape16,tape20,tape21)
23
24 Numerical Electromagnetics Code (NEC2) developed at Lawrence
25 Livermore lab., Livermore, CA. (contact G. Burke at 415-422-8414
26 for problems with the NEC code. For problems with the vax implem-
27 entation, contact J. Breakall at 415-422-8196 or E. Domning at 415
28 422-5936)
29 file created 4/11/80
30
31 *********** Notice **********
32 This computer code material was prepared as an account of work
33 sponsored by the United States government. Neither the United
34 States nor the United States Department Of Energy, nor any of
35 their employees, nor any of their contractors, subcontractors,
36 or their employees, makes any warranty, express or implied, or
37 assumes any legal liability or responsibility for the accuracy,
38 completeness or usefulness of any information, apparatus, product
39 or process disclosed, or represents that its use would not infringe
40 privately-owned rights.
41
42 ***********************************************************************/
43
44 #include "input.h"
45 #include "shared.h"
46
47 /*------------------------------------------------------------------------*/
48
49 /* Read_Comments()
50 *
51 * Reads CM comment cards from input file
52 */
53 gboolean
Read_Comments(void)54 Read_Comments( void )
55 {
56 char ain[3], line_buf[LINE_LEN];
57
58
59 /* Look for CM or CE card */
60 do
61 {
62 /* read a line from input file */
63 if( Load_Line(line_buf, input_fp) == EOF )
64 {
65 fprintf( stderr, "xnec2c: Read_Comments():"
66 "unexpected EOF (End of File)\n" );
67 stop( _("Read_Comments(): Error reading Comments\n"\
68 "Unexpected EOF (End of File)"), ERR_OK );
69 return( FALSE );
70 }
71
72 /* Check that comment line is not short */
73 if( strlen(line_buf) < 2 )
74 {
75 fprintf( stderr, "xnec2c: Read_Comments():"
76 "error reading Comments: "
77 "Comment mnemonic short or missing\n" );
78 stop( _("Read_Comments(): Error reading Comments\n"\
79 "Comment mnemonic short or missing"), ERR_OK );
80 return( FALSE );
81 }
82
83 /* separate card's id mnemonic */
84 Strlcpy( ain, line_buf, sizeof(ain) );
85
86 /* Check for incorrect mnemonic */
87 if( (strcmp(ain, "CM") != 0) && (strcmp(ain, "CE") != 0) )
88 {
89 stop( _("Read_Comments():\n"\
90 " Error reading input file\n"\
91 "Comment mnemonic incorrect"), ERR_OK );
92 return( FALSE );
93 }
94 }
95 while( (strcmp(ain, "CE") != 0) );
96
97 return( TRUE );
98 } /* Read_Comments() */
99
100 /*-----------------------------------------------------------------------*/
101
102 /* Read_Geometry()
103 *
104 * Reads geometry data from input file
105 */
106 gboolean
Read_Geometry(void)107 Read_Geometry( void )
108 {
109 int idx;
110 size_t mreq;
111
112 /* Moved here from Read_Commands() */
113 matpar.imat=0;
114 data.n = data.m = 0;
115 if( !datagn() ) return( FALSE );
116
117 /* Memory allocation for temporary buffers */
118 mreq = (size_t)data.npm * sizeof(double);
119 mem_realloc( (void **)&save.xtemp, mreq, "in input.c" );
120 mem_realloc( (void **)&save.ytemp, mreq, "in input.c" );
121 mem_realloc( (void **)&save.ztemp, mreq, "in input.c" );
122 mem_realloc( (void **)&save.bitemp, mreq, "in input.c" );
123 if( data.n > 0 )
124 {
125 mreq = (size_t)data.n * sizeof(double);
126 mem_realloc( (void **)&save.sitemp, mreq, "in input.c" );
127 }
128
129 /* Memory allocation for primary interacton matrix. */
130 mreq = (size_t)(data.np2m * (data.np + 2 * data.mp)) * sizeof(complex double);
131 mem_realloc( (void **)&cm, mreq, "in input.c" );
132
133 /* Memory allocation for current buffers */
134 mreq = (size_t)data.npm * sizeof( double);
135 mem_realloc( (void **)&crnt.air, mreq, "in input.c" );
136 mem_realloc( (void **)&crnt.aii, mreq, "in input.c" );
137 mem_realloc( (void **)&crnt.bir, mreq, "in input.c" );
138 mem_realloc( (void **)&crnt.bii, mreq, "in input.c" );
139 mem_realloc( (void **)&crnt.cir, mreq, "in input.c" );
140 mem_realloc( (void **)&crnt.cii, mreq, "in input.c" );
141 mreq = (size_t)data.np3m * sizeof( complex double);
142 mem_realloc( (void **)&crnt.cur, mreq, "in input.c" );
143
144 /* Memory allocation for loading buffers */
145 mreq = (size_t)data.npm * sizeof(complex double);
146 mem_realloc( (void **)&zload.zarray, mreq, "in input.c" );
147
148 /* Save segment and patch data for freq scaling */
149 if( data.n > 0 )
150 for( idx = 0; idx < data.n; idx++ )
151 {
152 save.xtemp[idx] = data.x[idx];
153 save.ytemp[idx] = data.y[idx];
154 save.ztemp[idx] = data.z[idx];
155 save.sitemp[idx] = data.si[idx];
156 save.bitemp[idx] = data.bi[idx];
157 }
158
159 if( data.m > 0 )
160 for( idx = 0; idx < data.m; idx++ )
161 {
162 int j;
163
164 j = idx + data.n;
165 save.xtemp[j] = data.px[idx];
166 save.ytemp[j] = data.py[idx];
167 save.ztemp[j] = data.pz[idx];
168 save.bitemp[j] = data.pbi[idx];
169 }
170
171 return( TRUE );
172 } /* Read_Geometry() */
173
174 /*------------------------------------------------------------------------*/
175
176 /* Read_Commands()
177 *
178 * Reads commands from input file and stores
179 * them for later execution by user command
180 */
181 gboolean
Read_Commands(void)182 Read_Commands( void )
183 {
184 /* input card mnemonic list */
185 char *atst[NUM_CMNDS] =
186 {
187 "CM", "CP", "EK", "EN", "EX", \
188 "FR", "GD", "GN", "KH", "LD", \
189 "NE", "NH", "NT", "PQ", "PT", \
190 "RP", "SY", "TL", "XQ"
191 };
192
193 char ain[3];
194 double tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
195 int
196 mpcnt, itmp1, itmp2, itmp3, itmp4,
197 ain_num; /* My addition, ain mnemonic as a number */
198 size_t mreq; /* My addition, size req. for malloc's */
199
200 /* initializations etc from original fortran code */
201 mpcnt = 0;
202
203 /* Matrix parameters */
204 if( matpar.imat == 0)
205 {
206 netcx.neq = data.n+2*data.m;
207 netcx.neq2 = 0;
208 }
209
210 /* default values for input parameters and flags */
211 calc_data.rkh = 1.0;
212 calc_data.iexk = 0;
213 calc_data.iped = 0;
214 calc_data.nfrq = 1;
215 calc_data.fmhz = CVEL;
216 save.fmhz = CVEL;
217 calc_data.mxfrq = 0.0;
218 fpat.dth = 0.0;
219 fpat.thets = 0.0;
220 fpat.ixtyp = 0;
221 fpat.nfeh = 0;
222 fpat.nrx = 0;
223 fpat.nry = 0;
224 fpat.nry = 0;
225 fpat.nth = 0;
226 fpat.nph = 0;
227 fpat.near = -1;
228 gnd.ifar = -1;
229 gnd.zrati = CPLX_10;
230 gnd.ksymp = 1;
231 gnd.nradl = 0;
232 gnd.iperf = 0;
233 netcx.nonet = 0;
234 netcx.ntsol = 0;
235 netcx.masym = 0;
236 netcx.npeq = data.np+2*data.mp;
237
238 /* My additions */
239 vsorc.nvqd = 0;
240 vsorc.nsant = 0;
241 zload.nldseg = 0;
242 zload.nload = 0;
243
244 /* Allocate some buffers */
245 mreq = (size_t)data.np2m * sizeof(int);
246 mem_realloc( (void **)&save.ip, mreq, "in input.c" );
247
248 /* Memory allocation for symmetry array */
249 smat.nop = netcx.neq/netcx.npeq;
250 mreq = (size_t)(smat.nop * smat.nop) * sizeof( complex double);
251 mem_realloc( (void **)&smat.ssx, mreq, "in input.c" );
252
253 /* main input section, exits at various points */
254 /* depending on error conditions or end of job */
255 while( TRUE )
256 {
257 /* Main input section - standard read statement - jumps */
258 /* to appropriate section for specific parameter set up */
259 if( !readmn(
260 ain, &itmp1, &itmp2, &itmp3, &itmp4,
261 &tmp1, &tmp2, &tmp3, &tmp4, &tmp5, &tmp6) )
262 return( FALSE );
263
264 mpcnt++;
265
266 /* identify command card id mnemonic */
267 for( ain_num = 0; ain_num < NUM_CMNDS; ain_num++ )
268 if( strncmp( ain, atst[ain_num], 2) == 0 )
269 break;
270
271 /* take action according to card id mnemonic */
272 switch( ain_num )
273 {
274 case CM: /* "cm" card ignored, comments in data cards as in NEC4 */
275 fprintf( stderr, "xnec2c: Read_Commands():"
276 " ignoring CM card in commands\n" );
277 stop( _("Read_Commands(): Ignoring CM card in commands"),
278 ERR_OK );
279 continue;
280
281 case CP: /* "cp" card ignored, maximum coupling between antennas */
282 stop( _("Read_Commands(): CP card is ignored\n"\
283 "Coupling calculation not implemented"), ERR_OK );
284 continue; /* continue card input loop */
285
286 case EK: /* "ek" card, extended thin wire kernel option */
287 if( itmp1 == -1)
288 calc_data.iexk = 0;
289 else
290 calc_data.iexk = 1;
291 continue; /* continue card input loop */
292
293 case EN: /* "en" card, end data input, no action */
294 break;
295
296 case EX: /* "ex" card, excitation parameters */
297 netcx.masym = itmp4/10;
298 fpat.ixtyp = itmp1;
299
300 /* Applied E field or current discontinuity */
301 if( (fpat.ixtyp == 0) || (fpat.ixtyp == 5) )
302 {
303 netcx.ntsol = 0;
304
305 /* Current discontinuity E source */
306 if( fpat.ixtyp == 5 )
307 {
308 vsorc.nvqd++;
309 mreq = (size_t)vsorc.nvqd * sizeof(int);
310 mem_realloc( (void **)&vsorc.ivqd, mreq, "in input.c" );
311 mem_realloc( (void **)&vsorc.iqds, mreq, "in input.c" );
312 mreq = (size_t)vsorc.nvqd * sizeof(complex double);
313 mem_realloc( (void **)&vsorc.vqd, mreq, "in input.c" );
314 mem_realloc( (void **)&vsorc.vqds, mreq, "in input.c" );
315 {
316 int indx = vsorc.nvqd-1;
317
318 if( (vsorc.ivqd[indx] = isegno(itmp2, itmp3)) < 0 )
319 return( FALSE ); /* my addition, error */
320 vsorc.vqd[indx]= cmplx( tmp1, tmp2);
321 if( cabs( vsorc.vqd[indx]) < 1.0e-20)
322 vsorc.vqd[indx] = CPLX_10;
323
324 calc_data.iped = itmp4- netcx.masym*10;
325 calc_data.zpnorm = tmp3;
326 }
327
328 } /* if( fpat.ixtyp == 5) */
329 else
330 {
331 /* Else, applied E field */
332 vsorc.nsant++;
333 mreq = (size_t)vsorc.nsant * sizeof(int);
334 mem_realloc( (void **)&vsorc.isant, mreq, "in input.c" );
335 mreq = (size_t)vsorc.nsant * sizeof(complex double);
336 mem_realloc( (void **)&vsorc.vsant, mreq, "in input.c" );
337 {
338 int indx = vsorc.nsant-1;
339
340 if( (vsorc.isant[indx] = isegno(itmp2, itmp3)) < 0 )
341 return( FALSE ); /* my addition, error condition */
342 vsorc.vsant[indx]= cmplx( tmp1, tmp2);
343 if( cabs( vsorc.vsant[indx]) < 1.0e-20)
344 vsorc.vsant[indx] = CPLX_10;
345
346 calc_data.iped= itmp4- netcx.masym*10;
347 calc_data.zpnorm= tmp3;
348 if( (calc_data.iped == 1) && (calc_data.zpnorm > 0.0) )
349 calc_data.iped=2;
350 }
351
352 } /* if( fpat.ixtyp == 5 ) */
353
354 } /* if( (fpat.ixtyp == 0) || (fpat.ixtyp == 5) ) */
355 else
356 {
357 /* For fpat.ixtyp = 2|3|4 = incident field or current source */
358 calc_data.nthi= itmp2;
359 calc_data.nphi= itmp3;
360 calc_data.xpr1= tmp1;
361 calc_data.xpr2= tmp2;
362 calc_data.xpr3= tmp3;
363 calc_data.xpr4= tmp4;
364 calc_data.xpr5= tmp5;
365 calc_data.xpr6= tmp6;
366 vsorc.nsant=0;
367 vsorc.nvqd=0;
368 calc_data.thetis= tmp1;
369 calc_data.phiss= tmp2;
370 }
371
372 SetFlag( ENABLE_EXCITN );
373 continue; /* continue card input loop */
374
375 case FR: /* "fr" card, frequency parameters */
376 if( !CHILD )
377 {
378 calc_data.nfrq = itmp2;
379 if( calc_data.nfrq <= 0)
380 calc_data.nfrq = 1;
381 }
382 else calc_data.nfrq = 1;
383
384 /* Allocate normalization buffer */
385 {
386 mreq = (size_t)calc_data.nfrq * sizeof(double);
387 mem_realloc( (void **)&impedance_data.zreal, mreq, "in input.c" );
388 mem_realloc( (void **)&impedance_data.zimag, mreq, "in input.c" );
389 mem_realloc( (void **)&impedance_data.zmagn, mreq, "in input.c" );
390 mem_realloc( (void **)&impedance_data.zphase, mreq, "in input.c" );
391 mem_realloc( (void **)&save.freq, mreq, "in input.c" );
392 mreq = (size_t)calc_data.nfrq * sizeof(char);
393 mem_realloc( (void **)&save.fstep, mreq, "in input.c" );
394 }
395
396 if( CHILD ) continue;
397
398 calc_data.ifrq = itmp1;
399 calc_data.fmhz = save.fmhz = tmp1;
400
401 /* My addition, max frequency */
402 if( itmp1 == 0 )
403 calc_data.mxfrq =
404 (double)tmp1 + (double)tmp2 * (double)(itmp2-1);
405 else if( itmp1 == 1 )
406 calc_data.mxfrq =
407 (double)tmp1 * pow( (double)tmp2, (double)(itmp2-1) );
408
409 /* My addition, extra features in "fr" card. */
410 /* Specifies lower and upper value of frequency range */
411 if( calc_data.ifrq == 2 )
412 {
413 calc_data.nfrq++;
414 /* Linear frequency stepping */
415 if( calc_data.nfrq > 1 )
416 calc_data.delfrq =
417 (tmp2 - tmp1)/(double)(calc_data.nfrq-1);
418 calc_data.ifrq = 0;
419 calc_data.mxfrq = (double)tmp2; /* Max frequency */
420 }
421 else if( calc_data.ifrq == 3 )
422 {
423 calc_data.nfrq++;
424 /* Multiplicative frequency stepping */
425 if( calc_data.nfrq > 1 )
426 calc_data.delfrq =
427 pow( (tmp2-tmp1), 1.0/(double)(calc_data.nfrq-1) );
428 calc_data.ifrq = 1;
429 calc_data.mxfrq = (double)tmp2; /* Max frequency */
430 }
431 else calc_data.delfrq = tmp2;
432
433 if( calc_data.iped == 1)
434 calc_data.zpnorm = 0.0;
435 continue; /* continue card input loop */
436
437 case GD: /* "gd" card, ground representation */
438 fpat.epsr2 = tmp1;
439 fpat.sig2 = tmp2;
440 fpat.clt = tmp3;
441 fpat.cht = tmp4;
442 continue; /* continue card input loop */
443
444 case GN: /* "gn" card, ground parameters under the antenna */
445 gnd.iperf = itmp1;
446 gnd.nradl = itmp2;
447 gnd.ksymp = 2;
448 save.epsr = tmp1;
449 save.sig = tmp2;
450
451 /* Theta must be less than 90 if ground present */
452 double test = (double)(fpat.nth - 1) * fpat.dth + fpat.thets;
453 if( (gnd.ifar != 1) && (test > 90.0) )
454 {
455 fprintf( stderr,
456 "xnec2c: Read_Commands(): theta > 90 deg. with ground specified\n" );
457 stop( _("Read_Commands(): Theta > 90 deg with ground specified\n"\
458 "Please check RP card data and correct"), ERR_OK );
459 return( FALSE );
460 }
461
462 if( gnd.nradl > 0)
463 {
464 if( gnd.iperf == 2)
465 {
466 fprintf( stderr,
467 "xnec2c: Read_Commands(): radial wire g.s. approximation\n"
468 "may not be used with Sommerfeld ground option\n" );
469 stop( _("Read_Commands(): radial wire g.s. approximation\n"\
470 "may not be used with Sommerfeld ground option"), ERR_OK );
471 return( FALSE );
472 }
473
474 save.scrwlt = tmp3;
475 save.scrwrt = tmp4;
476 continue; /* continue card input loop */
477 } /* if( gnd.nradl > 0) */
478 else
479 {
480 save.scrwlt = 0.0;
481 save.scrwrt = 0.0;
482 }
483
484 fpat.epsr2 = tmp3;
485 fpat.sig2 = tmp4;
486 fpat.clt = tmp5;
487 fpat.cht = tmp6;
488 continue; /* continue card input loop */
489
490 case KH: /* "kh" card, matrix integration limit */
491 calc_data.rkh = tmp1;
492 continue; /* continue card input loop */
493
494 case LD: /* "ld" card, loading parameters */
495 {
496 int idx, nseg;
497
498 /* Reallocate loading buffers */
499 zload.nload++;
500 mreq = (size_t)zload.nload * sizeof(int);
501 mem_realloc( (void **)&calc_data.ldtyp, mreq, "in input.c" );
502 mem_realloc( (void **)&calc_data.ldtag, mreq, "in input.c" );
503 mem_realloc( (void **)&calc_data.ldtagf, mreq, "in input.c" );
504 mem_realloc( (void **)&calc_data.ldtagt, mreq, "in input.c" );
505
506 mreq = (size_t)zload.nload * sizeof(double);
507 mem_realloc( (void **)&calc_data.zlr, mreq, "in input.c" );
508 mem_realloc( (void **)&calc_data.zli, mreq, "in input.c" );
509 mem_realloc( (void **)&calc_data.zlc, mreq, "in input.c" );
510
511 idx = zload.nload-1;
512 calc_data.ldtyp[idx]= itmp1;
513 calc_data.ldtag[idx]= itmp2;
514 if( itmp4 == 0) itmp4= itmp3;
515 calc_data.ldtagf[idx]= itmp3;
516 calc_data.ldtagt[idx]= itmp4;
517
518 if( itmp4 < itmp3 )
519 {
520 fprintf( stderr,
521 "xnec2c: Read_Commands(): data fault on loading card no %d\n"
522 "itag step1 %d is greater than itag step2 %d\n",
523 zload.nload, itmp3, itmp4 );
524 stop( _("Read_Commands(): Data fault on loading card\n"\
525 "itag step1 is greater than itag step2"), ERR_OK );
526 return( FALSE );
527 }
528
529 calc_data.zlr[idx]= tmp1;
530 calc_data.zli[idx]= tmp2;
531 calc_data.zlc[idx]= tmp3;
532
533 /*** My addition, for drawing structure ***/
534 /* Work out absolute seg number of loaded segments (!) */
535 if( itmp1 == -1 ) /* Null all loads */
536 zload.nldseg = 0;
537 else if( itmp2 == 0 ) /* No tag num */
538 {
539 if( itmp3 == 0 ) /* All segs loaded */
540 {
541 nseg = data.n;
542 mreq = (size_t)(nseg + zload.nldseg) * sizeof(int);
543 mem_realloc( (void **)&zload.ldsegn, mreq, "in input.c" );
544 mem_realloc( (void **)&zload.ldtype, mreq, "in input.c" );
545 for( idx = 0; idx < nseg; idx++ )
546 {
547 zload.ldtype[zload.nldseg] = itmp1;
548 zload.ldsegn[zload.nldseg++] = idx+1;
549 }
550 }
551 else /* Absolute seg num specified */
552 {
553 nseg = itmp4 - itmp3 + 1;
554 if( nseg <= 0 ) nseg = 1;
555 mreq = (size_t)(nseg + zload.nldseg) * sizeof(int);
556 mem_realloc( (void **)&zload.ldsegn, mreq, "in input.c" );
557 mem_realloc( (void **)&zload.ldtype, mreq, "in input.c" );
558 for( idx = 0; idx < nseg; idx++ )
559 {
560 zload.ldtype[zload.nldseg] = itmp1;
561 zload.ldsegn[zload.nldseg++] = itmp3+idx;
562 }
563 }
564
565 } /* if( itmp2 == 0 ) */
566 else /* Tag num specified */
567 {
568 if( (itmp3 == 0) && (itmp4 == 0) ) /* All segs of tag loaded */
569 {
570 for( idx = 0; idx < data.n; idx++ )
571 if( data.itag[idx] == itmp2 )
572 {
573 mreq = (size_t)(zload.nldseg + 1) * sizeof(int);
574 mem_realloc( (void **)&zload.ldsegn, mreq, "in input.c" );
575 mem_realloc( (void **)&zload.ldtype, mreq, "in input.c" );
576 zload.ldtype[zload.nldseg] = itmp1;
577 zload.ldsegn[zload.nldseg++] = idx+1;
578 }
579 }
580 else /* A range of segs of tag loaded */
581 {
582 nseg = itmp4 - itmp3 + 1;
583 if( nseg <= 0 ) nseg = 1; /* Just one seg of tag (=itmp3) */
584 mreq = (size_t)(zload.nldseg + nseg) * sizeof(int);
585 mem_realloc( (void **)&zload.ldsegn, mreq, "in input.c" );
586 mem_realloc( (void **)&zload.ldtype, mreq, "in input.c" );
587 for( idx = 0; idx < nseg; idx++ )
588 {
589 zload.ldtype[zload.nldseg] = itmp1;
590 if( (zload.ldsegn[zload.nldseg++] =
591 isegno(itmp2, itmp3+idx)) < 0 )
592 return( FALSE );
593 }
594 }
595 }
596 } /* case 8: */
597 continue; /* continue card input loop */
598
599 case NE: case NH: /* "ne"/"nh" cards, near field calculation parameters */
600 if( ain_num == 11 )
601 fpat.nfeh |= NEAR_HFIELD;
602 else
603 fpat.nfeh |= NEAR_EFIELD;
604
605 fpat.near = itmp1;
606 fpat.nrx = itmp2;
607 fpat.nry = itmp3;
608 fpat.nrz = itmp4;
609 fpat.xnr = tmp1;
610 fpat.ynr = tmp2;
611 fpat.znr = tmp3;
612 fpat.dxnr = tmp4;
613 fpat.dynr = tmp5;
614 fpat.dznr = tmp6;
615
616 if( (fpat.nrx > 0) &&
617 (fpat.nry > 0) &&
618 (fpat.nrz > 0) &&
619 (fpat.near != -1) )
620 {
621 SetFlag( ENABLE_NEAREH );
622 SetFlag( ALLOC_NEAREH_BUFF );
623 SetFlag( ALLOC_PNTING_BUFF );
624 }
625
626 /* Because of the interactive GUI, program
627 * execution is not triggered by any card */
628 continue; /* continue card input loop */
629
630 case NT: case TL: /* "nt" & "tl" cards, network parameters */
631 {
632 int idx;
633
634 /* Re-allocate network buffers */
635 netcx.nonet++;
636 mreq = (size_t)netcx.nonet * sizeof(int);
637 mem_realloc( (void **)&netcx.ntyp, mreq, "in input.c" );
638 mem_realloc( (void **)&netcx.iseg1, mreq, "in input.c" );
639 mem_realloc( (void **)&netcx.iseg2, mreq, "in input.c" );
640
641 mreq = (size_t)netcx.nonet * sizeof(double);
642 mem_realloc( (void **)&netcx.x11r, mreq, "in input.c" );
643 mem_realloc( (void **)&netcx.x11i, mreq, "in input.c" );
644 mem_realloc( (void **)&netcx.x12r, mreq, "in input.c" );
645 mem_realloc( (void **)&netcx.x12i, mreq, "in input.c" );
646 mem_realloc( (void **)&netcx.x22r, mreq, "in input.c" );
647 mem_realloc( (void **)&netcx.x22i, mreq, "in input.c" );
648
649 idx = netcx.nonet-1;
650 if( ain_num == 12 )
651 netcx.ntyp[idx] = 1;
652 else
653 {
654 netcx.ntyp[idx] = 2;
655 if( tmp1 == 0.0 )
656 {
657 fprintf( stderr,
658 "xnec2c: Read_Commands(): Transmission Line impedance = 0\n"
659 "is not valid. Please correct NT or TL card\n" );
660 stop( _("Read_Commands(): Transmission Line impedance = 0\n"\
661 "is not valid. Please correct NT or TL card"), ERR_OK );
662 return( FALSE );
663 }
664 }
665
666 if( ((netcx.iseg1[idx] = isegno(itmp1, itmp2)) < 0) ||
667 ((netcx.iseg2[idx] = isegno(itmp3, itmp4)) < 0) )
668 {
669 fprintf( stderr,
670 "xnec2c: Read_Commands(): Segment number error in TL or NT card\n" );
671 stop( _("Read_Commands(): Segment number\n"\
672 "error in NT or TL card"), ERR_OK );
673 return( FALSE );
674 }
675 netcx.x11r[idx] = tmp1;
676 netcx.x11i[idx] = tmp2;
677 netcx.x12r[idx] = tmp3;
678 netcx.x12i[idx] = tmp4;
679 netcx.x22r[idx] = tmp5;
680 netcx.x22i[idx] = tmp6;
681
682 if( (netcx.ntyp[idx] == 1) || (tmp1 > 0.0) )
683 continue; /* continue card input loop */
684
685 netcx.ntyp[idx] = 3;
686 netcx.x11r[idx] = -tmp1;
687 continue; /* continue card input loop */
688
689 } /* case 12: case 17: */
690
691 case PQ: case PT: /* "pq" and "pt" cards ignored, no printing */
692 fprintf( stderr,
693 "xnec2c: Read_Commands(): PQ and PT cards are ignored\n"
694 "Printing to file not implemented\n" );
695 stop( _("Read_Commands(): PQ and PT cards are ignored\n"\
696 "Printing to file not implemented"), ERR_OK );
697 continue; /* continue card input loop */
698
699 case RP: /* "rp" card, standard observation angle parameters */
700 if( itmp1 == 1 )
701 {
702 fprintf( stderr,
703 "xnec2c: Read_Commands(): Surface wave option (I1=1)\n"
704 "of RP command not implemented\n" );
705 stop( _("Read_Commands(): Surface wave option (I1=1)\n"\
706 "of RP command not implemented"), ERR_OK );
707 return( FALSE );
708 }
709
710 gnd.ifar = itmp1;
711 fpat.nth = itmp2;
712 fpat.nph = itmp3;
713
714 if( fpat.nth <= 0)
715 fpat.nth=1;
716 if( fpat.nph <= 0)
717 fpat.nph=1;
718
719 fpat.ipd = itmp4 / 10;
720 fpat.iavp = itmp4 - fpat.ipd*10;
721 fpat.inor = fpat.ipd / 10;
722 fpat.ipd = fpat.ipd - fpat.inor*10;
723 fpat.iax = fpat.inor / 10;
724 fpat.inor = fpat.inor - fpat.iax*10;
725
726 if( fpat.iavp )
727 {
728 fprintf( stderr,
729 "xnec2c: Read_Commands(): Gain averaging (XNDA ***1 or ***2)\n"
730 "of RP command not implemented\n" );
731 stop( _("Read_Commands(): Gain averaging (XNDA ***1 or ***2)\n"\
732 "of RP command not supported"), ERR_OK );
733 return( FALSE );
734 }
735 if( fpat.iax != 0) fpat.iax = 1;
736 if( fpat.ipd != 0) fpat.ipd = 1;
737 fpat.thets = tmp1;
738 fpat.phis = tmp2;
739 fpat.dth = tmp3;
740 fpat.dph = tmp4;
741 fpat.rfld = tmp5;
742 fpat.gnor = tmp6;
743
744 /* Theta must be less than 90 if ground present */
745 tmp1 = (double)(fpat.nth - 1) * fpat.dth + fpat.thets;
746 if( (gnd.ksymp == 2) && (gnd.ifar != 1) && (tmp1 > 90.0) )
747 {
748 fprintf( stderr,
749 "xnec2c: Read_Commands(): Theta > 90 deg. with ground specified\n"
750 "Please check RP card data and correct\n" );
751 stop( _("Read_Commands(): Theta > 90 deg. with ground specified\n"\
752 "Please check RP card data and correct"), ERR_OK );
753 return( FALSE );
754 }
755
756 /* Because of the interactive GUI, program
757 * execution is not triggered by any card */
758 continue; /* continue card input loop */
759
760 case SY: /* "sy" TODO Compatibility with 4nec2.
761 Too difficult, may never happen :-( */
762 continue;
763
764 case XQ: /* "xq" execute card */
765 /* Because of the interactive GUI, program
766 * execution is not triggered by any card.
767 * XQ now is the same as EN because of above */
768 if( itmp1 == 0 )
769 break; /* No rad pat, stop reading commands */
770
771 /* Read radiation pattern parameters */
772 gnd.ifar = 0;
773 fpat.rfld = 0.0;
774 fpat.ipd = 0;
775 fpat.iavp = 0;
776 fpat.inor = 0;
777 fpat.iax = 0;
778 fpat.nth = 91;
779 fpat.nph = 1;
780 fpat.thets= 0.0;
781 fpat.phis = 0.0;
782 fpat.dth = 1.0;
783 fpat.dph = 0.0;
784
785 if( itmp1 == 2)
786 fpat.phis = 90.0;
787 else if( itmp1 == 3)
788 {
789 fpat.nph = 2;
790 fpat.dph = 90.0;
791 }
792
793 SetFlag( ENABLE_RDPAT );
794
795 /* Because of the interactive GUI, program
796 * execution is not triggered by any card.
797 * XQ now is the same as EN because of above */
798 break;
799
800 default:
801 fprintf( stderr,
802 "xnec2c: Read_Commands(): faulty data "
803 "card label after geometry section\n" );
804 stop( _("Read_Commands(): Faulty data card\n"\
805 "label after geometry section"), ERR_OK );
806 return( FALSE );
807 } /* switch( ain_num ) */
808
809 /* Disable radiation pattern plots */
810 if( (fpat.nth < 2) || (fpat.nph < 1) || (gnd.ifar == 1) )
811 ClearFlag( ENABLE_RDPAT );
812 else
813 {
814 /* Allocate radiation pattern buffers */
815 Alloc_Rdpattern_Buffers( calc_data.nfrq+1, fpat.nth, fpat.nph );
816 SetFlag( ENABLE_RDPAT );
817 }
818
819 return( TRUE );
820 } /* while( TRUE ) */
821
822 } /* Read_Commands() */
823
824 /*-----------------------------------------------------------------------*/
825
826 gboolean
readmn(char * mn,int * i1,int * i2,int * i3,int * i4,double * f1,double * f2,double * f3,double * f4,double * f5,double * f6)827 readmn( char *mn, int *i1, int *i2, int *i3, int *i4,
828 double *f1, double *f2, double *f3,
829 double *f4, double *f5, double *f6 )
830 {
831 char
832 *line_buf = NULL,
833 *startptr = NULL,
834 *endptr = NULL;
835 int len, i, idx;
836 int nint = 4, nflt = 6;
837 int iarr[4] = { 0, 0, 0, 0 };
838 double rarr[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
839 int eof; /* EOF error flag */
840
841
842 /* Clear return values */
843 *i1 = *i2 = *i3 = *i4 = 0;
844 *f1 = *f2 = *f3 = *f4 = *f5 = *f6 = 0.0;
845
846 /* read a line from input file */
847 mem_alloc((void **)&line_buf, LINE_LEN, "in readmn()");
848 if( line_buf == NULL ) return( FALSE );
849 startptr = line_buf;
850 eof = Load_Line( line_buf, input_fp );
851 if( eof == EOF )
852 {
853 Strlcpy( mn, "EN", 3 );
854 fprintf( stderr,
855 "xnec2c: readmn(): command data card error\n"
856 "Unexpected EOF while reading input file - appending EN card\n" );
857 stop( _("readmn(): Command data card error\n"\
858 "Unexpected EOF while reading input file\n"\
859 "Uppending a default EN card"), ERR_OK );
860 free_ptr( (void **)&startptr );
861 return( FALSE );
862 }
863
864 /* get line length */
865 len = (int)strlen( line_buf );
866
867 /* abort if card's mnemonic too short or missing */
868 if( len < 2 )
869 {
870 Strlcpy( mn, "XX", 3 );
871 fprintf( stderr,
872 "xnec2c: readmn(): command data card error\n"
873 "card's mnemonic code too short or missing\n" );
874 stop( _("readmn(): Command data card error\n"\
875 "Mnemonic code too short or missing"), ERR_OK );
876 free_ptr( (void **)&startptr );
877 return( FALSE );
878 }
879
880 /* extract card's mnemonic code */
881 Strlcpy( mn, line_buf, 3 );
882
883 /* Return if only mnemonic on card */
884 if( len == 2 )
885 {
886 free_ptr( (void **)&startptr );
887 return( TRUE );
888 }
889
890 /* Compatibility with NEC4, comments between data cards */
891 if( strncmp(mn, "CM", 2) == 0 )
892 {
893 free_ptr( (void **)&startptr );
894 return( TRUE );
895 }
896
897 /* check line for spurious characters */
898 for( idx = 2; idx < len; idx++ )
899 {
900 if( ((line_buf[idx] >= '0') &&
901 (line_buf[idx] <= '9')) ||
902 (line_buf[idx] == ' ') ||
903 (line_buf[idx] == '.') ||
904 (line_buf[idx] == ',') ||
905 (line_buf[idx] == '+') ||
906 (line_buf[idx] == '-') ||
907 (line_buf[idx] == 'E') ||
908 (line_buf[idx] == 'e') ||
909 (line_buf[idx] == '\t') ||
910 (line_buf[idx] == '\0') )
911 continue;
912 else
913 break;
914 }
915 if( idx < len )
916 {
917 fprintf( stderr,
918 "xnec2c: readmn(): command data card \"%s\" error\n"
919 "Spurious character '%c' at column %d\n",
920 mn, line_buf[idx], idx+1 );
921 stop( _("readmn(): Command data card error\n"\
922 "Spurious character in command card"), ERR_OK );
923 free_ptr( (void **)&startptr );
924 return( FALSE );
925 }
926
927 /* read integers from line */
928 line_buf += 2;
929 for( i = 0; i < nint; i++ )
930 {
931 /* read an integer from line */
932 iarr[i] = (int)strtol( line_buf, &endptr, 10 );
933 if( *endptr == '\0' ) break;
934 line_buf = endptr + 1;
935 } /* for( i = 0; i < nint; i++ ) */
936
937 /* Return if no floats are specified in the card */
938 if( *endptr == '\0' )
939 {
940 *i1= iarr[0];
941 *i2= iarr[1];
942 *i3= iarr[2];
943 *i4= iarr[3];
944 *f1= rarr[0];
945 *f2= rarr[1];
946 *f3= rarr[2];
947 *f4= rarr[3];
948 *f5= rarr[4];
949 *f6= rarr[5];
950 free_ptr( (void **)&startptr );
951 return( TRUE );
952 }
953
954 /* read doubles from line */
955 for( i = 0; i < nflt; i++ )
956 {
957 /* read a double from line */
958 rarr[i] = Strtod( line_buf, &endptr );
959 if( *endptr == '\0' ) break;
960 line_buf = endptr + 1;
961 } /* for( i = 0; i < nflt; i++ ) */
962
963 /* Return values on normal exit */
964 *i1= iarr[0];
965 *i2= iarr[1];
966 *i3= iarr[2];
967 *i4= iarr[3];
968 *f1= rarr[0];
969 *f2= rarr[1];
970 *f3= rarr[2];
971 *f4= rarr[3];
972 *f5= rarr[4];
973 *f6= rarr[5];
974
975 free_ptr( (void **)&startptr );
976 return( TRUE );
977 } /* readmn() */
978
979 /*-----------------------------------------------------------------------*/
980
981 gboolean
readgm(char * gm,int * i1,int * i2,double * x1,double * y1,double * z1,double * x2,double * y2,double * z2,double * rad)982 readgm( char *gm, int *i1, int *i2, double *x1,
983 double *y1, double *z1, double *x2,
984 double *y2, double *z2, double *rad )
985 {
986 char
987 *line_buf = NULL,
988 *startptr = NULL,
989 *endptr = NULL;
990 int len, i, idx;
991 int nint = 2, nflt = 7;
992 int iarr[2] = { 0, 0 };
993 double rarr[7] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
994 int eof; /* EOF error flag */
995
996
997 /* Clear return values */
998 *i1 = *i2 = 0;
999 *x1 = *y1 = *z1 = *x2 = *y2 = *z2 = *rad = 0.0;
1000
1001 /* read a line from input file */
1002 mem_alloc((void **)&line_buf, LINE_LEN, "in readgm()");
1003 if( line_buf == NULL ) return( FALSE );
1004 startptr = line_buf;
1005 eof = Load_Line( line_buf, input_fp );
1006 if( eof == EOF )
1007 {
1008 Strlcpy( gm, "GE", 3 );
1009 fprintf( stderr,
1010 "xnec2c: readgm(): geometry data card error\n"
1011 "Unexpected EOF while reading input file - appending GE card\n" );
1012 stop( _("readgm(): Geometry data card error\n"\
1013 "Unexpected EOF while reading input file\n"\
1014 "Uppending a default GE card"), ERR_OK );
1015 free_ptr( (void **)&startptr );
1016 return( FALSE );
1017 }
1018
1019 /* get line length */
1020 len = (int)strlen( line_buf );
1021
1022 /* abort if card's mnemonic too short or missing */
1023 if( len < 2 )
1024 {
1025 Strlcpy( gm, "XX", 3 );
1026 fprintf( stderr,
1027 "xnec2c: readgm(): geometry data card error\n"
1028 "card's mnemonic code too short or missing\n" );
1029 stop( _("readgm(): Geometry data card error\n"\
1030 "Card's mnemonic code too short or missing"), ERR_OK );
1031 free_ptr( (void **)&startptr );
1032 return( FALSE );
1033 }
1034
1035 /* extract card's mnemonic code */
1036 Strlcpy( gm, line_buf, 3 );
1037
1038 /* Return if only mnemonic on card */
1039 if( len == 2 )
1040 {
1041 free_ptr( (void **)&startptr );
1042 return( TRUE );
1043 }
1044
1045 /* Compatibility with NEC4,
1046 * comments between data cards */
1047 if( strcmp(gm, "CM") == 0 )
1048 {
1049 free_ptr( (void **)&startptr );
1050 return( TRUE );
1051 }
1052
1053 /* check line for spurious characters */
1054 for( idx = 2; idx < len; idx++ )
1055 {
1056 if( ((line_buf[idx] >= '0') &&
1057 (line_buf[idx] <= '9')) ||
1058 (line_buf[idx] == ' ') ||
1059 (line_buf[idx] == '.') ||
1060 (line_buf[idx] == ',') ||
1061 (line_buf[idx] == '+') ||
1062 (line_buf[idx] == '-') ||
1063 (line_buf[idx] == 'E') ||
1064 (line_buf[idx] == 'e') ||
1065 (line_buf[idx] == '\t') ||
1066 (line_buf[idx] == '\0') )
1067 continue;
1068 else
1069 break;
1070 }
1071 if( idx < len )
1072 {
1073 fprintf( stderr,
1074 "xnec2c: readgm(): geometry data card \"%s\" error\n"
1075 "Spurious character '%c' at column %d\n",
1076 gm, line_buf[idx], idx+1 );
1077 stop( _("readmn(): Geometry data card error\n"\
1078 "Spurious character in command card"), ERR_OK );
1079 free_ptr( (void **)&startptr );
1080 return( FALSE );
1081 }
1082
1083 /* read integers from line */
1084 line_buf += 2;
1085 for( i = 0; i < nint; i++ )
1086 {
1087 /* read an integer from line, reject spurious chars */
1088 iarr[i] = (int)strtol( line_buf, &endptr, 10 );
1089 if( *endptr == '\0' ) break;
1090 line_buf = endptr + 1;
1091 } /* for( i = 0; i < nint; i++ ) */
1092
1093 /* Return if no floats are specified in the card */
1094 if( *endptr == '\0' )
1095 {
1096 *i1 = iarr[0];
1097 *i2 = iarr[1];
1098 *x1 = rarr[0];
1099 *y1 = rarr[1];
1100 *z1 = rarr[2];
1101 *x2 = rarr[3];
1102 *y2 = rarr[4];
1103 *z2 = rarr[5];
1104 *rad= rarr[6];
1105 free_ptr( (void **)&startptr );
1106 return( TRUE );
1107 }
1108
1109 /* read doubles from line */
1110 for( i = 0; i < nflt; i++ )
1111 {
1112 /* read a double from line */
1113 rarr[i] = Strtod( line_buf, &endptr );
1114 if( *endptr == '\0' ) break;
1115 line_buf = endptr + 1;
1116 } /* for( i = 0; i < nflt; i++ ) */
1117
1118 /* Return values on normal exit */
1119 *i1 = iarr[0];
1120 *i2 = iarr[1];
1121 *x1 = rarr[0];
1122 *y1 = rarr[1];
1123 *z1 = rarr[2];
1124 *x2 = rarr[3];
1125 *y2 = rarr[4];
1126 *z2 = rarr[5];
1127 *rad = rarr[6];
1128
1129 free_ptr( (void **)&startptr );
1130 return( TRUE );
1131 } /* readgm() */
1132
1133 /*-----------------------------------------------------------------------*/
1134
1135 /* datagn is the main routine for input of geometry data. */
1136 gboolean
datagn(void)1137 datagn( void )
1138 {
1139 char gm[3];
1140
1141 /* input card mnemonic list */
1142 char *atst[] =
1143 {
1144 "GW", "GX", "GR", "GS", "GE","GM", "SP",\
1145 "SM", "GA", "SC", "GH", "GF", "CT"
1146 };
1147
1148 int nwire, isct, itg, iy=0, iz;
1149 size_t mreq;
1150 int ix, i, ns, gm_num; /* geometry card id as a number */
1151 double rad, xs1, xs2, ys1, ys2, zs1, zs2;
1152 double x3=0, y3=0, z3=0, x4=0, y4=0, z4=0;
1153 double xw1, xw2, yw1, yw2, zw1, zw2;
1154 double dummy;
1155
1156 data.ipsym=0;
1157 nwire=0;
1158 data.n=0;
1159 data.np=0;
1160 data.m=0;
1161 data.mp=0;
1162 isct=0;
1163 structure_proj_params.r_max = 0.0;
1164
1165 /* read geometry data card and branch to */
1166 /* section for operation requested */
1167 do
1168 {
1169 if( !readgm(gm, &itg, &ns, &xw1, &yw1, &zw1, &xw2, &yw2, &zw2, &rad) )
1170 return( FALSE );
1171
1172 /* identify card id mnemonic */
1173 for( gm_num = 0; gm_num < NUM_GEOMN; gm_num++ )
1174 if( strncmp( gm, atst[gm_num], 2) == 0 )
1175 break;
1176
1177 if( gm_num != 9 ) isct=0;
1178
1179 switch( gm_num )
1180 {
1181 case GW: /* "gw" card, generate segment data for straight wire. */
1182 if( Tag_Seg_Error(itg, ns) ) return( FALSE );
1183 nwire++;
1184
1185 if( rad != 0.0)
1186 {
1187 xs1=1.0;
1188 ys1=1.0;
1189 }
1190 else
1191 {
1192 if( !readgm(gm, &ix, &iy, &xs1, &ys1, &zs1,
1193 &dummy, &dummy, &dummy, &dummy) )
1194 return( FALSE );
1195
1196 if( strcmp(gm, "GC" ) != 0 )
1197 {
1198 fprintf( stderr,
1199 "xnec2c: datagn(): geometry data card error "
1200 "no GC card for tapered wire\n" );
1201 stop( _("datagn(): Geometry data error\n"\
1202 "No GC card for tapered wire"), ERR_OK );
1203 return( FALSE );
1204 }
1205
1206 if( (ys1 == 0.0) || (zs1 == 0.0) )
1207 {
1208 fprintf( stderr, "xnec2c: datagn(): geometry GC data card error\n" );
1209 stop( _("datagn(): Geometry GC data card error"), ERR_OK );
1210 return( FALSE );
1211 }
1212
1213 rad= ys1;
1214 ys1= pow( (zs1/ys1), (1.0/(ns-1.0)) );
1215 }
1216
1217 wire( xw1, yw1, zw1, xw2, yw2, zw2, rad, xs1, ys1, ns, itg);
1218 continue;
1219
1220 /* reflect structure along x,y, or z */
1221 /* axes or rotate to form cylinder. */
1222 case GX: /* "gx" card */
1223 if( (ns < 0) || (itg < 0) )
1224 {
1225 fprintf( stderr, "xnec2c: datagn(): geometry GX data card error\n" );
1226 stop( _("datagn(): Geometry GX data card error"), ERR_OK );
1227 return( FALSE );
1228 }
1229
1230 iy= ns/10;
1231 iz= ns- iy*10;
1232 ix= iy/10;
1233 iy= iy- ix*10;
1234
1235 if( ix != 0)
1236 ix=1;
1237 if( iy != 0)
1238 iy=1;
1239 if( iz != 0)
1240 iz=1;
1241
1242 if( !reflc(ix, iy, iz, itg, ns) )
1243 return( FALSE );
1244 continue;
1245
1246 case GR: /* "gr" card */
1247 if( (ns < 0) || (itg < 0) )
1248 {
1249 fprintf( stderr, "xnec2c: datagn(): geometry GR data card error\n" );
1250 stop( _("datagn(): Geometry GR data card error"), ERR_OK );
1251 return( FALSE );
1252 }
1253
1254 ix=-1;
1255 iz = 0;
1256 if( !reflc(ix, iy, iz, itg, ns) )
1257 return( FALSE );
1258 continue;
1259
1260 case GS: /* "gs" card, scale structure dimensions by factor xw1 */
1261 if( (itg > 0) && (ns > 0) && (ns >= itg) )
1262 {
1263 for( i = 0; i < data.n; i++ )
1264 {
1265 if( (data.itag[i] >= itg) && (data.itag[i] <= ns) )
1266 {
1267 data.x1[i]= data.x1[i]* xw1;
1268 data.y1[i]= data.y1[i]* xw1;
1269 data.z1[i]= data.z1[i]* xw1;
1270 data.x2[i]= data.x2[i]* xw1;
1271 data.y2[i]= data.y2[i]* xw1;
1272 data.z2[i]= data.z2[i]* xw1;
1273 data.bi[i]= data.bi[i]* xw1;
1274 }
1275 }
1276 /* FIXME corrects errors when GS follows GX but this is just a work-around */
1277 data.np = data.n;
1278 data.ipsym = 0;
1279 }
1280 else for( i = 0; i < data.n; i++ )
1281 {
1282 data.x1[i]= data.x1[i]* xw1;
1283 data.y1[i]= data.y1[i]* xw1;
1284 data.z1[i]= data.z1[i]* xw1;
1285 data.x2[i]= data.x2[i]* xw1;
1286 data.y2[i]= data.y2[i]* xw1;
1287 data.z2[i]= data.z2[i]* xw1;
1288 data.bi[i]= data.bi[i]* xw1;
1289 }
1290
1291 yw1= xw1* xw1;
1292 for( i = 0; i < data.m; i++ )
1293 {
1294 data.px[i] = data.px[i]* xw1;
1295 data.py[i] = data.py[i]* xw1;
1296 data.pz[i] = data.pz[i]* xw1;
1297 data.pbi[i]= data.pbi[i]* yw1;
1298 }
1299 continue;
1300
1301 case GE: /* "ge" card, terminate structure geometry input. */
1302 /* My addition, for drawing */
1303 if( ((data.n > 0) || (data.m > 0)) && !CHILD )
1304 Init_Struct_Drawing();
1305 else if( (data.n == 0) && (data.m == 0) )
1306 {
1307 stop( _("No geometry data cards"), ERR_OK );
1308 return( FALSE );
1309 }
1310
1311 if( !conect(itg) ) return( FALSE );
1312
1313 if( data.n != 0)
1314 {
1315 /* Allocate wire buffers */
1316 mreq = (size_t)data.n * sizeof(double);
1317 mem_realloc( (void **)&data.si, mreq, "in input.c" );
1318 mem_realloc( (void **)&data.sab, mreq, "in input.c" );
1319 mem_realloc( (void **)&data.cab, mreq, "in input.c" );
1320 mem_realloc( (void **)&data.salp, mreq, "in input.c" );
1321 mem_realloc( (void **)&data.x, mreq, "in input.c" );
1322 mem_realloc( (void **)&data.y, mreq, "in input.c" );
1323 mem_realloc( (void **)&data.z, mreq, "in input.c" );
1324
1325 for( i = 0; i < data.n; i++ )
1326 {
1327 xw1= data.x2[i]- data.x1[i];
1328 yw1= data.y2[i]- data.y1[i];
1329 zw1= data.z2[i]- data.z1[i];
1330 data.x[i]=( data.x1[i]+ data.x2[i])/2.0;
1331 data.y[i]=( data.y1[i]+ data.y2[i])/2.0;
1332 data.z[i]=( data.z1[i]+ data.z2[i])/2.0;
1333 xw2= xw1* xw1+ yw1* yw1+ zw1* zw1;
1334 yw2= sqrt( xw2);
1335 //yw2=( xw2/yw2 + yw2)/2.0;
1336 data.si[i]= yw2;
1337 data.cab[i]= xw1/ yw2;
1338 data.sab[i]= yw1/ yw2;
1339
1340 xw2= zw1/ yw2;
1341 if( xw2 > 1.0)
1342 xw2=1.0;
1343 if( xw2 < -1.0)
1344 xw2=-1.0;
1345 data.salp[i]= xw2;
1346
1347 //xw2= asin( xw2)* TD;
1348 //yw2= atan2( yw1, xw1)* TD;
1349
1350 if( (data.si[i] <= 1.0e-20) || (data.bi[i] <= 0.0) )
1351 {
1352 fprintf( stderr, "xnec2c: datagn(): segment data error\n" );
1353 stop( _("datagn(): Segment data error"), ERR_OK );
1354 return( FALSE );
1355 }
1356
1357 } /* for( i = 0; i < data.n; i++ ) */
1358
1359 } /* if( data.n != 0) */
1360
1361 if( data.m != 0)
1362 {
1363 for( i = 0; i < data.m; i++ )
1364 {
1365 xw1=( data.t1y[i]* data.t2z[i] -
1366 data.t1z[i]* data.t2y[i])* data.psalp[i];
1367 yw1=( data.t1z[i]* data.t2x[i] -
1368 data.t1x[i]* data.t2z[i])* data.psalp[i];
1369 zw1=( data.t1x[i]* data.t2y[i] -
1370 data.t1y[i]* data.t2x[i])* data.psalp[i];
1371 } /* for( i = 0; i < data.m; i++ ) */
1372
1373 } /* if( data.m != 0) */
1374
1375 data.npm = data.n+data.m;
1376 data.np2m = data.n+2*data.m;
1377 data.np3m = data.n+3*data.m;
1378
1379 return( TRUE );
1380
1381 /* "gm" card, move structure or reproduce */
1382 /* original structure in new positions. */
1383 case GM:
1384 {
1385 int tgf = (int)(rad + 0.5);
1386 if( (tgf < 0) || (ns < 0) || (rad < 0.0) )
1387 {
1388 fprintf( stderr, "xnec2c: datagn(): move GM data card error\n" );
1389 stop( _("datagn(): Move GM data card error"), ERR_OK );
1390 return( FALSE );
1391 }
1392 xw1= xw1* TA;
1393 yw1= yw1* TA;
1394 zw1= zw1* TA;
1395 if( !move(xw1, yw1, zw1, xw2, yw2, zw2, (int)(rad+.5), ns, itg) )
1396 return( FALSE );
1397 }
1398 continue;
1399
1400 case SP: /* "sp" card, generate single new patch */
1401 ns++;
1402
1403 if( itg != 0)
1404 {
1405 fprintf( stderr, "xnec2c: datagn(): patch data card error\n" );
1406 stop( _("datagn(): Patch data card error"), ERR_OK );
1407 return( FALSE );
1408 }
1409
1410 if( (ns == 2) || (ns == 4) )
1411 isct=1;
1412
1413 if( ns > 1)
1414 {
1415 if( !readgm(gm, &ix, &iy, &x3, &y3,
1416 &z3, &x4, &y4, &z4, &dummy) )
1417 return( FALSE );
1418
1419 if( (ns == 2) || (itg > 0) )
1420 {
1421 x4= xw1+ x3- xw2;
1422 y4= yw1+ y3- yw2;
1423 z4= zw1+ z3- zw2;
1424 }
1425
1426 if( strcmp(gm, "SC") != 0 )
1427 {
1428 fprintf( stderr, "xnec2c: datagn(): patch data error\n" );
1429 stop( _("datagn(): Patch data error"), ERR_OK );
1430 return( FALSE );
1431 }
1432
1433 } /* if( ns > 1) */
1434 else
1435 {
1436 xw2= xw2* TA;
1437 yw2= yw2* TA;
1438 }
1439
1440 if( !patch( itg, ns, xw1, yw1, zw1, xw2,
1441 yw2, zw2, x3, y3, z3, x4, y4, z4) )
1442 return( FALSE );
1443 continue;
1444
1445 case SM: /* "sm" card, generate multiple-patch surface */
1446 if( (itg < 1) || (ns < 1) )
1447 {
1448 fprintf( stderr, "datagn(): xnec2c: patch card data error\n" );
1449 stop( _("datagn(): Patch data card error"), ERR_OK );
1450 return( FALSE );
1451 }
1452
1453 if( !readgm(gm, &ix, &iy, &x3, &y3,
1454 &z3, &x4, &y4, &z4, &dummy) )
1455 return( FALSE );
1456
1457 if( (ns == 2) || (itg > 0) )
1458 {
1459 x4= xw1+ x3- xw2;
1460 y4= yw1+ y3- yw2;
1461 z4= zw1+ z3- zw2;
1462 }
1463
1464 if( strcmp(gm, "SC" ) != 0 )
1465 {
1466 fprintf( stderr, "xnec2c: datagn(): patch card data error\n" );
1467 stop( _("datagn(): Patch data card error"), ERR_OK );
1468 return( FALSE );
1469 }
1470
1471 if( !patch(itg, ns, xw1, yw1, zw1, xw2,
1472 yw2, zw2, x3, y3, z3, x4, y4, z4) )
1473 return( FALSE );
1474 continue;
1475
1476 case GA: /* "ga" card, generate segment data for wire arc */
1477 if( Tag_Seg_Error(itg, ns) ) return( FALSE );
1478 nwire++;
1479 if( !arc(itg, ns, xw1, yw1, zw1, xw2) ) return( FALSE );
1480 continue;
1481
1482 case SC: /* "sc" card */
1483 if( isct == 0)
1484 {
1485 fprintf( stderr, "xnec2c: datagn(): patch data card error\n" );
1486 stop( _("datagn(): Patch data card error"), ERR_OK );
1487 return( FALSE );
1488 }
1489
1490 ns++;
1491
1492 if( (itg != 0) || ((ns != 2) && (ns != 4)) )
1493 {
1494 fprintf( stderr, "xnec2c: datagn(): patch data card error\n" );
1495 stop( _("datagn(): Patch data card error"), ERR_OK );
1496 return( FALSE );
1497 }
1498
1499 xs1= x4;
1500 ys1= y4;
1501 zs1= z4;
1502 xs2= x3;
1503 ys2= y3;
1504 zs2= z3;
1505 x3= xw1;
1506 y3= yw1;
1507 z3= zw1;
1508
1509 if( ns == 4)
1510 {
1511 x4= xw2;
1512 y4= yw2;
1513 z4= zw2;
1514 }
1515
1516 xw1= xs1;
1517 yw1= ys1;
1518 zw1= zs1;
1519 xw2= xs2;
1520 yw2= ys2;
1521 zw2= zs2;
1522
1523 if( ns != 4)
1524 {
1525 x4= xw1+ x3- xw2;
1526 y4= yw1+ y3- yw2;
1527 z4= zw1+ z3- zw2;
1528 }
1529
1530 if( !patch(itg, ns, xw1, yw1, zw1, xw2,
1531 yw2, zw2, x3, y3, z3, x4, y4, z4) )
1532 return( FALSE );
1533 continue;
1534
1535 case GH: /* "gh" card, generate helix */
1536 if( Tag_Seg_Error(itg, ns) ) return( FALSE );
1537 nwire++;
1538 helix( xw1, yw1, zw1, xw2, yw2, zw2, rad, ns, itg);
1539 continue;
1540
1541 case GF: /* "gf" card, not supported */
1542 fprintf( stderr, "xnec2c: datagn(): \"GF\" card (NGF solution) "
1543 "is not supported\n" );
1544 stop( _("datagn(): \"GF\" card (NGF solution)\n"\
1545 "is not supported"), ERR_OK );
1546 return( FALSE );
1547
1548 case CT: /* Ignore in-data comments (NEC4 compatibility) */
1549 fprintf( stderr, "xnec2c: datagn(): ignoring CM card in geometry\n" );
1550 stop( _("datagn(): Ignoring CM card in geometry"), ERR_OK );
1551 continue;
1552
1553 default: /* error message */
1554 fprintf( stderr, "xnec2c: datagn(): geometry data card error\n" );
1555 fprintf( stderr,
1556 "%2s %3d %5d %10.5f %10.5f %10.5f"
1557 " %10.5f %10.5f %10.5f %10.5f\n",
1558 gm, itg, ns, xw1, yw1, zw1, xw2, yw2, zw2, rad );
1559
1560 stop( _("datagn(): Geometry data card error"), ERR_OK );
1561 return( FALSE );
1562
1563 } /* switch( gm_num ) */
1564
1565 } /* do */
1566 while( TRUE );
1567
1568 } /* datagn() */
1569
1570 /*-----------------------------------------------------------------------*/
1571
1572 /* Tag_Seg_Error()
1573 *
1574 * Checks tag and segments number are valid (>1)
1575 */
1576 gboolean
Tag_Seg_Error(int tag,int segs)1577 Tag_Seg_Error( int tag, int segs )
1578 {
1579 gboolean retv = FALSE;
1580
1581 if( tag <= 0 )
1582 {
1583 fprintf( stderr,
1584 "xnec2c: Tag_Seg_Error(): geometry data card error -"
1585 "tag number is less than 1\n" );
1586 stop( _("Tag_Seg_Error(): Geometry data error\n"\
1587 "Tag number is less than 1"), ERR_OK );
1588 retv = TRUE;
1589 }
1590
1591 if( segs <= 0 )
1592 {
1593 fprintf( stderr,
1594 "xnec2c: Tag_Seg_Error(): geometry data card error - "
1595 "number of segments is less than 1\n" );
1596 stop( _("Tag_Seg_Error(): Geometry data error\n"\
1597 "Number of segments is less than 1"), ERR_OK );
1598 retv = TRUE;
1599 }
1600
1601 return( retv );
1602 }
1603
1604 /*-----------------------------------------------------------------------*/
1605
1606