Skip to content

Commit fe6e34e

Browse files
committed
Added acoustics
Added help
1 parent 95fda16 commit fe6e34e

19 files changed

+288
-69
lines changed

Notes

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ KNOWN BUGS:
66

77
#######################################################################################
88
TODOs:
9+
--> Output solution consecutive filename
910
--> Docstrings and typehints
1011
--> Weitere Überprüfung Geometrie auf Kompatibilität (Entweder in Klasse Geometry oder CreateBCParams)
1112
--> Hilfe-Button in Fenstern GUI, GEOMETRY und SHOWSOLUTION mit kleiner Erläuterung
@@ -52,7 +53,7 @@ GUI -> init_parameters()
5253
'1': {'coordinates': [(1.0, 0.0), (1.0, 1.0)], 'bc': {'type': None, 'value': None}}, '2': {'coordinates': [(1.0, 1.0), (0.0, 1.0)], 'bc': {'type': None, 'value': None}}, '3': {'coordinates': [(0.0, 1.0), (0.0, 0.0)], 'bc': {'type': None, 'value': None}}, '4': {'coordinates': [(1.0, 1.0), (1.0, 2.0)], 'bc': {'type': None, 'value': None}}, '5': {'coordinates': [(1.0, 2.0), (0.0, 1.0)], 'bc': {'type': None, 'value': None}}}
5354
self.node_parameters : {'0': {'coordinates': (0.5, 0.5), 'bc': {'type': None, 'value': None}},
5455
'1': {'coordinates': (0.0, 0.0), 'bc': {'type': None, 'value': None}}, '2': {'coordinates': (1.0, 0.0), 'bc': {'type': None, 'value': None}}, '3': {'coordinates': (1.0, 1.0), 'bc': {'type': None, 'value': None}}, '4': {'coordinates': (0.0, 1.0), 'bc': {'type': None, 'value': None}}, '5': {'coordinates': (1.0, 2.0), 'bc': {'type': None, 'value': None}}}
55-
self.calculation_parameters : {'mesh_density': None, 'freq': None, 'equation': 'HE'}
56+
self.calculation_parameters : {'mesh_density': None, 'freq': None, 'equation': 'HE', 'units': 'm'}
5657

5758
4) Definition von Randbedingungen, Regionen und Calculation Parametern
5859
GUI -> assign_BCs() | assign_materials() | assign_calc_params()

calcfem.py

+93-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from typing import List, Tuple, Union
99
from scipy.sparse import coo_matrix
1010
import copy
11-
11+
from guistatics import GUIStatics
1212
class CalcFEM:
1313

1414
def __init__(self, params_mesh, params_boundaries_materials):
@@ -28,6 +28,7 @@ def __init__(self, params_mesh, params_boundaries_materials):
2828
self.boundary_parameters = params_boundaries_materials[1]
2929
self.node_parameters = params_boundaries_materials[2]
3030
self.calculation_parameters = params_boundaries_materials[3]
31+
3132
# Instance vars created
3233
self.all_element_matrices_steif = None
3334
self.all_element_matrices_mass = None
@@ -38,9 +39,9 @@ def __init__(self, params_mesh, params_boundaries_materials):
3839
self.sysmatrix_diri = None # Systemmatrix after implementing Dirichlet Cond
3940
self.force_vector_diri = None # Force Vector after implementing Dirichlet Cond
4041
self.solution = None
41-
42+
self.acoustic_source = None # sources if equation is 'HH'
4243
# development
43-
self.file_path_dev = r'testing\output_gui_4_calcfem_' + '1' + '.txt'
44+
self.file_path_dev = r'testing\output_gui_4_calcfem_' + '2' + '.txt'
4445

4546
def develop_print_input(self):
4647
print("\n\n\n------------------DEBUG--------------------")
@@ -73,9 +74,9 @@ def calc_fem(self):
7374
:return:
7475
"""
7576

76-
7777
# set equation
7878
self.equation = self.calculation_parameters['equation'] # either HE (HeatEquation) or HH (HelmHoltz)
79+
#self.equation = 'HH' # todo for dev!
7980

8081
# calculate element matrices
8182
self.calc_elementmatrices()
@@ -86,6 +87,11 @@ def calc_fem(self):
8687
# create force vector
8788
self.create_force_vector()
8889

90+
# implement acoustic sources if helmholtz equation
91+
if self.equation =='HH':
92+
self.calculate_acoustic_sources()
93+
self.implement_acoustic_sources()
94+
8995
# implement boundary conditions
9096
self.implement_boundary_conditions()
9197

@@ -96,10 +102,82 @@ def calc_fem(self):
96102
self.solve_linear_system()
97103

98104
# plot solution
99-
self.plot_solution(self.solution, self.nodes_mesh_gen, self.triangulation)
105+
# self.plot_solution(self.solution, self.nodes_mesh_gen, self.triangulation)
100106

101107
return self.solution
102108

109+
def get_region_for_node_nbr(self, node):
110+
"""
111+
Gets the region number for a node
112+
:param node:
113+
:return:
114+
"""
115+
for key, val in self.triangulation_region_dict.items():
116+
if node in val:
117+
return key
118+
119+
def implement_acoustic_sources(self):
120+
"""
121+
Implements acoustic source, if any, into force vector for calculation Helmholtz equation
122+
:return:
123+
"""
124+
for pos, val in self.acoustic_source:
125+
self.force_vector[pos] = self.force_vector[pos] + val
126+
127+
128+
129+
def calculate_acoustic_sources(self):
130+
"""
131+
calculates acoustic source values
132+
:return:
133+
"""
134+
135+
freq = float(self.calculation_parameters['freq'])
136+
omega = freq * 2 * math.pi
137+
138+
self.acoustic_source = list()
139+
for node_nbr, vals in self.node_parameters.items():
140+
val_bc = vals['bc']['value']
141+
if val_bc:
142+
node_pos = self.single_nodes_dict[node_nbr]
143+
region_nbr = self.get_region_for_node_nbr(node_pos)
144+
rho = self.region_parameters[region_nbr]['material']['rho']
145+
mpsource = 4 * math.pi / rho * ((2 * rho * omega) / ((2 * math.pi) ** 2)) ** 0.5
146+
self.acoustic_source.append([node_pos, mpsource])
147+
148+
149+
150+
def plot_solution_dev(self):
151+
"""
152+
Plots the solution via matplotlib
153+
"""
154+
solution = self.solution
155+
all_points = self.nodes_mesh_gen
156+
triangles = self.triangulation
157+
158+
dataz = np.real(solution)
159+
values = dataz
160+
aspectxy = 1
161+
triang_mpl = tri.Triangulation(all_points[:, 0], all_points[:, 1], triangles)
162+
163+
fig, ax = plt.subplots(figsize=(12, 8))
164+
165+
units = self.calculation_parameters['units']
166+
ax.set_title('solution')
167+
ax.set_xlabel(f"x [{units}]")
168+
ax.set_ylabel(f"y [{units}]")
169+
ax.set_aspect(aspectxy)
170+
171+
contour = ax.tricontourf(triang_mpl, values, cmap='viridis', levels=20)
172+
divider = make_axes_locatable(ax)
173+
cax = divider.append_axes("right", size="5%", pad=0.2)
174+
cbar = fig.colorbar(contour, cax=cax)
175+
176+
ax.scatter(all_points[:, 0], all_points[:, 1], c=values, cmap='viridis', marker='.',
177+
edgecolors='w', s=10)
178+
ax.triplot(triang_mpl, 'w-', linewidth=0.1)
179+
180+
plt.show()
103181

104182
@staticmethod
105183
def plot_solution(solution, all_points, triangles):
@@ -144,6 +222,7 @@ def implement_boundary_conditions(self):
144222

145223
# create dirichlet list for implementation of dirichlet boundary conditions
146224
dirichlet_dict = dict()
225+
print(self.boundary_parameters)
147226
for boundary_nbr, params in self.boundary_parameters.items():
148227
bc = params['bc']
149228
bc_type = bc['type']
@@ -158,8 +237,10 @@ def implement_boundary_conditions(self):
158237
dirichlet_dict[node] = bc_value
159238
dirichlet_list = np.array([[key, val] for key, val in dirichlet_dict.items()])
160239

161-
self.sysmatrix_diri, self.force_vector_diri = self.implement_dirichlet_condition(dirichlet_list, self.sysarray, self.force_vector)
162-
240+
if dirichlet_list:
241+
self.sysmatrix_diri, self.force_vector_diri = self.implement_dirichlet_condition(dirichlet_list, self.sysarray, self.force_vector)
242+
else:
243+
self.sysmatrix_diri, self.force_vector_diri = self.sysarray, self.force_vector
163244

164245
@staticmethod
165246
def implement_dirichlet_condition(dirichlet_list: np.array, system_matrix: np.array, force_vector: np.array):
@@ -226,7 +307,9 @@ def calc_system_matrices(self):
226307
if self.equation == 'HE':
227308
self.sysarray = self.syssteifarray
228309
elif self.equation == 'HH': # todo: include in elementmatrices
229-
...
310+
freq = float(self.calculation_parameters['freq'])
311+
omega = freq * 2 * math.pi
312+
self.sysarray = self.syssteifarray - omega**2 * self.sysmassarray
230313

231314

232315
def calc_elementmatrices(self):
@@ -314,6 +397,8 @@ def print_matrix(matrix: Union[np.array, list]):
314397
if __name__ == '__main__':
315398
calcfem = CalcFEM((0,0,0,0,0), (0,0,0,0)) # Develop
316399
calcfem.develop() # read date via exec(!)
400+
calcfem.calc_fem()
401+
calcfem.plot_solution_dev()
317402
# calcfem.nodes_mesh_gen = [[0.5, 0.5], [0., 0. ], [0.5, 0. ], [1., 0. ], [1., 0.5], [1., 1. ], [0.5, 1. ], [0., 1. ], [0., 0.5], [1., 1.5], [1., 2. ], [0.5, 1.5]]
318403
# calcfem.single_nodes_dict = {'0': 1, '1': 3, '2': 5, '3': 7, '4': 10}
319404
# calcfem.boundary_nodes_dict = {'0': [[1, np.array([0., 0.])], [2, np.array([0.5, 0. ])], [3, np.array([1., 0.])]], '1': [[3, np.array([1., 0.])], [4, np.array([1. , 0.5])], [5, np.array([1., 1.])]], '2': [[5, np.array([1., 1.])], [6, np.array([0.5, 1. ])], [7, np.array([0., 1.])]], '3': [[7, np.array([0., 1.])], [8, np.array([0. , 0.5])], [1, np.array([0., 0.])]], '4': [[5, np.array([1., 1.])], [9, np.array([1. , 1.5])], [10, np.array([1., 2.])]], '5': [[10, np.array([1., 2.])], [11, np.array([0.5, 1.5])], [7, np.array([0., 1.])]]}
@@ -341,4 +426,3 @@ def print_matrix(matrix: Union[np.array, list]):
341426
# '5': {'coordinates': (1.0, 2.0), 'bc': {'type': None, 'value': None}}}
342427
# calcfem.calculation_parameters = {'mesh_density': 1, 'freq': None, 'equation': 'HE'}
343428

344-
calcfem.calc_fem()

elements.py

+2
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ def phiqequdistarray(xi1: Union[np.array, float], xi2: Union[np.array, float]) -
253253
fp = phixphit * jacobi_det * integration_weights
254254
mass_mat = mass_mat + fp
255255

256+
stiffness_mat = stiffness_mat * 1/val_rho
257+
mass_mat = mass_mat * 1/val_rho * 1/(val_c**2)
256258
return stiffness_mat, mass_mat
257259

258260
@staticmethod

0 commit comments

Comments
 (0)