Advertisement
Guest User

Untitled

a guest
Jan 26th, 2020
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.12 KB | None | 0 0
  1. import numpy as np
  2. from grid import Grid
  3. from universal_element import UniversalElement
  4. import shape_f
  5. from data import Data
  6. from jacobian import Jacobian
  7. from matrixH import MatrixH
  8. from matrixC import MatrixC
  9. from matrixHBC import MatrixHBC
  10.  
  11.  
  12. class FEM:
  13. def __init__(self, height, width, nodes_height, nodes_width):
  14. self.g = Grid(height, width, nodes_height, nodes_width)
  15. self.u_e = UniversalElement()
  16. self.d = Data()
  17. self.j = Jacobian(self.g, self.u_e, self.d)
  18. self.h = MatrixH(self.g, self.u_e, self.d, self.j)
  19. self.c = MatrixC(self.g, self.u_e, self.d, self.j)
  20. self.hbc = MatrixHBC(self.g, self.u_e, self.d, self.j, self.h)
  21.  
  22.  
  23. self.H_g = np.zeros((self.g.n_n, self.g.n_n))
  24. self.C_g = np.zeros((self.g.n_n, self.g.n_n))
  25. self.H_Cdt = np.zeros((self.g.n_n, self.g.n_n))
  26. self.calculate_h_g_c_g()
  27. self.calculate_h_cdt_g()
  28.  
  29. self.p_for_side_pc = np.zeros((self.d.number_of_sides, self.d.number_of_pc_for_bc, self.u_e.num_of_shape_f,
  30. self.d.vector_columns))
  31. self.p_for_side = np.zeros((self.d.number_of_sides, self.u_e.num_of_shape_f, self.d.vector_columns))
  32. self.p_for_elements = np.zeros((self.g.n_e, self.u_e.num_of_shape_f, self.d.vector_columns))
  33. self.calculate_p_for_side_pc()
  34. self.calculate_p_for_sides()
  35. self.calculate_p_for_elements()
  36.  
  37. self.P_g = np.zeros((self.g.n_n, 1))
  38. self.calculate_p_g()
  39.  
  40. self.T_1 = np.zeros((self.g.n_n, 1))
  41. self.T_1.fill(100)
  42. self.P_Cdt_T0 = np.zeros((self.g.n_n, 1))
  43. self.calculate_p_cdt_t0()
  44.  
  45. self.min_max_temperatures = np.zeros((self.d.number_of_steps, 1, 2))
  46. self.simulate()
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55. # AGREGACJA macierzy h i macierzy c (czyli dodawanie do odpowiednich komórek macierzy globalnej odpowiednich komó©ek macierzy lokalnych - po to mamy zapisane indeksy nodeów w elemetach) - powstaje macierz H i c dla całej siatki (o rozmairze ilość nodeów*ilość nodeów)
  56. def calculate_h_g_c_g(self):
  57. for i in range(self.g.n_e):
  58. i1 = 0
  59. for j in self.g.elements[i].nodes_id:
  60. i2 = 0
  61. for k in self.g.elements[i].nodes_id:
  62. self.H_g[j][k] += self.hbc.h_plus_hbc[i][i1][i2]
  63. self.C_g[j][k] += self.c.c_for_el[i][i1][i2]
  64.  
  65. i2 += 1
  66. i1 += 1
  67.  
  68. # implementaja wzorku co jest w pdfach (to się nie zmienia, jest stale w symulacji)
  69. def calculate_h_cdt_g(self):
  70. self.H_Cdt = self.H_g + self.C_g/self.d.dT
  71.  
  72.  
  73. # wektor p liczy się jak hbc, więc opisałem powyżej (w sumie to to samo tyle że z minusem XD)
  74. # TODO: shorten the code using nested loops
  75. def calculate_p_for_side_pc(self):
  76. # POINT: side / point / coordinate
  77. # MATRIX: side / point / shape_f
  78. # 1:
  79. self.p_for_side_pc[0][0][0] = -shape_f.n1(self.u_e.int_points_for_Hbc[0][0][0],
  80. self.u_e.int_points_for_Hbc[0][0][1])
  81. self.p_for_side_pc[0][0][1] = -shape_f.n2(self.u_e.int_points_for_Hbc[0][0][0],
  82. self.u_e.int_points_for_Hbc[0][0][1])
  83.  
  84. self.p_for_side_pc[0][1][0] = -shape_f.n1(self.u_e.int_points_for_Hbc[0][1][0],
  85. self.u_e.int_points_for_Hbc[0][1][1])
  86. self.p_for_side_pc[0][1][1] = -shape_f.n2(self.u_e.int_points_for_Hbc[0][1][0],
  87. self.u_e.int_points_for_Hbc[0][1][1])
  88. # 2:
  89. self.p_for_side_pc[1][0][1] = -shape_f.n2(self.u_e.int_points_for_Hbc[1][0][0],
  90. self.u_e.int_points_for_Hbc[1][0][1])
  91. self.p_for_side_pc[1][0][2] = -shape_f.n3(self.u_e.int_points_for_Hbc[1][0][0],
  92. self.u_e.int_points_for_Hbc[1][0][1])
  93.  
  94. self.p_for_side_pc[1][1][1] = -shape_f.n2(self.u_e.int_points_for_Hbc[1][1][0],
  95. self.u_e.int_points_for_Hbc[1][1][1])
  96. self.p_for_side_pc[1][1][2] = -shape_f.n3(self.u_e.int_points_for_Hbc[1][1][0],
  97. self.u_e.int_points_for_Hbc[1][1][1])
  98. # 3:
  99. self.p_for_side_pc[2][0][2] = -shape_f.n3(self.u_e.int_points_for_Hbc[2][0][0],
  100. self.u_e.int_points_for_Hbc[2][0][1])
  101. self.p_for_side_pc[2][0][3] = -shape_f.n4(self.u_e.int_points_for_Hbc[2][0][0],
  102. self.u_e.int_points_for_Hbc[2][0][1])
  103.  
  104. self.p_for_side_pc[2][1][2] = -shape_f.n3(self.u_e.int_points_for_Hbc[2][1][0],
  105. self.u_e.int_points_for_Hbc[2][1][1])
  106. self.p_for_side_pc[2][1][3] = -shape_f.n4(self.u_e.int_points_for_Hbc[2][1][0],
  107. self.u_e.int_points_for_Hbc[2][1][1])
  108. # 4:
  109. self.p_for_side_pc[3][0][0] = -shape_f.n1(self.u_e.int_points_for_Hbc[3][0][0],
  110. self.u_e.int_points_for_Hbc[3][0][1])
  111. self.p_for_side_pc[3][0][3] = -shape_f.n4(self.u_e.int_points_for_Hbc[3][0][0],
  112. self.u_e.int_points_for_Hbc[3][0][1])
  113.  
  114. self.p_for_side_pc[3][1][0] = -shape_f.n1(self.u_e.int_points_for_Hbc[3][1][0],
  115. self.u_e.int_points_for_Hbc[3][1][1])
  116. self.p_for_side_pc[3][1][3] = -shape_f.n4(self.u_e.int_points_for_Hbc[3][1][0],
  117. self.u_e.int_points_for_Hbc[3][1][1])
  118.  
  119. # to liczę jak calculate_hbc_4x4 (opisane wyżej, tylko tu inne stałe są)
  120. def calculate_p_for_sides(self):
  121. for i in range(0, 4, 2):
  122. self.p_for_side[i] = (self.hbc.hbc_4x1[i][0]*self.d.weights_hbc[0] +
  123. self.hbc.hbc_4x1[i][1]*self.d.weights_hbc[1])* \
  124. self.d.alfa*self.d.t_ot*self.g.dx/2
  125. self.p_for_side[i + 1] = (self.hbc.hbc_4x1[i + 1][0]*self.d.weights_hbc[0] +
  126. self.hbc.hbc_4x1[i + 1][1]*self.d.weights_hbc[1])* \
  127. self.d.alfa*self.d.t_ot*self.g.dy/2
  128.  
  129. # liczę dla każdego elementu wektor p czyli dodaję wektory p dla ścian do elementów co są na brzegch(a te co w środku mają wektor p = 0)
  130. def calculate_p_for_elements(self):
  131. j = self.g.n_e - 1
  132. for i in range(self.g.n_h - 1):
  133. self.p_for_elements[i] += self.p_for_side[3]
  134. self.p_for_elements[j] += self.p_for_side[1]
  135. j -= 1
  136. j = self.g.n_h - 2
  137. i = 0
  138. while i < self.g.n_e - 1:
  139. self.p_for_elements[i] += self.p_for_side[0]
  140. self.p_for_elements[j] += self.p_for_side[2]
  141. i += self.g.n_h - 1
  142. j += self.g.n_h - 1
  143.  
  144. # agregacja wektora P (podobnie jak agregacja h i c)
  145. def calculate_p_g(self):
  146. for i in range(self.g.n_e):
  147. i1 = 0
  148. for j in self.g.elements[i].nodes_id:
  149. self.P_g[j] += self.p_for_elements[i][i1]
  150. i1 += 1
  151.  
  152. # to się zmienia co iterację (ale na początku trza raz policzyć to sb odrębną funkcję napisałem xD)
  153. # T1 to jest wektor temperatur początkowych dla nodeów (w pdf to jest T0)
  154. def calculate_p_cdt_t0(self):
  155. self.P_Cdt_T0 = self.P_g + (self.C_g/self.d.dT).dot(self.T_1)
  156.  
  157. # tu się liczy wektor T1 - czyli wektor temperatur po czasie dT, i go liczę dla każdej iteraci i tylko on się zmienia
  158. # wzorki masz wypisane w pdf co jest test case
  159. # a min max wyciąga min i max wartość z wektora p
  160. def simulate(self):
  161. for i in range(10):
  162. self.T_1 = np.linalg.inv(self.H_Cdt).dot((self.C_g/self.d.dT).dot(self.T_1) + self.P_g)
  163. self.min_max_temperatures[i] = [self.T_1.min(), self.T_1.max()]
  164.  
  165.  
  166. f = FEM(0.1, 0.1, 4, 4)
  167. print(f.min_max_temperatures)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement