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 "matrix.h"
45 #include "shared.h"
46
47 /*-------------------------------------------------------------------*/
48
49 /* cmset sets up the complex structure matrix in the array cm */
cmset(int nrow,complex double * cmx,double rkhx,int iexkx)50 void cmset( int nrow, complex double *cmx, double rkhx, int iexkx )
51 {
52 int mp2, neq, npeq, it, i, j, i1, i2, in2, im1;
53 int im2, ist, ij, ipr, jss, jm1, jm2, jst, k, ka, kk;
54 complex double zaj, deter, *scm = NULL;
55
56 mp2=2* data.mp;
57 npeq= data.np+ mp2;
58 neq= data.n+2* data.m;
59 smat.nop = neq/npeq;
60
61 dataj.rkh= rkhx;
62 dataj.iexk= iexkx;
63 it= matpar.nlast;
64
65 for( i = 0; i < nrow; i++ )
66 for( j = 0; j < it; j++ )
67 cmx[i+j*nrow]= CPLX_00;
68
69 i1= 1;
70 i2= it;
71 in2= i2;
72
73 if( in2 > data.np)
74 in2= data.np;
75
76 im1= i1- data.np;
77 im2= i2- data.np;
78
79 if( im1 < 1)
80 im1=1;
81
82 ist=1;
83 if( i1 <= data.np)
84 ist= data.np- i1+2;
85
86 /* wire source loop */
87 if( data.n != 0)
88 {
89 for( j = 1; j <= data.n; j++ )
90 {
91 trio(j);
92 for( i = 0; i < segj.jsno; i++ )
93 {
94 ij= segj.jco[i];
95 segj.jco[i]=(( ij-1)/ data.np)* mp2+ ij;
96 }
97
98 if( i1 <= in2)
99 cmww( j, i1, in2, cmx, nrow, cmx, nrow,1);
100
101 if( im1 <= im2)
102 cmws( j, im1, im2, &cmx[(ist-1)*nrow], nrow, cmx, 1);
103
104 /* matrix elements modified by loading */
105 if( zload.nload == 0)
106 continue;
107
108 if( j > data.np)
109 continue;
110
111 ipr= j;
112 if( (ipr < 1) || (ipr > it) )
113 continue;
114
115 zaj= zload.zarray[j-1];
116
117 for( i = 0; i < segj.jsno; i++ )
118 {
119 jss= segj.jco[i];
120 cmx[(jss-1)+(ipr-1)*nrow] -=
121 ( segj.ax[i]+ segj.cx[i])* zaj;
122 }
123
124 } /* for( j = 1; j <= n; j++ ) */
125
126 } /* if( n != 0) */
127
128 if( data.m != 0)
129 {
130 /* matrix elements for patch current sources */
131 jm1=1- data.mp;
132 jm2=0;
133 jst=1- mp2;
134
135 for( i = 0; i < smat.nop; i++ )
136 {
137 jm1 += data.mp;
138 jm2 += data.mp;
139 jst += npeq;
140
141 if( i1 <= in2)
142 cmsw( jm1, jm2, i1, in2,
143 &cmx[(jst-1)], cmx, 0, nrow, 1);
144
145 if( im1 <= im2)
146 cmss( jm1, jm2, im1, im2,
147 &cmx[(jst-1)+(ist-1)*nrow], nrow, 1);
148 }
149
150 } /* if( m != 0) */
151
152 if( matpar.icase == 1)
153 return;
154
155 /* Allocate to scratch memory */
156 size_t mreq = (size_t)data.np2m * sizeof(complex double);
157 mem_alloc( (void **)&scm, mreq, "in matrix.c");
158
159 /* combine elements for symmetry modes */
160 for( i = 0; i < it; i++ )
161 {
162 for( j = 0; j < npeq; j++ )
163 {
164 for( k = 0; k < smat.nop; k++ )
165 {
166 ka= j+ k*npeq;
167 scm[k]= cmx[ka+i*nrow];
168 }
169
170 deter= scm[0];
171
172 for( kk = 1; kk < smat.nop; kk++ )
173 deter += scm[kk];
174
175 cmx[j+i*nrow]= deter;
176
177 for( k = 1; k < smat.nop; k++ )
178 {
179 ka= j+ k*npeq;
180 deter= scm[0];
181
182 for( kk = 1; kk < smat.nop; kk++ )
183 {
184 deter += scm[kk]* smat.ssx[k+kk*smat.nop];
185 cmx[ka+i*nrow]= deter;
186 }
187
188 } /* for( k = 1; k < smat.nop; k++ ) */
189
190 } /* for( j = 0; j < npeq; j++ ) */
191
192 } /* for( i = 0; i < it; i++ ) */
193
194 free_ptr( (void **)&scm );
195
196 return;
197 }
198
199 /*-----------------------------------------------------------------------*/
200
201 /* cmss computes matrix elements for surface-surface interactions. */
cmss(int j1,int j2,int im1,int im2,complex double * cmx,int nrow,int itrp)202 void cmss( int j1, int j2, int im1, int im2,
203 complex double *cmx, int nrow, int itrp )
204 {
205 int i1, i2, icomp, ii1, i, il, ii2, jj1, j, jl, jj2;
206 double t1xi, t1yi, t1zi, t2xi, t2yi, t2zi, xi, yi, zi;
207 complex double g11, g12, g21, g22;
208
209 i1=( im1+1)/2;
210 i2=( im2+1)/2;
211 icomp= i1*2-3;
212 ii1=-2;
213 if( icomp+2 < im1)
214 ii1=-3;
215
216 /* loop over observation patches */
217 il = -1;
218 for( i = i1; i <= i2; i++ )
219 {
220 il++;
221 icomp += 2;
222 ii1 += 2;
223 ii2 = ii1+1;
224
225 t1xi= data.t1x[il]* data.psalp[il];
226 t1yi= data.t1y[il]* data.psalp[il];
227 t1zi= data.t1z[il]* data.psalp[il];
228 t2xi= data.t2x[il]* data.psalp[il];
229 t2yi= data.t2y[il]* data.psalp[il];
230 t2zi= data.t2z[il]* data.psalp[il];
231 xi= data.px[il];
232 yi= data.py[il];
233 zi= data.pz[il];
234
235 /* loop over source patches */
236 jj1=-2;
237 for( j = j1; j <= j2; j++ )
238 {
239 jl=j-1;
240 jj1 += 2;
241 jj2 = jj1+1;
242
243 dataj.s= data.pbi[jl];
244 dataj.xj= data.px[jl];
245 dataj.yj= data.py[jl];
246 dataj.zj= data.pz[jl];
247 dataj.t1xj= data.t1x[jl];
248 dataj.t1yj= data.t1y[jl];
249 dataj.t1zj= data.t1z[jl];
250 dataj.t2xj= data.t2x[jl];
251 dataj.t2yj= data.t2y[jl];
252 dataj.t2zj= data.t2z[jl];
253
254 hintg( xi, yi, zi);
255
256 g11=-( t2xi* dataj.exk+ t2yi* dataj.eyk+ t2zi* dataj.ezk);
257 g12=-( t2xi* dataj.exs+ t2yi* dataj.eys+ t2zi* dataj.ezs);
258 g21=-( t1xi* dataj.exk+ t1yi* dataj.eyk+ t1zi* dataj.ezk);
259 g22=-( t1xi* dataj.exs+ t1yi* dataj.eys+ t1zi* dataj.ezs);
260
261 if( i == j )
262 {
263 g11 -= .5;
264 g22 += .5;
265 }
266
267 /* normal fill */
268 if( itrp == 0)
269 {
270 if( icomp >= im1 )
271 {
272 cmx[ii1+jj1*nrow]= g11;
273 cmx[ii1+jj2*nrow]= g12;
274 }
275
276 if( icomp >= im2 )
277 continue;
278
279 cmx[ii2+jj1*nrow]= g21;
280 cmx[ii2+jj2*nrow]= g22;
281 continue;
282
283 } /* if( itrp == 0) */
284
285 /* transposed fill */
286 if( icomp >= im1 )
287 {
288 cmx[jj1+ii1*nrow]= g11;
289 cmx[jj2+ii1*nrow]= g12;
290 }
291
292 if( icomp >= im2 )
293 continue;
294
295 cmx[jj1+ii2*nrow]= g21;
296 cmx[jj2+ii2*nrow]= g22;
297
298 } /* for( j = j1; j <= j2; j++ ) */
299
300 } /* for( i = i1; i <= i2; i++ ) */
301
302 return;
303 }
304
305 /*-----------------------------------------------------------------------*/
306
307 /* computes matrix elements for e along wires due to patch current */
cmsw(int j1,int j2,int i1,int i2,complex double * cmx,complex double * cw,int ncw,int nrow,int itrp)308 void cmsw( int j1, int j2, int i1, int i2, complex double *cmx,
309 complex double *cw, int ncw, int nrow, int itrp )
310 {
311 int jsnox; /* -1 offset to "jsno" for array indexing */
312 static complex double *emel = NULL;
313
314 size_t mreq = 9 * sizeof(complex double);
315 mem_alloc( (void **)&emel, mreq, "in matrix.c");
316
317 jsnox = segj.jsno-1;
318
319 if( itrp >= 0)
320 {
321 int k, icgo, i, ipch, jl, j, js, il, ip;
322 double xi, yi, zi, cabi, sabi, salpi, fsign=1.0, pyl, pxl;
323
324 k=-1;
325 icgo=0;
326
327 /* observation loop */
328 for( i = i1-1; i < i2; i++ )
329 {
330 k++;
331 xi= data.x[i];
332 yi= data.y[i];
333 zi= data.z[i];
334 cabi= data.cab[i];
335 sabi= data.sab[i];
336 salpi= data.salp[i];
337 ipch=0;
338
339 if( data.icon1[i] >= PCHCON)
340 {
341 ipch= data.icon1[i]-PCHCON;
342 fsign=-1.0;
343 }
344
345 if( data.icon2[i] >= PCHCON)
346 {
347 ipch= data.icon2[i]-PCHCON;
348 fsign=1.0;
349 }
350
351 /* source loop */
352 jl = -1;
353 for( j = j1; j <= j2; j++ )
354 {
355 jl += 2;
356 js = j-1;
357 dataj.t1xj= data.t1x[js];
358 dataj.t1yj= data.t1y[js];
359 dataj.t1zj= data.t1z[js];
360 dataj.t2xj= data.t2x[js];
361 dataj.t2yj= data.t2y[js];
362 dataj.t2zj= data.t2z[js];
363 dataj.xj= data.px[js];
364 dataj.yj= data.py[js];
365 dataj.zj= data.pz[js];
366 dataj.s= data.pbi[js];
367
368 /* ground loop */
369 for( ip = 1; ip <= gnd.ksymp; ip++ )
370 {
371 dataj.ipgnd= ip;
372
373 if( ((ipch == j) || (icgo != 0)) && (ip != 2) )
374 {
375 if( icgo <= 0 )
376 {
377 pcint( xi, yi, zi, cabi, sabi, salpi, emel);
378
379 pyl= PI* data.si[i]* fsign;
380 pxl= sin( pyl);
381 pyl= cos( pyl);
382 dataj.exc= emel[8]* fsign;
383
384 trio(i+1);
385
386 il= i-ncw;
387 if( i < data.np)
388 il += (il/data.np)*2*data.mp;
389
390 if( itrp == 0 )
391 cw[k+il*nrow] +=
392 dataj.exc*( segj.ax[jsnox] +
393 segj.bx[jsnox]* pxl+ segj.cx[jsnox]* pyl);
394 else
395 cw[il+k*nrow] +=
396 dataj.exc*( segj.ax[jsnox] +
397 segj.bx[jsnox]* pxl+ segj.cx[jsnox]* pyl);
398
399 } /* if( icgo <= 0 ) */
400
401 if( itrp == 0)
402 {
403 cmx[k+(jl-1)*nrow]= emel[icgo];
404 cmx[k+jl*nrow] = emel[icgo+4];
405 }
406 else
407 {
408 cmx[(jl-1)+k*nrow]= emel[icgo];
409 cmx[jl+k*nrow] = emel[icgo+4];
410 }
411
412 icgo++;
413 if( icgo == 4)
414 icgo=0;
415
416 continue;
417
418 } /* if( ((ipch == (j+1)) || (icgo != 0)) && (ip != 2) ) */
419
420 unere( xi, yi, zi);
421
422 /* normal fill */
423 if( itrp == 0)
424 {
425 cmx[k+(jl-1)*nrow] +=
426 dataj.exk* cabi+ dataj.eyk* sabi+ dataj.ezk* salpi;
427 cmx[k+jl*nrow] +=
428 dataj.exs* cabi+ dataj.eys* sabi+ dataj.ezs* salpi;
429 continue;
430 }
431
432 /* transposed fill */
433 cmx[(jl-1)+k*nrow] +=
434 dataj.exk* cabi+ dataj.eyk* sabi+ dataj.ezk* salpi;
435 cmx[jl+k*nrow] +=
436 dataj.exs* cabi+ dataj.eys* sabi+ dataj.ezs* salpi;
437
438 } /* for( ip = 1; ip <= gnd.ksymp; ip++ ) */
439
440 } /* for( j = j1; j <= j2; j++ ) */
441
442 } /* for( i = i1-1; i < i2; i++ ) */
443
444 } /* if( itrp >= 0) */
445
446 return;
447 }
448
449 /*-----------------------------------------------------------------------*/
450
451 /* cmws computes matrix elements for wire-surface interactions */
cmws(int j,int i1,int i2,complex double * cmx,int nr,complex double * cw,int itrp)452 void cmws( int j, int i1, int i2, complex double *cmx,
453 int nr, complex double *cw, int itrp )
454 {
455 int ipr, i, ipatch, ik, js=0, ij, jx;
456 double xi, yi, zi, tx, ty, tz;
457 complex double etk, ets, etc;
458
459 j--;
460 dataj.s= data.si[j];
461 dataj.b= data.bi[j];
462 dataj.xj= data.x[j];
463 dataj.yj= data.y[j];
464 dataj.zj= data.z[j];
465 dataj.cabj= data.cab[j];
466 dataj.sabj= data.sab[j];
467 dataj.salpj= data.salp[j];
468
469 /* observation loop */
470 ipr= -1;
471 for( i = i1; i <= i2; i++ )
472 {
473 ipr++;
474 ipatch=(i+1)/2;
475 ik= i-( i/2)*2;
476
477 if( (ik != 0) || (ipr == 0) )
478 {
479 js= ipatch-1;
480 xi= data.px[js];
481 yi= data.py[js];
482 zi= data.pz[js];
483 hsfld( xi, yi, zi, 0.0);
484
485 if( ik != 0 )
486 {
487 tx= data.t2x[js];
488 ty= data.t2y[js];
489 tz= data.t2z[js];
490 }
491 else
492 {
493 tx= data.t1x[js];
494 ty= data.t1y[js];
495 tz= data.t1z[js];
496 }
497
498 } /* if( (ik != 0) || (ipr == 0) ) */
499 else
500 {
501 tx= data.t1x[js];
502 ty= data.t1y[js];
503 tz= data.t1z[js];
504
505 } /* if( (ik != 0) || (ipr == 0) ) */
506
507 etk=-( dataj.exk* tx+ dataj.eyk* ty +
508 dataj.ezk* tz)* data.psalp[js];
509 ets=-( dataj.exs* tx+ dataj.eys* ty +
510 dataj.ezs* tz)* data.psalp[js];
511 etc=-( dataj.exc* tx+ dataj.eyc* ty +
512 dataj.ezc* tz)* data.psalp[js];
513
514 /* fill matrix elements. element locations */
515 /* determined by connection data. */
516
517 /* normal fill */
518 if( itrp == 0)
519 {
520 for( ij = 0; ij < segj.jsno; ij++ )
521 {
522 jx= segj.jco[ij]-1;
523 cmx[ipr+jx*nr] += etk* segj.ax[ij] +
524 ets* segj.bx[ij]+ etc* segj.cx[ij];
525 }
526
527 continue;
528 } /* if( itrp == 0) */
529
530 /* transposed fill */
531 if( itrp != 2)
532 {
533 for( ij = 0; ij < segj.jsno; ij++ )
534 {
535 jx= segj.jco[ij]-1;
536 cmx[jx+ipr*nr] += etk* segj.ax[ij] +
537 ets* segj.bx[ij]+ etc* segj.cx[ij];
538 }
539
540 continue;
541 } /* if( itrp != 2) */
542
543 /* transposed fill - c(ws) and d(ws)prime (=cw) */
544 for( ij = 0; ij < segj.jsno; ij++ )
545 {
546 jx= segj.jco[ij]-1;
547 if( jx < nr)
548 cmx[jx+ipr*nr] += etk* segj.ax[ij] +
549 ets* segj.bx[ij]+ etc* segj.cx[ij];
550 else
551 {
552 jx -= nr;
553 cw[jx+ipr*nr] += etk* segj.ax[ij] +
554 ets* segj.bx[ij]+ etc* segj.cx[ij];
555 }
556 } /* for( ij = 0; ij < segj.jsno; ij++ ) */
557
558 } /* for( i = i1; i <= i2; i++ ) */
559
560 return;
561 }
562
563 /*-----------------------------------------------------------------------*/
564
565 /* cmww computes matrix elements for wire-wire interactions */
cmww(int j,int i1,int i2,complex double * cmx,int nr,complex double * cw,int nw,int itrp)566 void cmww( int j, int i1, int i2, complex double *cmx,
567 int nr, complex double *cw, int nw, int itrp)
568 {
569 int ipr, iprx, i, ij, jx;
570 double xi, yi, zi, ai, cabi, sabi, salpi;
571 complex double etk, ets, etc;
572
573 /* set source segment parameters */
574 jx = j;
575 j--;
576 dataj.s= data.si[j];
577 dataj.b= data.bi[j];
578 dataj.xj= data.x[j];
579 dataj.yj= data.y[j];
580 dataj.zj= data.z[j];
581 dataj.cabj= data.cab[j];
582 dataj.sabj= data.sab[j];
583 dataj.salpj= data.salp[j];
584
585 /* decide whether ext. t.w. approx. can be used */
586 if( dataj.iexk != 0)
587 {
588 ipr = data.icon1[j];
589 if (ipr > PCHCON) dataj.ind1 = 0;
590 else if( ipr < 0 )
591 {
592 ipr= -ipr;
593 iprx= ipr-1;
594
595 if( -data.icon1[iprx] != jx )
596 dataj.ind1=2;
597 else
598 {
599 xi= fabs( dataj.cabj* data.cab[iprx]+ dataj.sabj*
600 data.sab[iprx]+ dataj.salpj* data.salp[iprx]);
601 if( (xi < 0.999999) ||
602 (fabs(data.bi[iprx]/dataj.b-1.0) > 1.0e-6) )
603 dataj.ind1=2;
604 else
605 dataj.ind1=0;
606
607 } /* if( -data.icon1[iprx] != jx ) */
608
609 } /* if( ipr < 0 ) */
610 else
611 {
612 iprx = ipr-1;
613 if( ipr == 0 )
614 dataj.ind1=1;
615 else
616 {
617 if( ipr != jx )
618 {
619 if( data.icon2[iprx] != jx )
620 dataj.ind1=2;
621 else
622 {
623 xi= fabs( dataj.cabj* data.cab[iprx]+ dataj.sabj*
624 data.sab[iprx]+ dataj.salpj* data.salp[iprx]);
625 if( (xi < 0.999999) ||
626 (fabs(data.bi[iprx]/dataj.b-1.0) > 1.0e-6) )
627 dataj.ind1=2;
628 else
629 dataj.ind1=0;
630
631 } /* if( data.icon2[iprx] != jx ) */
632
633 } /* if( ipr != jx ) */
634 else if( (dataj.cabj* dataj.cabj +
635 dataj.sabj* dataj.sabj) > 1.0e-8)
636 dataj.ind1=2;
637 else
638 dataj.ind1=0;
639
640 } /* if( ipr == 0 ) */
641
642 } /* if( ipr < 0 ) */
643
644 ipr = data.icon2[j];
645 if (ipr > PCHCON) dataj.ind2 = 2;
646 else if( ipr < 0 )
647 {
648 ipr= -ipr;
649 iprx = ipr-1;
650 if( -data.icon2[iprx] != jx )
651 dataj.ind2=2;
652 else
653 {
654 xi= fabs( dataj.cabj* data.cab[iprx]+ dataj.sabj*
655 data.sab[iprx]+ dataj.salpj* data.salp[iprx]);
656 if( (xi < 0.99999) ||
657 (fabs(data.bi[iprx]/dataj.b-1.0) > 1.0e-6) )
658 dataj.ind2=2;
659 else
660 dataj.ind2=0;
661
662 } /* if( -data.icon1[iprx] != jx ) */
663
664 } /* if( ipr < 0 ) */
665 else
666 {
667 iprx = ipr-1;
668 if( ipr == 0 )
669 dataj.ind2=1;
670 else
671 {
672 if( ipr != jx )
673 {
674 if( data.icon1[iprx] != jx )
675 dataj.ind2=2;
676 else
677 {
678 xi= fabs( dataj.cabj* data.cab[iprx]+ dataj.sabj*
679 data.sab[iprx]+ dataj.salpj* data.salp[iprx]);
680 if( (xi < 0.999999) ||
681 (fabs(data.bi[iprx]/dataj.b-1.0) > 1.0e-6) )
682 dataj.ind2=2;
683 else
684 dataj.ind2=0;
685
686 } /* if( data.icon2[iprx] != jx ) */
687
688 } /* if( ipr != jx ) */
689 else if( (dataj.cabj* dataj.cabj +
690 dataj.sabj* dataj.sabj) > 1.0e-8)
691 dataj.ind2=2;
692 else
693 dataj.ind2=0;
694
695 } /* if( ipr == 0 ) */
696
697 } /* if( ipr < 0 ) */
698
699 } /* if( dataj.iexk != 0) */
700
701 /* observation loop */
702 ipr=-1;
703 for( i = i1-1; i < i2; i++ )
704 {
705 ipr++;
706 ij= i-j;
707 xi= data.x[i];
708 yi= data.y[i];
709 zi= data.z[i];
710 ai= data.bi[i];
711 cabi= data.cab[i];
712 sabi= data.sab[i];
713 salpi= data.salp[i];
714
715 efld( xi, yi, zi, ai, ij);
716
717 etk= dataj.exk* cabi+ dataj.eyk *
718 sabi+ dataj.ezk* salpi;
719 ets= dataj.exs* cabi+ dataj.eys *
720 sabi+ dataj.ezs* salpi;
721 etc= dataj.exc* cabi+ dataj.eyc *
722 sabi+ dataj.ezc* salpi;
723
724 /* fill matrix elements. element locations */
725 /* determined by connection data. */
726
727 /* normal fill */
728 if( itrp == 0)
729 {
730 for( ij = 0; ij < segj.jsno; ij++ )
731 {
732 jx = segj.jco[ij]-1;
733 cmx[ipr+jx*nr] += etk* segj.ax[ij] +
734 ets* segj.bx[ij]+ etc* segj.cx[ij];
735 }
736 continue;
737 }
738
739 /* transposed fill */
740 if( itrp != 2)
741 {
742 for( ij = 0; ij < segj.jsno; ij++ )
743 {
744 jx= segj.jco[ij]-1;
745 cmx[jx+ipr*nr] += etk* segj.ax[ij] +
746 ets* segj.bx[ij]+ etc* segj.cx[ij];
747 }
748 continue;
749 }
750
751 /* trans. fill for c(ww) - test for elements for d(ww)prime */
752 for( ij = 0; ij < segj.jsno; ij++ )
753 {
754 jx= segj.jco[ij]-1;
755 if( jx < nr)
756 cmx[jx+ipr*nr] += etk* segj.ax[ij] +
757 ets* segj.bx[ij]+ etc* segj.cx[ij];
758 else
759 {
760 jx -= nr;
761 cw[jx*ipr*nw] += etk* segj.ax[ij] +
762 ets* segj.bx[ij]+ etc* segj.cx[ij];
763 }
764
765 } /* for( ij = 0; ij < segj.jsno; ij++ ) */
766
767 } /* for( i = i1-1; i < i2; i++ ) */
768
769 return;
770 }
771
772 /*-----------------------------------------------------------------------*/
773
774 /* etmns fills the array e with the negative of the */
775 /* electric field incident on the structure. e is the */
776 /* right hand side of the matrix equation. */
etmns(double p1,double p2,double p3,double p4,double p5,double p6,int ipr,complex double * e)777 void etmns( double p1, double p2, double p3, double p4,
778 double p5, double p6, int ipr, complex double *e )
779 {
780 int i, is, i1, i2=0, neq;
781 double cth, sth, cph, sph, cet, set, pxl, pyl, pzl, wx;
782 double wy, wz, qx, qy, qz, arg, ds, dsh, rs, r;
783 complex double cx, cy, cz, er, et, ezh;
784 complex double erh, rrv=CPLX_00, rrh=CPLX_00, tt1, tt2;
785
786 neq= data.n+2*data.m;
787 vsorc.nqds=0;
788
789 /* applied field of voltage sources for transmitting case */
790 if( (ipr == 0) || (ipr == 5) )
791 {
792 for( i = 0; i < neq; i++ )
793 e[i]=CPLX_00;
794
795 if( vsorc.nsant != 0)
796 {
797 for( i = 0; i < vsorc.nsant; i++ )
798 {
799 is= vsorc.isant[i]-1;
800 e[is]= -vsorc.vsant[i]/( data.si[is]* data.wlam);
801 }
802 }
803
804 if( vsorc.nvqd == 0)
805 return;
806
807 for( i = 0; i < vsorc.nvqd; i++ )
808 {
809 is= vsorc.ivqd[i];
810 qdsrc( is, vsorc.vqd[i], e);
811 }
812 return;
813
814 } /* if( (ipr <= 0) || (ipr == 5) ) */
815
816 /* incident plane wave, linearly polarized. */
817 if( ipr <= 3)
818 {
819 cth= cos( p1);
820 sth= sin( p1);
821 cph= cos( p2);
822 sph= sin( p2);
823 cet= cos( p3);
824 set= sin( p3);
825 pxl= cth* cph* cet- sph* set;
826 pyl= cth* sph* cet+ cph* set;
827 pzl= -sth* cet;
828 wx= -sth* cph;
829 wy= -sth* sph;
830 wz= -cth;
831 qx= wy* pzl- wz* pyl;
832 qy= wz* pxl- wx* pzl;
833 qz= wx* pyl- wy* pxl;
834
835 if( gnd.ksymp != 1)
836 {
837 if( gnd.iperf != 1)
838 {
839 rrv= csqrt(1.0- gnd.zrati* gnd.zrati* sth* sth);
840 rrh= gnd.zrati* cth;
841 rrh=( rrh- rrv)/( rrh+ rrv);
842 rrv= gnd.zrati* rrv;
843 rrv=-( cth- rrv)/( cth+ rrv);
844 }
845 else
846 {
847 rrv=-CPLX_10;
848 rrh=-CPLX_10;
849 } /* if( gnd.iperf != 1) */
850
851 } /* if( gnd.ksymp != 1) */
852
853 if( ipr <= 1)
854 {
855 if( data.n != 0)
856 {
857 for( i = 0; i < data.n; i++ )
858 {
859 arg= -TP*( wx* data.x[i]+ wy* data.y[i]+ wz* data.z[i]);
860 e[i]=-( pxl* data.cab[i]+ pyl* data.sab[i]+ pzl*
861 data.salp[i])* cmplx( cos( arg), sin( arg));
862 }
863
864 if( gnd.ksymp != 1)
865 {
866 tt1=( pyl* cph- pxl* sph)*( rrh- rrv);
867 cx= rrv* pxl- tt1* sph;
868 cy= rrv* pyl+ tt1* cph;
869 cz= -rrv* pzl;
870
871 for( i = 0; i < data.n; i++ )
872 {
873 arg= -TP*( wx* data.x[i]+ wy* data.y[i]- wz* data.z[i]);
874 e[i]= e[i]-( cx* data.cab[i]+ cy* data.sab[i]+
875 cz* data.salp[i])* cmplx(cos( arg), sin( arg));
876 }
877
878 } /* if( gnd.ksymp != 1) */
879
880 } /* if( data.n != 0) */
881
882 if( data.m == 0)
883 return;
884
885 i= -1;
886 i1= data.n-2;
887 for( is = 0; is < data.m; is++ )
888 {
889 i++;
890 i1 += 2;
891 i2 = i1+1;
892 arg= -TP*( wx* data.px[i] +
893 wy* data.py[i]+ wz* data.pz[i]);
894 tt1= cmplx( cos( arg), sin( arg)) *
895 data.psalp[i]* RETA;
896 e[i2]=( qx* data.t1x[i]+ qy* data.t1y[i] +
897 qz* data.t1z[i])* tt1;
898 e[i1]=( qx* data.t2x[i]+ qy* data.t2y[i] +
899 qz* data.t2z[i])* tt1;
900 }
901
902 if( gnd.ksymp == 1)
903 return;
904
905 tt1=( qy* cph- qx* sph)*( rrv- rrh);
906 cx=-( rrh* qx- tt1* sph);
907 cy=-( rrh* qy+ tt1* cph);
908 cz= rrh* qz;
909
910 i= -1;
911 i1= data.n-2;
912 for( is = 0; is < data.m; is++ )
913 {
914 i++;
915 i1 += 2;
916 i2 = i1+1;
917 arg= -TP*( wx* data.px[i] +
918 wy* data.py[i]- wz* data.pz[i]);
919 tt1= cmplx( cos( arg), sin( arg)) *
920 data.psalp[i]* RETA;
921 e[i2]= e[i2]+( cx* data.t1x[i]+ cy *
922 data.t1y[i]+ cz* data.t1z[i])* tt1;
923 e[i1]= e[i1]+( cx* data.t2x[i]+ cy *
924 data.t2y[i]+ cz* data.t2z[i])* tt1;
925 }
926 return;
927
928 } /* if( ipr <= 1) */
929
930 /* incident plane wave, elliptic polarization. */
931 tt1=-(CPLX_01)* p6;
932 if( ipr == 3)
933 tt1= -tt1;
934
935 if( data.n != 0)
936 {
937 cx= pxl+ tt1* qx;
938 cy= pyl+ tt1* qy;
939 cz= pzl+ tt1* qz;
940
941 for( i = 0; i < data.n; i++ )
942 {
943 arg= -TP*( wx* data.x[i]+ wy* data.y[i] + wz* data.z[i]);
944 e[i]=-( cx* data.cab[i]+ cy* data.sab[i] +
945 cz * data.salp[i])* cmplx( cos( arg), sin( arg));
946 }
947
948 if( gnd.ksymp != 1)
949 {
950 tt2=( cy* cph- cx* sph)*( rrh- rrv);
951 cx= rrv* cx- tt2* sph;
952 cy= rrv* cy+ tt2* cph;
953 cz= -rrv* cz;
954
955 for( i = 0; i < data.n; i++ )
956 {
957 arg= -TP*( wx* data.x[i]+ wy* data.y[i]- wz* data.z[i]);
958 e[i]= e[i]-( cx* data.cab[i]+ cy* data.sab[i]+
959 cz* data.salp[i])* cmplx(cos( arg), sin( arg));
960 }
961
962 } /* if( gnd.ksymp != 1) */
963
964 } /* if( n != 0) */
965
966 if( data.m == 0)
967 return;
968
969 cx= qx- tt1* pxl;
970 cy= qy- tt1* pyl;
971 cz= qz- tt1* pzl;
972
973 i= -1;
974 i1= data.n-2;
975 for( is = 0; is < data.m; is++ )
976 {
977 i++;
978 i1 += 2;
979 i2 = i1+1;
980 arg= -TP*( wx* data.px[i] +
981 wy* data.py[i]+ wz* data.pz[i]);
982 tt2= cmplx( cos( arg),
983 sin( arg)) * data.psalp[i] * RETA;
984 e[i2]=( cx* data.t1x[i] +
985 cy* data.t1y[i]+ cz* data.t1z[i])* tt2;
986 e[i1]=( cx* data.t2x[i] +
987 cy* data.t2y[i]+ cz* data.t2z[i])* tt2;
988 }
989
990 if( gnd.ksymp == 1)
991 return;
992
993 tt1=( cy* cph- cx* sph)*( rrv- rrh);
994 cx=-( rrh* cx- tt1* sph);
995 cy=-( rrh* cy+ tt1* cph);
996 cz= rrh* cz;
997
998 i= -1;
999 i1= data.n-2;
1000 for( is=0; is < data.m; is++ )
1001 {
1002 i++;
1003 i1 += 2;
1004 i2 = i1+1;
1005 arg= -TP*( wx* data.px[i] +
1006 wy* data.py[i]- wz* data.pz[i]);
1007 tt1= cmplx( cos( arg), sin( arg)) *
1008 data.psalp[i]* RETA;
1009 e[i2]= e[i2]+( cx* data.t1x[i]+ cy *
1010 data.t1y[i]+ cz* data.t1z[i])* tt1;
1011 e[i1]= e[i1]+( cx* data.t2x[i]+ cy *
1012 data.t2y[i]+ cz* data.t2z[i])* tt1;
1013 }
1014
1015 return;
1016
1017 } /* if( ipr <= 3) */
1018
1019 /* incident field of an elementary current source. */
1020 wz= cos( p4);
1021 wx= wz* cos( p5);
1022 wy= wz* sin( p5);
1023 wz= sin( p4);
1024 ds= p6*59.9580;
1025 dsh= p6/(2.0* TP);
1026
1027 is= 0;
1028 i1= data.n-2;
1029 for( i = 0; i < data.npm; i++ )
1030 {
1031 if( i >= data.n )
1032 {
1033 i1 += 2;
1034 i2 = i1+1;
1035 pxl= data.px[is]- p1;
1036 pyl= data.py[is]- p2;
1037 pzl= data.pz[is]- p3;
1038 }
1039 else
1040 {
1041 pxl= data.x[i]- p1;
1042 pyl= data.y[i]- p2;
1043 pzl= data.z[i]- p3;
1044 }
1045
1046 rs= pxl* pxl+ pyl* pyl+ pzl* pzl;
1047 if( rs < 1.0e-30)
1048 continue;
1049
1050 r= sqrt( rs);
1051 pxl= pxl/ r;
1052 pyl= pyl/ r;
1053 pzl= pzl/ r;
1054 cth= pxl* wx+ pyl* wy+ pzl* wz;
1055 sth= sqrt(1.0- cth* cth);
1056 qx= pxl- wx* cth;
1057 qy= pyl- wy* cth;
1058 qz= pzl- wz* cth;
1059
1060 arg= sqrt( qx* qx+ qy* qy+ qz* qz);
1061 if( arg >= 1.0e-30)
1062 {
1063 qx= qx/ arg;
1064 qy= qy/ arg;
1065 qz= qz/ arg;
1066 }
1067 else
1068 {
1069 qx=1.0;
1070 qy=0.0;
1071 qz=0.0;
1072
1073 } /* if( arg >= 1.0e-30) */
1074
1075 arg= -TP* r;
1076 tt1= cmplx( cos( arg), sin( arg));
1077
1078 if( i < data.n )
1079 {
1080 tt2= cmplx(1.0,-1.0/( r* TP))/ rs;
1081 er= ds* tt1* tt2* cth;
1082 et=.5* ds* tt1*((CPLX_01)* TP/ r+ tt2)* sth;
1083 ezh= er* cth- et* sth;
1084 erh= er* sth+ et* cth;
1085 cx= ezh* wx+ erh* qx;
1086 cy= ezh* wy+ erh* qy;
1087 cz= ezh* wz+ erh* qz;
1088 e[i]=-( cx* data.cab[i] +
1089 cy* data.sab[i]+ cz* data.salp[i]);
1090 }
1091 else
1092 {
1093 pxl= wy* qz- wz* qy;
1094 pyl= wz* qx- wx* qz;
1095 pzl= wx* qy- wy* qx;
1096 tt2= dsh* tt1* cmplx(1.0/ r, TP) /
1097 r* sth* data.psalp[is];
1098 cx= tt2* pxl;
1099 cy= tt2* pyl;
1100 cz= tt2* pzl;
1101 e[i2]= cx* data.t1x[is] +
1102 cy* data.t1y[is]+ cz* data.t1z[is];
1103 e[i1]= cx* data.t2x[is] +
1104 cy* data.t2y[is]+ cz* data.t2z[is];
1105 is++;
1106 } /* if( i < data.n) */
1107
1108 } /* for( i = 0; i < npm; i++ ) */
1109
1110 return;
1111 }
1112
1113 /*-----------------------------------------------------------------------*/
1114
1115 /* subroutine to factor a matrix into a unit lower triangular matrix */
1116 /* and an upper triangular matrix using the gauss-doolittle algorithm */
1117 /* presented on pages 411-416 of a. ralston--a first course in */
1118 /* numerical analysis. comments below refer to comments in ralstons */
1119 /* text. (matrix transposed.) */
1120
factr(int n,complex double * a,int * ip,int ndim)1121 void factr( int n, complex double *a, int *ip, int ndim)
1122 {
1123 int r, rm1, rp1, pj, pr, iflg, k, j, jp1, i;
1124 double dmax, elmag;
1125 complex double arj, *scm = NULL;
1126
1127 /* Allocate to scratch memory */
1128 size_t mreq = (size_t)data.np2m * sizeof(complex double);
1129 mem_alloc( (void **)&scm, mreq, "in matrix.c");
1130
1131 /* Un-transpose the matrix for Gauss elimination */
1132 for( i = 1; i < n; i++ )
1133 for( j = 0; j < i; j++ )
1134 {
1135 arj = a[i+j*ndim];
1136 a[i+j*ndim] = a[j+i*ndim];
1137 a[j+i*ndim] = arj;
1138 }
1139
1140 iflg=FALSE;
1141 /* step 1 */
1142 for( r = 0; r < n; r++ )
1143 {
1144 for( k = 0; k < n; k++ )
1145 scm[k]= a[k+r*ndim];
1146
1147 /* steps 2 and 3 */
1148 rm1= r;
1149 if( rm1 > 0)
1150 {
1151 for( j = 0; j < rm1; j++ )
1152 {
1153 pj= ip[j]-1;
1154 arj= scm[pj];
1155 a[j+r*ndim]= arj;
1156 scm[pj]= scm[j];
1157 jp1= j+1;
1158
1159 for( i = jp1; i < n; i++ )
1160 scm[i] -= a[i+j*ndim]* arj;
1161
1162 } /* for( j = 0; j < rm1; j++ ) */
1163
1164 } /* if( rm1 >= 0.0) */
1165
1166 /* step 4 */
1167 dmax= creal( scm[r]*conj(scm[r]) );
1168
1169 rp1= r+1;
1170 ip[r]= rp1;
1171 if( rp1 < n)
1172 {
1173 for( i = rp1; i < n; i++ )
1174 {
1175 elmag= creal( scm[i]* conj(scm[i]) );
1176 if( elmag >= dmax)
1177 {
1178 dmax= elmag;
1179 ip[r]= i+1;
1180 }
1181 }
1182 } /* if( rp1 < n) */
1183
1184 if( dmax < 1.0e-10)
1185 iflg=TRUE;
1186
1187 pr= ip[r]-1;
1188 a[r+r*ndim]= scm[pr];
1189 scm[pr]= scm[r];
1190
1191 /* step 5 */
1192 if( rp1 < n)
1193 {
1194 arj=1.0/ a[r+r*ndim];
1195
1196 for( i = rp1; i < n; i++ )
1197 a[i+r*ndim]= scm[i]* arj;
1198 }
1199
1200 if( iflg == TRUE )
1201 {
1202 fprintf( stderr,
1203 "xnec2c: pivot(%d)= %16.8E\n", r, dmax );
1204 iflg=FALSE;
1205 }
1206
1207 } /* for( r=0; r < n; r++ ) */
1208
1209 free_ptr( (void **)&scm );
1210
1211 return;
1212 }
1213
1214 /*-----------------------------------------------------------------------*/
1215
1216 /* factrs, for symmetric structure, transforms submatricies to form */
1217 /* matricies of the symmetric modes and calls routine to factor */
1218 /* matricies. if no symmetry, the routine is called to factor the */
1219 /* complete matrix. */
factrs(int np,int nrow,complex double * a,int * ip)1220 void factrs( int np, int nrow, complex double *a, int *ip )
1221 {
1222 int kk, ka;
1223
1224 smat.nop = nrow/np;
1225 for( kk = 0; kk < smat.nop; kk++ )
1226 {
1227 ka= kk* np;
1228 factr( np, &a[ka], &ip[ka], nrow );
1229 }
1230 return;
1231 }
1232
1233 /*-----------------------------------------------------------------------*/
1234
1235 /* fblock sets parameters for out-of-core */
1236 /* solution for the primary matrix (a) */
1237 void
fblock(int nrow,int ncol,int imax,int ipsym)1238 fblock( int nrow, int ncol, int imax, int ipsym )
1239 {
1240 int i, j, k, ka, kk;
1241 double phaz, arg;
1242 complex double deter;
1243
1244 if( nrow*ncol <= imax)
1245 {
1246 matpar.npblk= nrow;
1247 matpar.nlast= nrow;
1248 matpar.imat= nrow* ncol;
1249
1250 if( nrow == ncol)
1251 {
1252 matpar.icase=1;
1253 return;
1254 }
1255 else matpar.icase=2;
1256
1257 } /* if( nrow*ncol <= imax) */
1258
1259 smat.nop = ncol/nrow;
1260 if( smat.nop*nrow != ncol)
1261 {
1262 fprintf( stderr,
1263 "xnec2c: fblock(): symmetry error - nrow:%d ncol:%d\n",nrow, ncol );
1264 stop( _("fblock(): Symmetry error"), ERR_STOP );
1265 }
1266
1267 /* set up smat.ssx matrix for rotational symmetry. */
1268 if( ipsym <= 0)
1269 {
1270 phaz = TP/smat.nop;
1271
1272 for( i = 1; i < smat.nop; i++ )
1273 {
1274 for( j= i; j < smat.nop; j++ )
1275 {
1276 arg= phaz* (double)i * (double)j;
1277 smat.ssx[i+j*smat.nop]= cmplx( cos( arg), sin( arg));
1278 smat.ssx[j+i*smat.nop]= smat.ssx[i+j*smat.nop];
1279 }
1280 }
1281 return;
1282
1283 } /* if( ipsym <= 0) */
1284
1285 /* set up smat.ssx matrix for plane symmetry */
1286 kk=1;
1287 smat.ssx[0]=CPLX_10;
1288
1289 k = 2;
1290 for( ka = 1; k != smat.nop; ka++ )
1291 k *= 2;
1292
1293 for( k = 0; k < ka; k++ )
1294 {
1295 for( i = 0; i < kk; i++ )
1296 {
1297 for( j = 0; j < kk; j++ )
1298 {
1299 deter= smat.ssx[i+j*smat.nop];
1300 smat.ssx[i+(j+kk)*smat.nop]= deter;
1301 smat.ssx[i+kk+(j+kk)*smat.nop]= -deter;
1302 smat.ssx[i+kk+j*smat.nop]= deter;
1303 }
1304 }
1305 kk *= 2;
1306
1307 } /* for( k = 0; k < ka; k++ ) */
1308
1309 return;
1310 }
1311
1312 /*-----------------------------------------------------------------------*/
1313
1314
1315 /* subroutine to solve the matrix equation lu*x=b where l is a unit */
1316 /* lower triangular matrix and u is an upper triangular matrix both */
1317 /* of which are stored in a. the rhs vector b is input and the */
1318 /* solution is returned through vector b. (matrix transposed) */
1319 void
solve(int n,complex double * a,int * ip,complex double * b,int ndim)1320 solve( int n, complex double *a, int *ip,
1321 complex double *b, int ndim )
1322 {
1323 int i, ip1, j, k, pia;
1324 complex double sum, *scm = NULL;
1325
1326 /* Allocate to scratch memory */
1327 size_t mreq = (size_t)data.np2m * sizeof(complex double);
1328 mem_alloc( (void **)&scm, mreq, "in matrix.c");
1329
1330 /* forward substitution */
1331 for( i = 0; i < n; i++ )
1332 {
1333 pia= ip[i]-1;
1334 scm[i]= b[pia];
1335 b[pia]= b[i];
1336 ip1= i+1;
1337
1338 if( ip1 < n)
1339 for( j = ip1; j < n; j++ )
1340 b[j] -= a[j+i*ndim]* scm[i];
1341 }
1342
1343 /* backward substitution */
1344 for( k = 0; k < n; k++ )
1345 {
1346 i= n-k-1;
1347 sum=CPLX_00;
1348 ip1= i+1;
1349
1350 if( ip1 < n)
1351 for( j = ip1; j < n; j++ )
1352 sum += a[i+j*ndim]* b[j];
1353
1354 b[i]=( scm[i]- sum)/ a[i+i*ndim];
1355 }
1356
1357 free_ptr( (void **)&scm );
1358
1359 return;
1360 }
1361
1362 /*-----------------------------------------------------------------------*/
1363
1364 /* subroutine solves, for symmetric structures, handles the */
1365 /* transformation of the right hand side vector and solution */
1366 /* of the matrix eq. */
1367 void
solves(complex double * a,int * ip,complex double * b,int neq,int nrh,int np,int n,int mp,int m)1368 solves( complex double *a, int *ip,
1369 complex double *b, int neq, int nrh,
1370 int np, int n, int mp, int m)
1371 {
1372 int npeq, nrow, ic, i, kk, ia, ib, j, k;
1373 double fnop, fnorm;
1374 complex double sum, *scm = NULL;
1375
1376 npeq= np+ 2*mp;
1377 smat.nop = neq/npeq;
1378 fnop= smat.nop;
1379 fnorm=1.0/ fnop;
1380 nrow= neq;
1381
1382 /* Allocate to scratch memory */
1383 size_t mreq = (size_t)data.np2m * sizeof(complex double);
1384 mem_alloc( (void **)&scm, mreq, "in matrix.c");
1385
1386 if( smat.nop != 1)
1387 {
1388 for( ic = 0; ic < nrh; ic++ )
1389 {
1390 if( (n != 0) && (m != 0) )
1391 {
1392 for( i = 0; i < neq; i++ )
1393 scm[i]= b[i+ic*neq];
1394
1395 kk=2* mp;
1396 ia= np-1;
1397 ib= n-1;
1398 j= np-1;
1399
1400 for( k = 0; k < smat.nop; k++ )
1401 {
1402 if( k != 0 )
1403 {
1404 for( i = 0; i < np; i++ )
1405 {
1406 ia++;
1407 j++;
1408 b[j+ic*neq]= scm[ia];
1409 }
1410
1411 if( k == (smat.nop-1) )
1412 continue;
1413
1414 } /* if( k != 0 ) */
1415
1416 for( i = 0; i < kk; i++ )
1417 {
1418 ib++;
1419 j++;
1420 b[j+ic*neq]= scm[ib];
1421 }
1422
1423 } /* for( k = 0; k < smat.nop; k++ ) */
1424
1425 } /* if( (n != 0) && (m != 0) ) */
1426
1427 /* transform matrix eq. rhs vector according to symmetry modes */
1428 for( i = 0; i < npeq; i++ )
1429 {
1430 for( k = 0; k < smat.nop; k++ )
1431 {
1432 ia= i+ k* npeq;
1433 scm[k]= b[ia+ic*neq];
1434 }
1435
1436 sum= scm[0];
1437 for( k = 1; k < smat.nop; k++ )
1438 sum += scm[k];
1439
1440 b[i+ic*neq]= sum* fnorm;
1441
1442 for( k = 1; k < smat.nop; k++ )
1443 {
1444 ia= i+ k* npeq;
1445 sum= scm[0];
1446
1447 for( j = 1; j < smat.nop; j++ )
1448 sum += scm[j]* conj( smat.ssx[k+j*smat.nop]);
1449
1450 b[ia+ic*neq]= sum* fnorm;
1451 }
1452
1453 } /* for( i = 0; i < npeq; i++ ) */
1454
1455 } /* for( ic = 0; ic < nrh; ic++ ) */
1456
1457 } /* if( smat.nop != 1) */
1458
1459 /* solve each mode equation */
1460 for( kk = 0; kk < smat.nop; kk++ )
1461 {
1462 ia= kk* npeq;
1463 ib= ia;
1464
1465 for( ic = 0; ic < nrh; ic++ )
1466 solve( npeq, &a[ib], &ip[ia], &b[ia+ic*neq], nrow );
1467
1468 } /* for( kk = 0; kk < smat.nop; kk++ ) */
1469
1470 if( smat.nop == 1)
1471 {
1472 free_ptr( (void **)&scm );
1473 return;
1474 }
1475
1476 /* inverse transform the mode solutions */
1477 for( ic = 0; ic < nrh; ic++ )
1478 {
1479 for( i = 0; i < npeq; i++ )
1480 {
1481 for( k = 0; k < smat.nop; k++ )
1482 {
1483 ia= i+ k* npeq;
1484 scm[k]= b[ia+ic*neq];
1485 }
1486
1487 sum= scm[0];
1488 for( k = 1; k < smat.nop; k++ )
1489 sum += scm[k];
1490
1491 b[i+ic*neq]= sum;
1492 for( k = 1; k < smat.nop; k++ )
1493 {
1494 ia= i+ k* npeq;
1495 sum= scm[0];
1496
1497 for( j = 1; j < smat.nop; j++ )
1498 sum += scm[j]* smat.ssx[k+j*smat.nop];
1499
1500 b[ia+ic*neq]= sum;
1501 }
1502
1503 } /* for( i = 0; i < npeq; i++ ) */
1504
1505 if( (n == 0) || (m == 0) )
1506 continue;
1507
1508 for( i = 0; i < neq; i++ )
1509 scm[i]= b[i+ic*neq];
1510
1511 kk=2* mp;
1512 ia= np-1;
1513 ib= n-1;
1514 j= np-1;
1515
1516 for( k = 0; k < smat.nop; k++ )
1517 {
1518 if( k != 0 )
1519 {
1520 for( i = 0; i < np; i++ )
1521 {
1522 ia++;
1523 j++;
1524 b[ia+ic*neq]= scm[j];
1525 }
1526
1527 if( k == smat.nop)
1528 continue;
1529
1530 } /* if( k != 0 ) */
1531
1532 for( i = 0; i < kk; i++ )
1533 {
1534 ib++;
1535 j++;
1536 b[ib+ic*neq]= scm[j];
1537 }
1538
1539 } /* for( k = 0; k < smat.nop; k++ ) */
1540
1541 } /* for( ic = 0; ic < nrh; ic++ ) */
1542
1543 free_ptr( (void **)&scm );
1544
1545 return;
1546 }
1547
1548 /*-----------------------------------------------------------------------*/
1549
1550