assemble_free_space.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*
  2. FACILITY: NMMTL
  3. MODULE DESCRIPTION:
  4. Contains nmmtl_assemble_free_space function.
  5. AUTHOR(S):
  6. Kevin J. Buchs
  7. CREATION DATE: Mon Mar 30 12:47:58 1992
  8. COPYRIGHT: Copyright (C) 1992 by Mayo Foundation. All rights reserved.
  9. */
  10. /*
  11. *******************************************************************
  12. ** INCLUDE FILES
  13. *******************************************************************
  14. */
  15. #include "nmmtl.h"
  16. /*
  17. *******************************************************************
  18. ** STRUCTURE DECLARATIONS AND TYPE DEFINTIONS
  19. *******************************************************************
  20. */
  21. /*
  22. *******************************************************************
  23. ** MACRO DEFINITIONS
  24. *******************************************************************
  25. */
  26. /*
  27. *******************************************************************
  28. ** PREPROCESSOR CONSTANTS
  29. *******************************************************************
  30. */
  31. /*
  32. *******************************************************************
  33. ** GLOBALS
  34. *******************************************************************
  35. */
  36. /*
  37. *******************************************************************
  38. ** FUNCTION DECLARATIONS
  39. *******************************************************************
  40. */
  41. /*
  42. *******************************************************************
  43. ** FUNCTION DEFINITIONS
  44. *******************************************************************
  45. */
  46. /*
  47. FUNCTION NAME: nmmtl_assemble_free_space
  48. FUNCTIONAL DESCRIPTION:
  49. Calculates the assemble matrix for the Boundary element
  50. solution of Multilayer, Multiconductor Transmission Line
  51. Quasi-static Parameter calculations. This is the free space
  52. version of nmmtl_assemble, and it assumes that no dielectric
  53. material exists, it is all free space. It goes through the elements
  54. in the system only if they are dielectric-conductor
  55. elements, and computes their contribution to each node in the
  56. system. Later, the assemble matrix is used to solve a matrix equation
  57. FORMAL PARAMETERS:
  58. int conductor_counter, - how many conductors
  59. CONDUCTOR_DATA_P conductor_data, - array of data on conductors
  60. float **assemble_matrix - out: resultant assemble matrix
  61. RETURN VALUE:
  62. None
  63. CALLING SEQUENCE:
  64. nmmtl_assemble_free_space(conductor_counter,conductor_data,
  65. assemble_matrix);
  66. */
  67. void nmmtl_assemble_free_space(int conductor_counter,
  68. CONDUCTOR_DATA_P conductor_data,
  69. float **assemble_matrix)
  70. {
  71. int i,j,cond_num,inner_cond_num;
  72. CELEMENTS_P cel,inner_cel;
  73. int Legendre_counter;
  74. double x,y; /* interpolated coordinates */
  75. double shape[INTERP_PTS];
  76. double value[INTERP_PTS];
  77. double Jacobian;
  78. double nu0,nu1;
  79. /* matrix should be zeroed */
  80. /* create outer loop on the the conductor elements - by looping on
  81. both conductors and then each element of each conductor */
  82. for(cond_num = 0; cond_num <= conductor_counter; cond_num++)
  83. {
  84. cel=conductor_data[cond_num].elements;
  85. while(cel != NULL)
  86. {
  87. for(Legendre_counter = 0; Legendre_counter < Legendre_root_a_max;
  88. Legendre_counter++)
  89. {
  90. nmmtl_shape(Legendre_root_a[Legendre_counter],shape);
  91. /* interpolate x,y coordinate using no_edge shape function */
  92. x = 0.0;
  93. y = 0.0;
  94. for(i=0;i < INTERP_PTS;i++)
  95. {
  96. x += shape[i]*cel->xpts[i];
  97. y += shape[i]*cel->ypts[i];
  98. }
  99. /* if an edge element - recalculate shape using edge effects */
  100. if(cel->edge[0] != NULL || cel->edge[1] != NULL)
  101. {
  102. /* if given edge is really an edge, set the true value of nu,
  103. otherwise, don't really care */
  104. nu0 = cel->edge[0] ? cel->edge[0]->free_space_nu : 0;
  105. nu1 = cel->edge[1] ? cel->edge[1]->free_space_nu : 0;
  106. nmmtl_shape_c_edge(Legendre_root_a[Legendre_counter],shape,cel,
  107. nu0,nu1);
  108. }
  109. nmmtl_jacobian_c(Legendre_root_a[Legendre_counter],cel,&Jacobian);
  110. /* Now an inner loop over all the elements, performing an
  111. integration in each call to nmmtl_interval_*** */
  112. /* inner loop on conductor elements - broken into 3 parts - want
  113. to act differently for the self element - inner_cel == cel and
  114. this will only need to be checked while inner_cond_num == cond_num
  115. */
  116. /* PART 1 */
  117. for(inner_cond_num = 0; inner_cond_num < cond_num;
  118. inner_cond_num++)
  119. {
  120. inner_cel=conductor_data[inner_cond_num].elements;
  121. while(inner_cel != NULL)
  122. {
  123. nmmtl_interval_c_fs(x,y,inner_cel,value);
  124. /* now add in the contributions to the the basis points */
  125. for(i=0;i < INTERP_PTS;i++)
  126. {
  127. for(j=0;j < INTERP_PTS;j++)
  128. {
  129. assemble_matrix[inner_cel->node[j]][cel->node[i]] +=
  130. ASSEMBLE_CONST_1 * Legendre_weight_a[Legendre_counter] *
  131. shape[i] * value[j] * Jacobian;
  132. }
  133. }
  134. inner_cel = inner_cel->next;
  135. } /* while inner looping on elements of a particular conductor */
  136. } /* for inner looping on the conductors */
  137. /* PART 2 */
  138. inner_cel=conductor_data[inner_cond_num].elements;
  139. while(inner_cel != NULL)
  140. {
  141. /* Are we at the self element ? */
  142. if(cel == inner_cel)
  143. nmmtl_interval_self_c_fs(x,y,inner_cel,value,
  144. Legendre_root_a[Legendre_counter]);
  145. else
  146. nmmtl_interval_c_fs(x,y,inner_cel,value);
  147. /* now add in the contributions to the the basis points */
  148. for(i=0;i < INTERP_PTS;i++)
  149. {
  150. for(j=0;j < INTERP_PTS;j++)
  151. {
  152. assemble_matrix[inner_cel->node[j]][cel->node[i]] +=
  153. ASSEMBLE_CONST_1 * Legendre_weight_a[Legendre_counter] *
  154. shape[i] * value[j] * Jacobian;
  155. }
  156. }
  157. inner_cel = inner_cel->next;
  158. } /* while inner looping on elements of a particular conductor */
  159. /* PART 3 */
  160. for(inner_cond_num++; inner_cond_num <= conductor_counter;
  161. inner_cond_num++)
  162. {
  163. inner_cel=conductor_data[inner_cond_num].elements;
  164. while(inner_cel != NULL)
  165. {
  166. nmmtl_interval_c_fs(x,y,inner_cel,value);
  167. /* now add in the contributions to the the basis points */
  168. for(i=0;i < INTERP_PTS;i++)
  169. {
  170. for(j=0;j < INTERP_PTS;j++)
  171. {
  172. assemble_matrix[inner_cel->node[j]][cel->node[i]] +=
  173. ASSEMBLE_CONST_1 * Legendre_weight_a[Legendre_counter] *
  174. shape[i] * value[j] * Jacobian;
  175. }
  176. }
  177. inner_cel = inner_cel->next;
  178. } /* while inner looping on elements of a particular conductor */
  179. } /* for inner looping on the conductors */
  180. } /* while stepping through Guass-Legendre roots */
  181. cel = cel->next;
  182. } /* while outer looping on elments of a conductor */
  183. } /* while outer looping on conductors */
  184. }