def helper_bi_mat(self, mat1_name, mat2_name, backings, tol): mat1 = from_yaml(THIS_FILE_DIR + '/materials/{}.yaml'.format(mat1_name)) mat2 = from_yaml(THIS_FILE_DIR + '/materials/{}.yaml'.format(mat2_name)) prefix = '{}_{}'.format(mat1_name, mat2_name) for (backing_type, backing_func) in backings: for (d1, d2) in itertools.product(THICKNESSES, THICKNESSES): filename = THIS_FILE_DIR + '/references/{}_{}mm_{}mm_{}.csv'.format( prefix, int(d1 * 1e3), int(d2 * 1e3), backing_type) if not os.path.exists(filename): continue reference = np.loadtxt(filename) for l in reference: S = Solver() S.layers = [Layer(mat1, d1), Layer(mat2, d2)] S.backing = backing_func result = S.solve(l[0], l[1]) asserts.assertAlmostEqual(result['R'][0], l[2] + 1j * l[3], tol) if backing_func == backing.transmission: asserts.assertAlmostEqual(result['T'][0], l[4] + 1j * l[5], tol)
def check_pwfem(self): for _e in self.pwfem_entities: if isinstance(_e, PwFem): for s in _e.neighbouring_surfaces: if isinstance(s, (Air, FluidFem)): _e.nb_R = 1 _e.typ = "fluid" elif (isinstance(s, ElasticFem)): _e.nb_R = 2 _e.typ = "elastic" elif isinstance(s, PemFem): if s.formulation98: _e.nb_R = 3 _e.typ = "Biot98" else: _e.nb_R = 3 _e.typ = "Biot01" if isinstance(_e, IncidentPwFem): if self.incident_ml: _e.ml = [] for _l in self.incident_ml: mat = from_yaml(_l[0]+".yaml") d = _l[1] _e.ml.append(Layer(mat,d)) if isinstance(_e, TransmissionPwFem): if self.transmission_ml: _e.ml = [] for _l in self.transmission_ml: mat = from_yaml(_l[0]+".yaml") d = -_l[1] # Thickness of transmission layers is set negative _e.ml.append(Layer(mat,d)) for _l in _e.ml: _l.thickness *= -1
def helper_bi_mat_eqf(self, mat1_name, mat2_name, backings, tol, no_is_default=-1, ref_path='eqf'): if no_is_default == 1: mat1 = from_yaml(THIS_FILE_DIR + '/materials/{}.yaml'.format(mat1_name)) else: mat1 = from_yaml(THIS_FILE_DIR + '/materials/{}.yaml'.format(mat1_name), force=EqFluidJCA) if no_is_default == 2: mat2 = from_yaml(THIS_FILE_DIR + '/materials/{}.yaml'.format(mat2_name)) else: mat2 = from_yaml(THIS_FILE_DIR + '/materials/{}.yaml'.format(mat2_name), force=EqFluidJCA) prefix = '{}_{}'.format(mat1_name, mat2_name) for (backing_type, backing_func) in backings: for (d1, d2) in itertools.product(THICKNESSES, THICKNESSES): for a in ANGLES: filename = THIS_FILE_DIR + '/references/{}/{}_{}mm_{}mm_{}_{}deg.PW'.format( ref_path, prefix, int(d1 * 1e3), int(d2 * 1e3), backing_type, a) if not os.path.exists(filename): continue reference = np.loadtxt(filename) for l in reference: S = Solver() S.layers = [Layer(mat1, d1), Layer(mat2, d2)] S.backing = backing_func result = S.solve(l[0], a) asserts.assertAlmostEqual( result['R'][0], l[2] + 1j * l[3], tol, '(reflection) {} {} : f={}Hz angle={}deg d1={:2.3f}m d2={:2.3f}m' .format(mat1_name, mat2_name, l[0], a, d1, d2)) if backing_func == backing.transmission: asserts.assertAlmostEqual( result['T'][0], l[5] + 1j * l[6], tol, '(transmission) {} {} : f={}Hz angle={}deg d1={:2.3f}m d2={:2.3f}m' .format(mat1_name, mat2_name, l[0], a, d1, d2))
def helper_numerical_tests_eqf(self, materials, backings, tol): for mat_name in materials: mat = from_yaml(THIS_FILE_DIR + '/materials/{}.yaml'.format(mat_name), force=EqFluidJCA) for (backing_type, backing_func) in backings: for d in THICKNESSES: for a in ANGLES: reference = np.loadtxt( THIS_FILE_DIR + '/references/eqf/{}_{}mm_{}_{}deg.PW'.format( mat_name, int(d * 1e3), backing_type, a)) for l in reference: S = Solver() S.layers = [Layer(mat, d)] S.backing = backing_func result = S.solve(l[0], a) asserts.assertAlmostEqual( result['R'][0], l[2] + 1j * l[3], tol, '(reflection) {}: f={}Hz angle={}deg d={:2.3f}m' .format(mat_name, l[0], a, d)) if backing_func == backing.transmission: asserts.assertAlmostEqual( result['T'][0], l[5] + 1j * l[6], tol, '(transmission) {}: f={}Hz angle={}deg d={:2.3f}m' .format(mat_name, l[0], a, d))
def result_pymls(**kwargs): name_project = kwargs.get("name_project", "unnamed_project") ml = kwargs.get("ml", False) termination = kwargs.get("termination", "rigid") theta_d = kwargs.get("theta_d", 45) freq = kwargs.get("frequencies", np.array([440])) plot_RT = kwargs.get("plot_RT", False) solver = Solver() for _l in ml: mat = load_material(_l[0]) solver.layers.append(Layer(mat, _l[1])) R = [] if termination in ["rigid", "Rigid", "Rigid Wall", "Wall"]: solver.backing = backing.rigid T = False else: T = [] solver.backing = backing.transmission for _f in freq: _ = solver.solve(_f, theta_d) R.append(_["R"][0]) if termination == "transmission": T.append(_["T"][0]) if plot_RT: plt.figure(name_project + "/ Reflection coefficient") plt.plot(freq, [_.real for _ in R], 'r', label="Re(R) pymls") plt.plot(freq, [_.imag for _ in R], 'b', label="Im(R) pymls") plt.legend() if T is not False: plt.figure(name_project + "/ Transmission coefficient") plt.plot(freq, [_.real for _ in T], 'r', label="Re(T) pymls") plt.plot(freq, [_.imag for _ in T], 'b', label="Im(T) pymls") plt.legend() return freq, R, T
def helper_bi_mat_eqf(self, mat1_name, mat2_name, backings, tol, no_is_default=-1, ref_path='eqf'): if no_is_default == 1: mat1 = from_yaml(THIS_FILE_DIR + f'/materials/{mat1_name}.yaml') else: mat1 = from_yaml(THIS_FILE_DIR + f'/materials/{mat1_name}.yaml', force=EqFluidJCA) if no_is_default == 2: mat2 = from_yaml(THIS_FILE_DIR + f'/materials/{mat2_name}.yaml') else: mat2 = from_yaml(THIS_FILE_DIR + f'/materials/{mat2_name}.yaml', force=EqFluidJCA) prefix = f'{mat1_name}_{mat2_name}' for (backing_type, backing_func) in backings: for (d1, d2) in itertools.product(THICKNESSES, THICKNESSES): for a in ANGLES: filename = THIS_FILE_DIR + f'/references/{ref_path}/{prefix}_{int(d1*1e3)}mm_{int(d2*1e3)}mm_{backing_type}_{a}deg.PW' if not os.path.exists(filename): continue reference = np.loadtxt(filename) for l in reference: S = Solver() S.layers = [Layer(mat1, d1), Layer(mat2, d2)] S.backing = backing_func result = S.solve(l[0], a) self.assertAlmostEqual( result['R'][0], l[2] + 1j * l[3], tol, f'(reflection) {mat1_name} {mat2_name} : f={l[0]}Hz angle={a}deg d1={d1:2.3f}m d2={d2:2.3f}m' ) if backing_func == backing.transmission: self.assertAlmostEqual( result['T'][0], l[5] + 1j * l[6], tol, f'(transmission) {mat1_name} {mat2_name} : f={l[0]}Hz angle={a}deg d1={d1:2.3f}m d2={d2:2.3f}m' )
def test_air_analytical(self): for d in THICKNESSES: S = Solver() S.layers = [Layer(Air, d)] S.backing = backing.rigid result = S.solve(FREQS, 0) for i_f, f in enumerate(result['f']): omega = 2 * np.pi * f k_air = omega * np.sqrt(Air.rho / Air.K) Z_s = -1j * Air.Z / np.tan(k_air * d) R_analytical = (Z_s - Air.Z) / (Z_s + Air.Z) asserts.assertAlmostEqual( R_analytical, result['R'][i_f], NB_PLACES, '(reflection) f={}Hz, d={}, theta=0'.format(f, d))
def helper_numerical_tests(self, materials, backings, tol): for mat_name in materials: mat = from_yaml(THIS_FILE_DIR + '/materials/{}.yaml'.format(mat_name)) for (backing_type, backing_func) in backings: for d in THICKNESSES: reference = np.loadtxt( THIS_FILE_DIR + '/references/{}_{}mm_{}.csv'.format( mat_name, int(d * 1e3), backing_type)) for l in reference: S = Solver() S.layers = [Layer(mat, d)] S.backing = backing_func result = S.solve(l[0], l[1]) asserts.assertAlmostEqual(result['R'][0], l[2] + 1j * l[3], tol) if backing_func == backing.transmission: asserts.assertAlmostEqual(result['T'][0], l[4] + 1j * l[5], tol)
def __init__(self, **kwargs): PwCalculus.__init__(self, **kwargs) ml = kwargs.get("ml") termination = kwargs.get("termination") self.layers = [] for _l in ml: if _l[0] == "Air": mat = Air else: mat = from_yaml(_l[0] + ".yaml") d = _l[1] self.layers.append(Layer(mat, d)) if termination in ["trans", "transmission", "Transmission"]: self.backing = "Transmission" else: self.backing = backing.rigid self.kx, self.ky, self.k = None, None, None self.shift_plot = kwargs.get("shift_pw", 0.) self.plot = kwargs.get("plot_results", [False] * 6) self.result = {} self.outfiles_directory = False initialisation_out_files_plain(self)
# Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # import sys sys.path.append('../') from pymls import from_yaml, Solver, Layer, backing freq = 20 d = 200e-3 theta = 30 foam = from_yaml('materials/foam2.yaml') S = Solver() S.layers = [Layer(foam, d)] S.backing = backing.rigid result = S.solve(freq, theta) pymls = result['R'][0] print("pymls: R = ", pymls)
# furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # import sys sys.path.append('../') from pymls import from_yaml, Solver, Layer, backing freq = 20 d_pem = 200e-3 d_wood = 2e-2 theta = 30 foam = from_yaml('materials/foam2.yaml') wood = from_yaml('materials/wood.yaml') S = Solver() S.layers = [ Layer(foam, d_pem), Layer(wood, d_wood), ] S.backing = backing.rigid result = S.solve(freq, theta) pymls = result['R'][0] print("pymls: R = ", pymls)
def solve(self, f, theta_d): out = dict() Layers = self.layers.copy() Layers.insert(0, Layer(Air, 0.1)) if self.backing == "transmission": Layers.append(Layer(Air, 0.2)) n, interfaces, dofs = initialise_PW_solver(Layers, self.backing) M = np.zeros((n - 1, n), dtype=complex) i_eq = 0 # Loop on the layers for i_inter, _inter in enumerate(interfaces): if _inter[0] == "fluid": if _inter[1] == "fluid": i_eq = self.interface_fluid_fluid(i_eq, i_inter, Layers, dofs, M) if _inter[1] == "pem": i_eq = self.interface_fluid_pem(i_eq, i_inter, Layers, dofs, M) if _inter[1] == "elastic": i_eq = self.interface_fluid_elastic( i_eq, i_inter, Layers, dofs, M) elif _inter[0] == "pem": if _inter[1] == "fluid": i_eq = self.interface_pem_fluid(i_eq, i_inter, Layers, dofs, M) if _inter[1] == "pem": i_eq = self.interface_pem_pem(i_eq, i_inter, Layers, dofs, M) if _inter[1] == "elastic": i_eq = self.interface_pem_elastic(i_eq, i_inter, Layers, dofs, M) elif _inter[0] == "elastic": if _inter[1] == "fluid": i_eq = self.interface_elastic_fluid( i_eq, i_inter, Layers, dofs, M) if _inter[1] == "pem": i_eq = self.interface_elastic_pem(i_eq, i_inter, Layers, dofs, M) if _inter[1] == "elastic": i_eq = self.interface_elastic_elastic( i_eq, i_inter, Layers, dofs, M) if self.backing == backing.rigid: if Layers[-1].medium.MODEL == "fluid": i_eq = self.interface_fluid_rigid(M, i_eq, Layers[-1], dofs[-1]) elif Layers[-1].medium.MODEL == "pem": i_eq = self.interface_pem_rigid(M, i_eq, Layers[-1], dofs[-1]) elif Layers[-1].medium.MODEL == "elastic": i_eq = self.interface_elastic_rigid(M, i_eq, Layers[-1], dofs[-1]) elif self.backing == "transmission": i_eq = self.semi_infinite_medium(M, i_eq, Layers[-1], dofs[-1]) F = -M[:, 0] * np.exp( 1j * self.ky * Layers[0].thickness ) # - is for transposition, exponential term is for the phase shift M = np.delete(M, 0, axis=1) X = LA.solve(M, F) R_pyPLANES_PW = X[0] if self.backing == "transmission": T_pyPLANES_PW = X[-2] else: T_pyPLANES_PW = 0. X = np.delete(X, 0) del (dofs[0]) for i, _ld in enumerate(dofs): dofs[i] -= 2 if self.plot: self.plot_sol_PW(X, dofs) out["R"] = R_pyPLANES_PW out["T"] = T_pyPLANES_PW return out
import sys sys.path.append('../') import numpy as np from pymls import Solver, Layer, backing from pymls.media import Air freq = 1000 omega = 2 * np.pi * freq d = 0.05 theta = 0 # Analytical solution k_air = omega * np.sqrt(Air.rho / Air.K) Z_s = -1j * Air.Z / np.tan(k_air * d) R_analytical = (Z_s - Air.Z) / (Z_s + Air.Z) # Solution using pymls S = Solver() S.layers = [Layer(Air, d)] S.backing = backing.rigid result = S.solve(freq, theta) pymls = result['R'][0] print('Analytical : R = ', R_analytical) print('pymls : R = ', pymls)
# Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # import sys sys.path.append('../') from pymls import from_yaml, Solver, Layer, backing freq = 10 d = 0.5e-3 theta = 10 glass = from_yaml('materials/glass.yaml') S = Solver() S.layers = [Layer(glass, d)] S.backing = backing.transmission result = S.solve(freq, theta) pymls = result['R'][0] print("pymls: R = ", pymls)
def check_model(self): ''' This function checks if the model is correct and adapt it if not ''' unfinished = True while unfinished: unfinished = False for _e in self.entities: if _e.dim == 1: # 1D entities if len(_e.neighbouring_surfaces) > 1: if isinstance(_e, (PwFem, RigidWallFem, PeriodicityFem)): raise ValueError( "Error in check model: 1D entity is linked to more than one surface" ) if isinstance(_e, FluidStructureFem): if len(_e.neighbouring_surfaces) != 2: raise NameError( "For FluidStructureFem, the number of neighbours should be 2" ) else: if isinstance(_e.neighbouring_surfaces[0], FluidFem) and isinstance( _e.neighbouring_surfaces[1], ElasticFem): _e.fluid_neighbour, _e.struc_neighbour = _e.neighbouring_surfaces[ 0], _e.neighbouring_surfaces[1] elif isinstance(_e.neighbouring_surfaces[0], ElasticFem) and isinstance( _e.neighbouring_surfaces[1], FluidFem): _e.fluid_neighbour, _e.struc_neighbour = _e.neighbouring_surfaces[ 1], _e.neighbouring_surfaces[0] else: raise NameError( "FluidStructureFem doest not relate a fluid and elastic struture" ) for _elem in _e.elements: vert = [ _elem.vertices[0].tag, _elem.vertices[1].tag ] # Vertices of the FSI element # Determination of the neighbouring element in neighbouring_surfaces[0] _iter = iter(_e.fluid_neighbour.elements) while True: _el = next(_iter) vert_2D = [ _el.vertices[0].tag, _el.vertices[1].tag, _el.vertices[2].tag ] _ = len(set(vert).intersection( vert_2D)) # Number of common vertices if _ == 2: # Case of two common vertices _elem.normal_fluid = normal_to_element( _elem, _el) _elem.normal_struc = -_elem.normal_fluid break if _e.dim == 2: if isinstance(_e, PemFem): # _e.formulation98 = True _e.formulation98 = False # Check that the number of interfaces go by pairs list_interfaces = [ _ent for _ent in self.model_entities if isinstance(_ent, InterfaceFem) ] name_interfaces = [_ent.ml for _ent in list_interfaces] n_interface = len(list_interfaces) if n_interface % 2 == 1: raise ValueError("Error in check model: Number of interfaces is odd") else: while n_interface != 0: _int_minus = list_interfaces[0] _index = name_interfaces[1:].index(_int_minus.ml) + 1 _int_plus = list_interfaces[_index] _int_minus.neighbour = _int_plus _int_plus.neighbour = _int_minus del list_interfaces[_index] del list_interfaces[0] del name_interfaces[_index] del name_interfaces[0] if _int_minus.side == "+": if _int_plus.side == "-": _int_minus, _int_plus = _int_plus, _int_minus else: raise ValueError( "_int_minus.side = + and _int_plus.side != + ") elif _int_minus.side == "-": if _int_plus.side != "+": raise ValueError( "_int_minus.side = - and _int_plus.side != + ") else: raise ValueError("_int_minus.side ins neither + or - ") for _el in _int_minus.elements: print(_el) n_interface -= 2 for _e in self.model_entities: if isinstance(_e, PwFem): for s in _e.neighbouring_surfaces: if isinstance(s, (Air, FluidFem)): _e.nb_R = 1 _e.typ = "fluid" elif (isinstance(s, ElasticFem)): _e.nb_R = 2 _e.typ = "elastic" elif isinstance(s, PemFem): if s.formulation98: _e.nb_R = 3 _e.typ = "Biot98" else: _e.nb_R = 3 _e.typ = "Biot01" if isinstance(_e, IncidentPwFem): if self.incident_ml: _e.ml = [] for _l in self.incident_ml: mat = from_yaml(_l[0] + ".yaml") d = _l[1] _e.ml.append(Layer(mat, d)) if isinstance(_e, TransmissionPwFem): if self.transmission_ml: _e.ml = [] for _l in self.transmission_ml: mat = from_yaml(_l[0] + ".yaml") d = -_l[1] # Thickness of transmission layers is set negative _e.ml.append(Layer(mat, d)) for _l in _e.ml: _l.thickness *= -1
# furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # import sys sys.path.append('../') from pymls import from_yaml, Solver, Layer, backing freq = 20 theta = 30 foam = from_yaml('materials/foam2.yaml') d_foam = 200e-3 wood = from_yaml('materials/wood.yaml') d_wood = 2e-2 S = Solver() S.layers = [ Layer(wood, d_wood), Layer(foam, d_foam), ] S.backing = backing.rigid result = S.solve(freq, theta) pymls = result['R'][0] print("pymls: R = ", pymls)