Skip to content

Calculation backend

src.reverberation_calc

DIN_18041_limits

Defines a "DIN_18041_limits" object that calculates the limits for reverberation time according to DIN 18041 based on room type, volume, and height.

Attributes:

Name Type Description
room room

The room for which the limits are calculated, which is an instance of the room class.

volume int or float

The volume of the room in m\(^3\).

c int or float

The speed of sound in air in m/s, calculated based on the room's temperature and pressure.

type str

The type of room according to DIN 18041, specified as a string (e.g., "A1", "B2", or 'no requirements').

T_soll int or float

The target reverberation time in s according to DIN 18041, calculated based on the room type, volume and height.

T_upper_limit array

The upper limit for reverberation time in s according to DIN 18041, calculated based on the target reverberation time.

T_lower_limit array

The lower limit for reverberation time in s according to DIN 18041, calculated based on the target reverberation time.

Source code in src/reverberation_calc.py
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
class DIN_18041_limits:
    """
    Defines a "DIN_18041_limits" object that calculates the limits for reverberation time according to DIN 18041 based on room type, volume, and height.

    Attributes
    ----------
    room : room
        The room for which the limits are calculated, which is an instance of the room class.
    volume : int or float
        The volume of the room in m$^3$.
    c : int or float
        The speed of sound in air in m/s, calculated based on the room's temperature and pressure.
    type : str
        The type of room according to DIN 18041, specified as a string (e.g., "A1", "B2", or 'no requirements'). 
    T_soll : int or float
        The target reverberation time in s according to DIN 18041, calculated based on the room type, volume and height.
    T_upper_limit : np.array
        The upper limit for reverberation time in s according to DIN 18041, calculated based on the target reverberation time.
    T_lower_limit : np.array
        The lower limit for reverberation time in s according to DIN 18041, calculated based on the target reverberation time.

    """

    def __init__(self, calc_room, type):
        """
        Initializes a DIN_18041_limits object with a specified room and room type.

        Parameters
        ----------
        calc_room : room
            The room for which the limits are calculated, which is an instance of the room class.
        type : str
            The type of room according to DIN 18041, specified as a string (e.g., "A1", "B2", or 'no requirements'). 

        Raises
        -------
        TypeError
            If the room is not an instance of the room class or if the type is not a string.
        ValueError
            If the type is not a valid room type according to DIN 18041.
        """
        if not isinstance(calc_room, room):
            raise TypeError("Room must be an instance of the room class.")
        if not isinstance(type, str):
            raise TypeError("Type must be a string.")
        if len(type) != 2 or type[0] not in ["A", "B"] or type[1] not in ["1", "2", "3", "4", "5"]:
            if type != "no requirements":
                raise ValueError("Type must be a valid room type according to DIN 18041 (e.g., 'A1', 'B2') or 'no requirements'.")
        self.calc_room = calc_room
        self.volume = self.calc_room.volume
        self.c = self.calc_room.c
        self.type = str(type)
        self.get_limits()


    def get_limits(self):
        """
        Calculates the limits for reverberation time in s according to DIN 18041 based on room type, volume, and height.

        Returns
        -------
        list of float
            A list containing the upper and lower limits for reverberation time in s according to DIN 18041.
        """

        # Get the limits Tsoll for reverberation time according to DIN 18041 based on room type, volume and height
        self.T_soll = None
        match self.type[0]:
            case "A":
                T_upper_limit_A = np.array((1.7,1.45,1.2,1.2,1.2,1.2,1.2,1.2))
                T_lower_limit_A = np.array((0.5,0.65,0.8,0.8,0.8,0.8,0.65,0.5))

                match self.type[1]:
                    case "1":
                        if self.volume < 30:
                            warnings.warn("According to DIN 18041, the room volume should be at least 30 m³ for type A1.")
                        if self.volume > 1000:
                            warnings.warn("According to DIN 18041, the room volume should be smaller than 1000 m³ for type A1.")

                        self.T_soll = 0.45*np.log10(self.volume) + 0.07

                    case "2":
                        if self.volume < 50:
                            warnings.warn("According to DIN 18041, the room volume should be at least 50 m³ for type A2.")
                        if self.volume > 5000:
                            warnings.warn("According to DIN 18041, the room volume should be smaller than 5000 m³ for type A2.")

                        self.T_soll = 0.37*np.log10(self.volume) + 0.14

                    case "3":
                        if self.volume < 30:
                            warnings.warn("According to DIN 18041, the room volume should be at least 30 m³ for type A3.")
                        if self.volume > 5000:
                            warnings.warn("According to DIN 18041, the room volume should be smaller than 5000 m³ for type A3.")

                        self.T_soll = 0.32*np.log10(self.volume) + 0.17

                    case "4":
                        if self.volume < 30:
                            warnings.warn("According to DIN 18041, the room volume should be at least 30 m³ for type A4.")
                        if self.volume > 500:
                            warnings.warn("According to DIN 18041, the room volume should be smaller than 500 m³ for type A4.")

                        self.T_soll = 0.26*np.log10(self.volume) + 0.14

                    case "5":
                        if self.volume < 200:
                            warnings.warn("According to DIN 18041, the room volume should be at least 200 m³ for type A5.")
                        if self.volume > 9999:
                            self.T_soll = 2

                        self.T_soll = 0.75*np.log10(self.volume) + 1

                self.T_upper_limit = T_upper_limit_A*self.T_soll
                self.T_lower_limit = T_lower_limit_A*self.T_soll

            case "B":
                T_upper_limit_B = np.array((0,0,1,1,1,1,0,0))
                T_lower_limit_B = np.array((0,0,0,0,0,0,0,0))

                match self.type[1]:
                    case "1":
                        warnings.warn("According to DIN 18041, there are no requirements for type B1.")
                        self.T_soll = 0
                    case "2":
                        if self.calc_room.height <= 2.5:
                            A_V = 0.15
                        if self.calc_room.height > 2.5:
                            A_V = 1/(4.8 + 4.69 * np.log10(self.calc_room.height))

                    case "3":
                        if self.calc_room.height <= 2.5:
                            A_V = 0.20
                        if self.calc_room.height > 2.5:
                            A_V = 1/(3.13 + 4.69 * np.log10(self.calc_room.height))

                    case "4":
                        if self.calc_room.height <= 2.5:
                            A_V = 0.25
                        if self.calc_room.height > 2.5:
                            A_V = 1/(2.13 + 4.69 * np.log10(self.calc_room.height))

                    case "5":
                        if self.calc_room.height <= 2.5:
                            A_V = 0.30
                        if self.calc_room.height > 2.5:
                            A_V = 1/(1.47 + 4.69 * np.log10(self.calc_room.height))

                if self.T_soll == 0:
                    self.T_soll = 0
                else:
                    self.T_soll = (55.3/self.c) * (self.volume / (A_V * self.volume))

                self.T_upper_limit = T_upper_limit_B * self.T_soll
                self.T_lower_limit = T_lower_limit_B

            case _:
                raise ValueError("Invalid room type specified.")


        match self.type:
            case "no requirements":
                self.T_soll = np.nan
                self.T_upper_limit = np.array([np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan])
                self.T_lower_limit = np.array([np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan])

        return (self.T_upper_limit, self.T_lower_limit)

__init__(calc_room, type)

Initializes a DIN_18041_limits object with a specified room and room type.

Parameters:

Name Type Description Default
calc_room room

The room for which the limits are calculated, which is an instance of the room class.

required
type str

The type of room according to DIN 18041, specified as a string (e.g., "A1", "B2", or 'no requirements').

required

Raises:

Type Description
TypeError

If the room is not an instance of the room class or if the type is not a string.

ValueError

If the type is not a valid room type according to DIN 18041.

Source code in src/reverberation_calc.py
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
def __init__(self, calc_room, type):
    """
    Initializes a DIN_18041_limits object with a specified room and room type.

    Parameters
    ----------
    calc_room : room
        The room for which the limits are calculated, which is an instance of the room class.
    type : str
        The type of room according to DIN 18041, specified as a string (e.g., "A1", "B2", or 'no requirements'). 

    Raises
    -------
    TypeError
        If the room is not an instance of the room class or if the type is not a string.
    ValueError
        If the type is not a valid room type according to DIN 18041.
    """
    if not isinstance(calc_room, room):
        raise TypeError("Room must be an instance of the room class.")
    if not isinstance(type, str):
        raise TypeError("Type must be a string.")
    if len(type) != 2 or type[0] not in ["A", "B"] or type[1] not in ["1", "2", "3", "4", "5"]:
        if type != "no requirements":
            raise ValueError("Type must be a valid room type according to DIN 18041 (e.g., 'A1', 'B2') or 'no requirements'.")
    self.calc_room = calc_room
    self.volume = self.calc_room.volume
    self.c = self.calc_room.c
    self.type = str(type)
    self.get_limits()

get_limits()

Calculates the limits for reverberation time in s according to DIN 18041 based on room type, volume, and height.

Returns:

Type Description
list of float

A list containing the upper and lower limits for reverberation time in s according to DIN 18041.

Source code in src/reverberation_calc.py
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
def get_limits(self):
    """
    Calculates the limits for reverberation time in s according to DIN 18041 based on room type, volume, and height.

    Returns
    -------
    list of float
        A list containing the upper and lower limits for reverberation time in s according to DIN 18041.
    """

    # Get the limits Tsoll for reverberation time according to DIN 18041 based on room type, volume and height
    self.T_soll = None
    match self.type[0]:
        case "A":
            T_upper_limit_A = np.array((1.7,1.45,1.2,1.2,1.2,1.2,1.2,1.2))
            T_lower_limit_A = np.array((0.5,0.65,0.8,0.8,0.8,0.8,0.65,0.5))

            match self.type[1]:
                case "1":
                    if self.volume < 30:
                        warnings.warn("According to DIN 18041, the room volume should be at least 30 m³ for type A1.")
                    if self.volume > 1000:
                        warnings.warn("According to DIN 18041, the room volume should be smaller than 1000 m³ for type A1.")

                    self.T_soll = 0.45*np.log10(self.volume) + 0.07

                case "2":
                    if self.volume < 50:
                        warnings.warn("According to DIN 18041, the room volume should be at least 50 m³ for type A2.")
                    if self.volume > 5000:
                        warnings.warn("According to DIN 18041, the room volume should be smaller than 5000 m³ for type A2.")

                    self.T_soll = 0.37*np.log10(self.volume) + 0.14

                case "3":
                    if self.volume < 30:
                        warnings.warn("According to DIN 18041, the room volume should be at least 30 m³ for type A3.")
                    if self.volume > 5000:
                        warnings.warn("According to DIN 18041, the room volume should be smaller than 5000 m³ for type A3.")

                    self.T_soll = 0.32*np.log10(self.volume) + 0.17

                case "4":
                    if self.volume < 30:
                        warnings.warn("According to DIN 18041, the room volume should be at least 30 m³ for type A4.")
                    if self.volume > 500:
                        warnings.warn("According to DIN 18041, the room volume should be smaller than 500 m³ for type A4.")

                    self.T_soll = 0.26*np.log10(self.volume) + 0.14

                case "5":
                    if self.volume < 200:
                        warnings.warn("According to DIN 18041, the room volume should be at least 200 m³ for type A5.")
                    if self.volume > 9999:
                        self.T_soll = 2

                    self.T_soll = 0.75*np.log10(self.volume) + 1

            self.T_upper_limit = T_upper_limit_A*self.T_soll
            self.T_lower_limit = T_lower_limit_A*self.T_soll

        case "B":
            T_upper_limit_B = np.array((0,0,1,1,1,1,0,0))
            T_lower_limit_B = np.array((0,0,0,0,0,0,0,0))

            match self.type[1]:
                case "1":
                    warnings.warn("According to DIN 18041, there are no requirements for type B1.")
                    self.T_soll = 0
                case "2":
                    if self.calc_room.height <= 2.5:
                        A_V = 0.15
                    if self.calc_room.height > 2.5:
                        A_V = 1/(4.8 + 4.69 * np.log10(self.calc_room.height))

                case "3":
                    if self.calc_room.height <= 2.5:
                        A_V = 0.20
                    if self.calc_room.height > 2.5:
                        A_V = 1/(3.13 + 4.69 * np.log10(self.calc_room.height))

                case "4":
                    if self.calc_room.height <= 2.5:
                        A_V = 0.25
                    if self.calc_room.height > 2.5:
                        A_V = 1/(2.13 + 4.69 * np.log10(self.calc_room.height))

                case "5":
                    if self.calc_room.height <= 2.5:
                        A_V = 0.30
                    if self.calc_room.height > 2.5:
                        A_V = 1/(1.47 + 4.69 * np.log10(self.calc_room.height))

            if self.T_soll == 0:
                self.T_soll = 0
            else:
                self.T_soll = (55.3/self.c) * (self.volume / (A_V * self.volume))

            self.T_upper_limit = T_upper_limit_B * self.T_soll
            self.T_lower_limit = T_lower_limit_B

        case _:
            raise ValueError("Invalid room type specified.")


    match self.type:
        case "no requirements":
            self.T_soll = np.nan
            self.T_upper_limit = np.array([np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan])
            self.T_lower_limit = np.array([np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan])

    return (self.T_upper_limit, self.T_lower_limit)

air_damp

Defines an "air_damp" object that calculates the sound absorption coefficient \(m\) in 1/m of air based on frequency, temperature, humidity, and pressure according to DIN EN ISO 354, based on \(alpha\) from ISO 9613-1.

Parameters:

Name Type Description Default
frequency list

A list of frequencies in Hz for which the sound absorption coefficient is calculated.

required

Attributes:

Name Type Description
pressure (int or float, optional)

The pressure in kPa (default is 101.325 kPa).

ref_pressure (int or float, optional)

The reference pressure in kPa (default is 101.325 kPa).

rel_humidity (int or float, optional)

The relative humidity in % (default is 50 %).

abs_humidity (int or float, optional)

The absolute humidity as molar concentration of water vapour in air in % according to ISO 9613-1 Annex B.

temperature (int or float, optional)

The temperature in Celsius (default is 20°C).

ref_temperature (int or float, optional)

The reference temperature in Kelvin (default is 293.15 °K, which is 20 °C).

alpha list

A list of sound absorption coefficients in dB/m, calculated based on the frequency, temperature, humidity and pressure.

m list

A list of sound absorption coefficients in 1/m, calculated from alpha.

Source code in src/reverberation_calc.py
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
class air_damp:
    """
    Defines an "air_damp" object that calculates the sound absorption coefficient $m$ in 1/m of air based on frequency, temperature, humidity, and pressure according to DIN EN ISO 354, based on $alpha$ from ISO 9613-1.

    Parameters
    ----------
    frequency : list
        A list of frequencies in Hz for which the sound absorption coefficient is calculated.

    Attributes
    ----------
    pressure : int or float, optional
        The pressure in kPa (default is 101.325 kPa).
    ref_pressure : int or float, optional
        The reference pressure in kPa (default is 101.325 kPa).
    rel_humidity : int or float, optional
        The relative humidity in % (default is 50 %).
    abs_humidity : int or float, optional
        The absolute humidity as molar concentration of water vapour in air in % according to ISO 9613-1 Annex B.
    temperature : int or float, optional
        The temperature in Celsius (default is 20°C).
    ref_temperature : int or float, optional
        The reference temperature in Kelvin (default is 293.15 °K, which is 20 °C).
    alpha : list
        A list of sound absorption coefficients in dB/m, calculated based on the frequency, temperature, humidity and pressure.
    m : list
        A list of sound absorption coefficients in 1/m, calculated from alpha.
    """

    def __init__(self, frequency):
        """
        Initializes an air_damp object with a specified frequency and default values for pressure, relative humidity, temperature, and reference temperature.

        Parameters
        ----------
        frequency : list of int or float
            A list of frequencies in Hz for which the sound absorption coefficient is calculated.

        Raises
        -------
        TypeError
            If the frequency is not a list.
        ValueError
            If the frequency is not a list or if it contains non-numeric values.
        ValueError
            If the frequency list is empty.
        ValueError
            If the frequency list contains negative values.
        """
        if not isinstance(frequency, list):
            raise TypeError("Frequency must be a list.")
        if not all(isinstance(f, (int, float)) for f in frequency):
            raise ValueError("Frequency must be a list of numeric values.")
        if len(frequency) == 0:
            raise ValueError("Frequency list cannot be empty.")
        if any(f < 0 for f in frequency):
            raise ValueError("Frequency values must be non-negative.")

        self.frequency = frequency
        self.pressure = 101.325
        self.ref_pressure = 101.325
        self.rel_humidity = 50          # percentage
        self.temperature = 20           # Celsius
        self.ref_temperature = 293.15   # Kelvin
        self.calculate_abs_humidity()
        self.coefficient = self.calculate_coefficient()

    def set_frequency(self, frequency):
        """
        Sets the frequency in Hz for which the sound absorption coefficient is calculated.

        Parameters
        ----------
        frequency : list of int or float
            A list of frequencies in Hz.

        Raises
        -------
        TypeError
            If the frequency is not a list.
        ValueError
            If the frequency is not a list or if it contains non-numeric values.
        ValueError
            If the frequency list is empty.
        ValueError
            If the frequency list contains negative values.
        """
        if not isinstance(frequency, list):
            raise TypeError("Frequency must be a list.")
        if not all(isinstance(f, (int, float)) for f in frequency):
            raise ValueError("Frequency must be a list of numeric values.")
        if len(frequency) == 0:
            raise ValueError("Frequency list cannot be empty.")
        if any(f < 0 for f in frequency):
            raise ValueError("Frequency values must be non-negative.")

        self.frequency = frequency    

    def set_pressure(self, pressure):
        """
        Sets the pressure in kPa for the sound absorption coefficient calculation.

        Parameters
        ----------
        pressure : int or float
            The pressure in kPa.

        Raises
        -------
        TypeError
            If the pressure is not a numeric value.
        ValueError
            If the pressure is not a positive numeric value.
        """
        if not isinstance(pressure, (int, float)):
            raise TypeError("Pressure must be an integer or float.")
        if pressure <= 0:
            raise ValueError("Pressure must be a positive value.")
        self.pressure = pressure

    def set_temperature(self, temperature):
        """
        Sets the temperature in Celsius for the sound absorption coefficient calculation.

        Parameters
        ----------
        temperature : int or float
            The temperature in °C.

        Raises
        -------
        TypeError
            If the temperature is not a numeric value.
        ValueError
            If the temperature is not above absolute zero (-273.15 °C).
        """
        if not isinstance(temperature, (int, float)):
            raise TypeError("Temperature must be an integer or float.")
        if temperature < -273.15:
            raise ValueError("Temperature must be above absolute zero (-273.15 °C).")
        self.temperature = temperature + 273.15

    def get_temperature(self):
        """
        Returns the temperature in °C.

        Returns
        -------
        float
            The temperature in °C.
        """
        return self.temperature - 273.15

    def set_rel_humidity(self, rel_humidity):
        """
        Sets the relative humidity in % for the sound absorption coefficient calculation.

        Parameters
        ----------
        rel_humidity : int or float
            The relative humidity in %.

        Raises
        -------
        TypeError
            If the relative humidity is not an integer or float.
        ValueError
            If the relative humidity is not in the range of 0 % - 100 %.
        """
        if not isinstance(rel_humidity, (int, float)):
            raise TypeError("Relative humidity must be an integer or float.")  
        if rel_humidity < 0 or rel_humidity > 100:
            raise ValueError("Relative humidity must be between 0 and 100 %.")
        self.rel_humidity = rel_humidity
        self.calculate_abs_humidity()

    def calculate_abs_humidity(self):
        """
        Calculates the absolute humidity based on the relative humidity, pressure, and temperature.
        The absolute humidity is calculated as the molar concentration of water vapor in air according to ISO 9613-1 Annex B.
        """
        self.abs_humidity = (self.rel_humidity * 10**(-6.8346 * ((273.16 / (self.temperature))**1.261) + 4.6151)) / (self.pressure / 101.325)

    def set_ref_pressure(self, ref_pressure):
        """
        Sets the reference pressure in kPa for the sound absorption coefficient calculation.

        Parameters
        ----------
        ref_pressure : int or float
            The reference pressure in kPa.

        Raises
        -------
        TypeError
            If the reference pressure is not a numeric value.
        ValueError
            If the reference pressure is not a positive numeric value.
        """
        if not isinstance(ref_pressure, (int, float)):
            raise TypeError("Reference pressure must be an integer or float.")
        if ref_pressure <= 0:
            raise ValueError("Reference pressure must be a positive value.")
        self.ref_pressure = ref_pressure

    def calculate_coefficient(self):
        """
        Calculates the sound absorption coefficient $m$ in 1/m and $alpha$ in dB/m of air based on frequency, temperature, humidity and pressure according to DIN EN ISO 354, based on $alpha$ from ISO 9613-1.

        Returns
        -------
        list
            The sound absorption coefficient $m$ in 1/m.

        Raises
        -------
        ValueError
            If temperature, relative humidity or pressure is not set before calculating the coefficient.
        """
        if not hasattr(self, 'temperature'):
            raise ValueError("Temperature must be set before calculating coefficient.") 
        if not hasattr(self, 'rel_humidity'):
            raise ValueError("Relative humidity must be set before calculating coefficient.")
        if not hasattr(self, 'pressure'):
            raise ValueError("Pressure must be set before calculating coefficient.")
        else:
            alpha = np.zeros(len(self.frequency))
            f_rO = (self.pressure/self.ref_pressure)*(24.0+4.04*(10.0**4.0)*self.abs_humidity*((0.02+self.abs_humidity)/(0.391+self.abs_humidity)))
            f_rN = (self.pressure/self.ref_pressure)*((self.temperature/self.ref_temperature)**(-(1.0/2.0)))*(9.0+280.0*self.abs_humidity*np.exp(-4.170*(((self.temperature/self.ref_temperature)**(-(1.0/3.0)))-1.0)))
            for i, f in enumerate(self.frequency):
                alpha[i] = 8.686*(f**2.0)*((1.84*(10.0**(-11.0))*((self.pressure/self.ref_pressure)**(-1.0))*((self.temperature/self.ref_temperature)**(1.0/2.0)))+
                                 ((self.temperature/self.ref_temperature)**(-5.0/2.0))*
                                 (0.01275*np.exp(-2239.1/self.temperature)*((f_rO+((f**2.0)/f_rO))**(-1.0))+
                                  0.1068*np.exp(-3352.0/self.temperature)*((f_rN+((f**2.0)/f_rN))**(-1.0))))# dB/m

            m = (alpha*1000)/4350
            self.alpha = alpha
            self.m = m
            return m

__init__(frequency)

Initializes an air_damp object with a specified frequency and default values for pressure, relative humidity, temperature, and reference temperature.

Parameters:

Name Type Description Default
frequency list of int or float

A list of frequencies in Hz for which the sound absorption coefficient is calculated.

required

Raises:

Type Description
TypeError

If the frequency is not a list.

ValueError

If the frequency is not a list or if it contains non-numeric values.

ValueError

If the frequency list is empty.

ValueError

If the frequency list contains negative values.

Source code in src/reverberation_calc.py
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
def __init__(self, frequency):
    """
    Initializes an air_damp object with a specified frequency and default values for pressure, relative humidity, temperature, and reference temperature.

    Parameters
    ----------
    frequency : list of int or float
        A list of frequencies in Hz for which the sound absorption coefficient is calculated.

    Raises
    -------
    TypeError
        If the frequency is not a list.
    ValueError
        If the frequency is not a list or if it contains non-numeric values.
    ValueError
        If the frequency list is empty.
    ValueError
        If the frequency list contains negative values.
    """
    if not isinstance(frequency, list):
        raise TypeError("Frequency must be a list.")
    if not all(isinstance(f, (int, float)) for f in frequency):
        raise ValueError("Frequency must be a list of numeric values.")
    if len(frequency) == 0:
        raise ValueError("Frequency list cannot be empty.")
    if any(f < 0 for f in frequency):
        raise ValueError("Frequency values must be non-negative.")

    self.frequency = frequency
    self.pressure = 101.325
    self.ref_pressure = 101.325
    self.rel_humidity = 50          # percentage
    self.temperature = 20           # Celsius
    self.ref_temperature = 293.15   # Kelvin
    self.calculate_abs_humidity()
    self.coefficient = self.calculate_coefficient()

calculate_abs_humidity()

Calculates the absolute humidity based on the relative humidity, pressure, and temperature. The absolute humidity is calculated as the molar concentration of water vapor in air according to ISO 9613-1 Annex B.

Source code in src/reverberation_calc.py
412
413
414
415
416
417
def calculate_abs_humidity(self):
    """
    Calculates the absolute humidity based on the relative humidity, pressure, and temperature.
    The absolute humidity is calculated as the molar concentration of water vapor in air according to ISO 9613-1 Annex B.
    """
    self.abs_humidity = (self.rel_humidity * 10**(-6.8346 * ((273.16 / (self.temperature))**1.261) + 4.6151)) / (self.pressure / 101.325)

calculate_coefficient()

Calculates the sound absorption coefficient \(m\) in 1/m and \(alpha\) in dB/m of air based on frequency, temperature, humidity and pressure according to DIN EN ISO 354, based on \(alpha\) from ISO 9613-1.

Returns:

Type Description
list

The sound absorption coefficient \(m\) in 1/m.

Raises:

Type Description
ValueError

If temperature, relative humidity or pressure is not set before calculating the coefficient.

Source code in src/reverberation_calc.py
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
def calculate_coefficient(self):
    """
    Calculates the sound absorption coefficient $m$ in 1/m and $alpha$ in dB/m of air based on frequency, temperature, humidity and pressure according to DIN EN ISO 354, based on $alpha$ from ISO 9613-1.

    Returns
    -------
    list
        The sound absorption coefficient $m$ in 1/m.

    Raises
    -------
    ValueError
        If temperature, relative humidity or pressure is not set before calculating the coefficient.
    """
    if not hasattr(self, 'temperature'):
        raise ValueError("Temperature must be set before calculating coefficient.") 
    if not hasattr(self, 'rel_humidity'):
        raise ValueError("Relative humidity must be set before calculating coefficient.")
    if not hasattr(self, 'pressure'):
        raise ValueError("Pressure must be set before calculating coefficient.")
    else:
        alpha = np.zeros(len(self.frequency))
        f_rO = (self.pressure/self.ref_pressure)*(24.0+4.04*(10.0**4.0)*self.abs_humidity*((0.02+self.abs_humidity)/(0.391+self.abs_humidity)))
        f_rN = (self.pressure/self.ref_pressure)*((self.temperature/self.ref_temperature)**(-(1.0/2.0)))*(9.0+280.0*self.abs_humidity*np.exp(-4.170*(((self.temperature/self.ref_temperature)**(-(1.0/3.0)))-1.0)))
        for i, f in enumerate(self.frequency):
            alpha[i] = 8.686*(f**2.0)*((1.84*(10.0**(-11.0))*((self.pressure/self.ref_pressure)**(-1.0))*((self.temperature/self.ref_temperature)**(1.0/2.0)))+
                             ((self.temperature/self.ref_temperature)**(-5.0/2.0))*
                             (0.01275*np.exp(-2239.1/self.temperature)*((f_rO+((f**2.0)/f_rO))**(-1.0))+
                              0.1068*np.exp(-3352.0/self.temperature)*((f_rN+((f**2.0)/f_rN))**(-1.0))))# dB/m

        m = (alpha*1000)/4350
        self.alpha = alpha
        self.m = m
        return m

get_temperature()

Returns the temperature in °C.

Returns:

Type Description
float

The temperature in °C.

Source code in src/reverberation_calc.py
378
379
380
381
382
383
384
385
386
387
def get_temperature(self):
    """
    Returns the temperature in °C.

    Returns
    -------
    float
        The temperature in °C.
    """
    return self.temperature - 273.15

set_frequency(frequency)

Sets the frequency in Hz for which the sound absorption coefficient is calculated.

Parameters:

Name Type Description Default
frequency list of int or float

A list of frequencies in Hz.

required

Raises:

Type Description
TypeError

If the frequency is not a list.

ValueError

If the frequency is not a list or if it contains non-numeric values.

ValueError

If the frequency list is empty.

ValueError

If the frequency list contains negative values.

Source code in src/reverberation_calc.py
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
def set_frequency(self, frequency):
    """
    Sets the frequency in Hz for which the sound absorption coefficient is calculated.

    Parameters
    ----------
    frequency : list of int or float
        A list of frequencies in Hz.

    Raises
    -------
    TypeError
        If the frequency is not a list.
    ValueError
        If the frequency is not a list or if it contains non-numeric values.
    ValueError
        If the frequency list is empty.
    ValueError
        If the frequency list contains negative values.
    """
    if not isinstance(frequency, list):
        raise TypeError("Frequency must be a list.")
    if not all(isinstance(f, (int, float)) for f in frequency):
        raise ValueError("Frequency must be a list of numeric values.")
    if len(frequency) == 0:
        raise ValueError("Frequency list cannot be empty.")
    if any(f < 0 for f in frequency):
        raise ValueError("Frequency values must be non-negative.")

    self.frequency = frequency    

set_pressure(pressure)

Sets the pressure in kPa for the sound absorption coefficient calculation.

Parameters:

Name Type Description Default
pressure int or float

The pressure in kPa.

required

Raises:

Type Description
TypeError

If the pressure is not a numeric value.

ValueError

If the pressure is not a positive numeric value.

Source code in src/reverberation_calc.py
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
def set_pressure(self, pressure):
    """
    Sets the pressure in kPa for the sound absorption coefficient calculation.

    Parameters
    ----------
    pressure : int or float
        The pressure in kPa.

    Raises
    -------
    TypeError
        If the pressure is not a numeric value.
    ValueError
        If the pressure is not a positive numeric value.
    """
    if not isinstance(pressure, (int, float)):
        raise TypeError("Pressure must be an integer or float.")
    if pressure <= 0:
        raise ValueError("Pressure must be a positive value.")
    self.pressure = pressure

set_ref_pressure(ref_pressure)

Sets the reference pressure in kPa for the sound absorption coefficient calculation.

Parameters:

Name Type Description Default
ref_pressure int or float

The reference pressure in kPa.

required

Raises:

Type Description
TypeError

If the reference pressure is not a numeric value.

ValueError

If the reference pressure is not a positive numeric value.

Source code in src/reverberation_calc.py
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
def set_ref_pressure(self, ref_pressure):
    """
    Sets the reference pressure in kPa for the sound absorption coefficient calculation.

    Parameters
    ----------
    ref_pressure : int or float
        The reference pressure in kPa.

    Raises
    -------
    TypeError
        If the reference pressure is not a numeric value.
    ValueError
        If the reference pressure is not a positive numeric value.
    """
    if not isinstance(ref_pressure, (int, float)):
        raise TypeError("Reference pressure must be an integer or float.")
    if ref_pressure <= 0:
        raise ValueError("Reference pressure must be a positive value.")
    self.ref_pressure = ref_pressure

set_rel_humidity(rel_humidity)

Sets the relative humidity in % for the sound absorption coefficient calculation.

Parameters:

Name Type Description Default
rel_humidity int or float

The relative humidity in %.

required

Raises:

Type Description
TypeError

If the relative humidity is not an integer or float.

ValueError

If the relative humidity is not in the range of 0 % - 100 %.

Source code in src/reverberation_calc.py
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
def set_rel_humidity(self, rel_humidity):
    """
    Sets the relative humidity in % for the sound absorption coefficient calculation.

    Parameters
    ----------
    rel_humidity : int or float
        The relative humidity in %.

    Raises
    -------
    TypeError
        If the relative humidity is not an integer or float.
    ValueError
        If the relative humidity is not in the range of 0 % - 100 %.
    """
    if not isinstance(rel_humidity, (int, float)):
        raise TypeError("Relative humidity must be an integer or float.")  
    if rel_humidity < 0 or rel_humidity > 100:
        raise ValueError("Relative humidity must be between 0 and 100 %.")
    self.rel_humidity = rel_humidity
    self.calculate_abs_humidity()

set_temperature(temperature)

Sets the temperature in Celsius for the sound absorption coefficient calculation.

Parameters:

Name Type Description Default
temperature int or float

The temperature in °C.

required

Raises:

Type Description
TypeError

If the temperature is not a numeric value.

ValueError

If the temperature is not above absolute zero (-273.15 °C).

Source code in src/reverberation_calc.py
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
def set_temperature(self, temperature):
    """
    Sets the temperature in Celsius for the sound absorption coefficient calculation.

    Parameters
    ----------
    temperature : int or float
        The temperature in °C.

    Raises
    -------
    TypeError
        If the temperature is not a numeric value.
    ValueError
        If the temperature is not above absolute zero (-273.15 °C).
    """
    if not isinstance(temperature, (int, float)):
        raise TypeError("Temperature must be an integer or float.")
    if temperature < -273.15:
        raise ValueError("Temperature must be above absolute zero (-273.15 °C).")
    self.temperature = temperature + 273.15

material

Defines a "material" object with properties such as name, absorption coefficient (and price).

Attributes:

Name Type Description
name str

The name of the material.

absorption_coefficient list

The absorption coefficient of the material at different frequencies.

price (int or float, optional)

The price of the material as €/m\(^2\) (default is None).

Source code in src/reverberation_calc.py
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
class material:
    """
    Defines a "material" object with properties such as name, absorption coefficient (and price).

    Attributes
    ----------
    name : str
        The name of the material.
    absorption_coefficient : list
        The absorption coefficient of the material at different frequencies.
    price : int or float, optional
        The price of the material as €/m$^2$ (default is None).
    """

    def __init__(self, name, absorption_coefficient):
        """
        Initializes a material object with a specified name and absorption coefficient.

        Parameters
        ----------
        name : str
            The name of the material.
        absorption_coefficient : list of float
            A list of absorption coefficients at different frequencies.

        Raises
        -------
        TypeError
            If the name is not a string or if the absorption coefficient is not a list.
        ValueError
            If the absorption coefficient is not a list or if it contains non-numeric values.
        ValueError
            If the absorption coefficient list is empty.
        ValueError
            If the absorption coefficient list contains negative values.
        ValueError
            If the absorption coefficient list does not contain exactly 8 values for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.
        """
        if not isinstance(name, str):
            raise TypeError("Name must be a string.")
        if not isinstance(absorption_coefficient, list):
            raise TypeError("Absorption coefficient must be a list.")
        if not all(isinstance(ac, (int, float)) for ac in absorption_coefficient):
            raise ValueError("Absorption coefficient must be a list of numeric values.")
        if len(absorption_coefficient) == 0:
            raise ValueError("Absorption coefficient list cannot be empty.")
        if any(ac < 0 for ac in absorption_coefficient):
            raise ValueError("Absorption coefficient values must be non-negative.")
        if len(absorption_coefficient) != 8:
            raise ValueError("Absorption coefficient list must contain exactly 8 values for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.")
        self.name = name
        self.absorption_coefficient = np.array(absorption_coefficient)
        # self.frequency_weight = self.get_frequency_weight()
        self.price = None

    def set_absorption_coefficient(self, absorption_coefficient):
        """
        Sets the absorption coefficient of the material.

        Parameters
        ----------
        absorption_coefficient : list of float
            A list of absorption coefficients at different frequencies.

        Raises
        -------
        TypeError
            If the absorption coefficient is not a list.
        ValueError
            If the absorption coefficient is not a list or if it contains non-numeric values.
        ValueError
            If the absorption coefficient list is empty.
        ValueError
            If the absorption coefficient list contains negative values.
        ValueError
            If the absorption coefficient list does not contain exactly 8 values for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.
        """
        if not isinstance(absorption_coefficient, list):
            raise TypeError("Absorption coefficient must be a list.")
        if not all(isinstance(ac, (int, float)) for ac in absorption_coefficient):
            raise ValueError("Absorption coefficient must be a list of numeric values.")
        if len(absorption_coefficient) == 0:
            raise ValueError("Absorption coefficient list cannot be empty.")
        if any(ac < 0 for ac in absorption_coefficient):
            raise ValueError("Absorption coefficient values must be non-negative.")
        if len(absorption_coefficient) != 8:
            raise ValueError("Absorption coefficient list must contain exactly 8 values for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.")
        self.absorption_coefficient = absorption_coefficient

    def get_absorption_coefficient(self):
        """
        Returns the absorption coefficient of the material.

        Returns
        -------
        list
            The absorption coefficient of the material at different frequencies.
        """
        return self.absorption_coefficient

    def set_name(self, name):
        """
        Sets the name of the material.

        Parameters
        ----------
        name : str
            The name of the material.

        Raises
        -------
        TypeError
            If the name is not a string.
        """
        if not isinstance(name, str):
            raise TypeError("Name must be a string.")
        self.name = name

    def get_name(self):
        """
        Returns the name of the material.

        Returns
        -------
        str
            The name of the material if it has been set, otherwise returns None.
        """
        if not hasattr(self, 'name'):
            return None
        return self.name

    def set_price(self, price):
        """
        Sets the price of the material.

        Parameters
        ----------
        price : int or float
            The price of the material in €/m$^2$.

        Raises
        -------
        TypeError
            If the price is not a numeric value.
        ValueError
            If the price is not a positive numeric value.
        """
        if not isinstance(price, (int, float)):
            raise TypeError("Price must be an integer or float.")
        if price < 0:
            raise ValueError("Price must be a non-negative value.")
        self.price = price

    def get_price(self):
        """
        Returns the price of the material in €/m$^2$ if it has been set.

        Returns
        -------
        float or None
            The price of the material in €/m$^2$ if it has been set, otherwise returns None.
        """
        return self.price if hasattr(self, 'price') else None

__init__(name, absorption_coefficient)

Initializes a material object with a specified name and absorption coefficient.

Parameters:

Name Type Description Default
name str

The name of the material.

required
absorption_coefficient list of float

A list of absorption coefficients at different frequencies.

required

Raises:

Type Description
TypeError

If the name is not a string or if the absorption coefficient is not a list.

ValueError

If the absorption coefficient is not a list or if it contains non-numeric values.

ValueError

If the absorption coefficient list is empty.

ValueError

If the absorption coefficient list contains negative values.

ValueError

If the absorption coefficient list does not contain exactly 8 values for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.

Source code in src/reverberation_calc.py
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
def __init__(self, name, absorption_coefficient):
    """
    Initializes a material object with a specified name and absorption coefficient.

    Parameters
    ----------
    name : str
        The name of the material.
    absorption_coefficient : list of float
        A list of absorption coefficients at different frequencies.

    Raises
    -------
    TypeError
        If the name is not a string or if the absorption coefficient is not a list.
    ValueError
        If the absorption coefficient is not a list or if it contains non-numeric values.
    ValueError
        If the absorption coefficient list is empty.
    ValueError
        If the absorption coefficient list contains negative values.
    ValueError
        If the absorption coefficient list does not contain exactly 8 values for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.
    """
    if not isinstance(name, str):
        raise TypeError("Name must be a string.")
    if not isinstance(absorption_coefficient, list):
        raise TypeError("Absorption coefficient must be a list.")
    if not all(isinstance(ac, (int, float)) for ac in absorption_coefficient):
        raise ValueError("Absorption coefficient must be a list of numeric values.")
    if len(absorption_coefficient) == 0:
        raise ValueError("Absorption coefficient list cannot be empty.")
    if any(ac < 0 for ac in absorption_coefficient):
        raise ValueError("Absorption coefficient values must be non-negative.")
    if len(absorption_coefficient) != 8:
        raise ValueError("Absorption coefficient list must contain exactly 8 values for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.")
    self.name = name
    self.absorption_coefficient = np.array(absorption_coefficient)
    # self.frequency_weight = self.get_frequency_weight()
    self.price = None

get_absorption_coefficient()

Returns the absorption coefficient of the material.

Returns:

Type Description
list

The absorption coefficient of the material at different frequencies.

Source code in src/reverberation_calc.py
567
568
569
570
571
572
573
574
575
576
def get_absorption_coefficient(self):
    """
    Returns the absorption coefficient of the material.

    Returns
    -------
    list
        The absorption coefficient of the material at different frequencies.
    """
    return self.absorption_coefficient

get_name()

Returns the name of the material.

Returns:

Type Description
str

The name of the material if it has been set, otherwise returns None.

Source code in src/reverberation_calc.py
596
597
598
599
600
601
602
603
604
605
606
607
def get_name(self):
    """
    Returns the name of the material.

    Returns
    -------
    str
        The name of the material if it has been set, otherwise returns None.
    """
    if not hasattr(self, 'name'):
        return None
    return self.name

get_price()

Returns the price of the material in €/m\(^2\) if it has been set.

Returns:

Type Description
float or None

The price of the material in €/m\(^2\) if it has been set, otherwise returns None.

Source code in src/reverberation_calc.py
631
632
633
634
635
636
637
638
639
640
def get_price(self):
    """
    Returns the price of the material in €/m$^2$ if it has been set.

    Returns
    -------
    float or None
        The price of the material in €/m$^2$ if it has been set, otherwise returns None.
    """
    return self.price if hasattr(self, 'price') else None

set_absorption_coefficient(absorption_coefficient)

Sets the absorption coefficient of the material.

Parameters:

Name Type Description Default
absorption_coefficient list of float

A list of absorption coefficients at different frequencies.

required

Raises:

Type Description
TypeError

If the absorption coefficient is not a list.

ValueError

If the absorption coefficient is not a list or if it contains non-numeric values.

ValueError

If the absorption coefficient list is empty.

ValueError

If the absorption coefficient list contains negative values.

ValueError

If the absorption coefficient list does not contain exactly 8 values for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.

Source code in src/reverberation_calc.py
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
def set_absorption_coefficient(self, absorption_coefficient):
    """
    Sets the absorption coefficient of the material.

    Parameters
    ----------
    absorption_coefficient : list of float
        A list of absorption coefficients at different frequencies.

    Raises
    -------
    TypeError
        If the absorption coefficient is not a list.
    ValueError
        If the absorption coefficient is not a list or if it contains non-numeric values.
    ValueError
        If the absorption coefficient list is empty.
    ValueError
        If the absorption coefficient list contains negative values.
    ValueError
        If the absorption coefficient list does not contain exactly 8 values for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.
    """
    if not isinstance(absorption_coefficient, list):
        raise TypeError("Absorption coefficient must be a list.")
    if not all(isinstance(ac, (int, float)) for ac in absorption_coefficient):
        raise ValueError("Absorption coefficient must be a list of numeric values.")
    if len(absorption_coefficient) == 0:
        raise ValueError("Absorption coefficient list cannot be empty.")
    if any(ac < 0 for ac in absorption_coefficient):
        raise ValueError("Absorption coefficient values must be non-negative.")
    if len(absorption_coefficient) != 8:
        raise ValueError("Absorption coefficient list must contain exactly 8 values for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.")
    self.absorption_coefficient = absorption_coefficient

set_name(name)

Sets the name of the material.

Parameters:

Name Type Description Default
name str

The name of the material.

required

Raises:

Type Description
TypeError

If the name is not a string.

Source code in src/reverberation_calc.py
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
def set_name(self, name):
    """
    Sets the name of the material.

    Parameters
    ----------
    name : str
        The name of the material.

    Raises
    -------
    TypeError
        If the name is not a string.
    """
    if not isinstance(name, str):
        raise TypeError("Name must be a string.")
    self.name = name

set_price(price)

Sets the price of the material.

Parameters:

Name Type Description Default
price int or float

The price of the material in €/m\(^2\).

required

Raises:

Type Description
TypeError

If the price is not a numeric value.

ValueError

If the price is not a positive numeric value.

Source code in src/reverberation_calc.py
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
def set_price(self, price):
    """
    Sets the price of the material.

    Parameters
    ----------
    price : int or float
        The price of the material in €/m$^2$.

    Raises
    -------
    TypeError
        If the price is not a numeric value.
    ValueError
        If the price is not a positive numeric value.
    """
    if not isinstance(price, (int, float)):
        raise TypeError("Price must be an integer or float.")
    if price < 0:
        raise ValueError("Price must be a non-negative value.")
    self.price = price

reverberation_time

Defines a "reverberation_time" object that calculates the reverberation time of a room based on the extended Sabine formula from DIN EN ISO 354.

Attributes:

Name Type Description
calc_room room

The room for which the reverberation time is calculated, which is an instance of the room class.

surfaces list

A list of surfaces in the room, each of which is an instance of the surface class.

frequency_bands list

A list of frequency bands in Hz for which the reverberation time is calculated.

air_damp_calc (bool, optional)

A flag indicating whether air damping is considered in the calculation (default is True).

Aeq int or float

The equivalent sound absorption area of the room in m\(^2\), calculated based on the surfaces and their materials.

c int or float

The speed of sound in air in m/s, calculated based on the room's temperature and pressure.

volume int or float

The volume of the room in m\(^3\).

air_damp air_damp

An instance of the air_damp class that calculates the sound absorption coefficient of air based on frequency, temperature, humidity, and pressure.

reverberation_time list

The calculated reverberation time of the room in s.

Source code in src/reverberation_calc.py
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
class reverberation_time:
    """
    Defines a "reverberation_time" object that calculates the reverberation time of a room based on the extended Sabine formula from DIN EN ISO 354.

    Attributes
    ----------
    calc_room : room
        The room for which the reverberation time is calculated, which is an instance of the room class.
    surfaces : list
        A list of surfaces in the room, each of which is an instance of the surface class.
    frequency_bands : list
        A list of frequency bands in Hz for which the reverberation time is calculated.
    air_damp_calc : bool, optional
        A flag indicating whether air damping is considered in the calculation (default is True).
    Aeq : int or float
        The equivalent sound absorption area of the room in m$^2$, calculated based on the surfaces and their materials.
    c : int or float
        The speed of sound in air in m/s, calculated based on the room's temperature and pressure.
    volume : int or float
        The volume of the room in m$^3$.
    air_damp : air_damp
        An instance of the air_damp class that calculates the sound absorption coefficient of air based on frequency, temperature, humidity, and pressure.
    reverberation_time : list
        The calculated reverberation time of the room in s.
    """

    def __init__(self, calc_room, surfaces, air_damp_calc=True, meas_reverberation_time=None):
        """
        Initializes a reverberation_time object with a specified room, surfaces, and optional parameters for air damping calculation and measured reverberation time.

        Parameters
        ----------
        calc_room : room
            The room for which the reverberation time is calculated, which is an instance of the room class.
        surfaces : list of surface
            A list of surfaces in the room, each of which is an instance of the surface class.
        air_damp_calc : bool, optional
            A flag indicating whether air damping is considered in the calculation (default is True).
        meas_reverberation_time : list of int or float, optional
            A list of measured reverberation times of the room in s (default is None).

        Raises
        -------
        ValueError
            If the room is not an instance of the room class.
        TypeError
            If the surfaces are not a list or if any surface is not an instance of the surface class.
        ValueError
            If the surfaces list is empty.
        TypeError
            If the air_damp_calc is not a boolean.
        TypeError
            If the measured reverberation time is not a list or if it contains non-numeric values.
        ValueError
            If the measured reverberation time list does not contain exactly 8 entries for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.
        ValueError
            If the measured reverberation time list is empty or if it contains negative values.
        """
        if not isinstance(calc_room, room):
            raise TypeError("Room must be an instance of the room class.")
        if not isinstance(surfaces, list):
            raise TypeError("Surfaces must be a list.")
        if not all(isinstance(calc_surface, surface) for calc_surface in surfaces):
            raise TypeError("All surfaces must be instances of the surface class.")
        if len(surfaces) == 0:
            raise ValueError("Surfaces list cannot be empty.")
        if not isinstance(air_damp_calc, bool):
            raise TypeError("Air damping calculation flag must be a boolean.")
        if meas_reverberation_time is not None:
            if not isinstance(meas_reverberation_time, list):
                raise TypeError("Measured reverberation time must be a list.")
            if not all(isinstance(mrt, (int, float)) for mrt in meas_reverberation_time):
                raise ValueError("Measured reverberation time must be a list of numeric values.")
            if len(meas_reverberation_time) != 8:
                raise ValueError("Measured reverberation time must be a list containing 8 entries for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.")
            if len(meas_reverberation_time) == 0:
                raise ValueError("Measured reverberation time list cannot be empty.")
            if any(mrt < 0 for mrt in meas_reverberation_time):
                raise ValueError("Measured reverberation time values must be non-negative.")


        self.calc_room = calc_room
        self.frequency_bands = [63, 125, 250, 500, 1000, 2000, 4000, 8000]
        self.surfaces = surfaces
        self.calculate_Aeq()
        self.c = calc_room.get_c()
        #self.materials = surfaces.materials
        self.volume = calc_room.volume
        self.air_damp_calc = air_damp_calc
        self.air_damp = air_damp(self.frequency_bands)
        self.air_damp.set_temperature(calc_room.get_temperature())
        self.air_damp.set_pressure(calc_room.get_pressure())
        self.air_damp.set_rel_humidity(calc_room.get_rel_humidity())
        if meas_reverberation_time is not None:
            self.meas_reverberation_time = np.array(meas_reverberation_time)
        else:
            self.meas_reverberation_time = None
        self.calculate_reverberation_time()

    def calculate_Aeq(self):
        """
        Calculates the equivalent sound absorption area (Aeq) in m$^2$ of the room based on the surfaces and their materials.
        The equivalent sound absorption area is calculated as the sum of the product of the absorption coefficient and the area of each surface.

        Returns
        -------
        float
            The equivalent sound absorption area of the room in m$^2$.

        Raises
        -------
        ValueError
            If any surface does not have a material with an absorption coefficient defined.
        """
        if not all(hasattr(surface, 'get_material') and surface.get_material() is not None for surface in self.surfaces):
            raise ValueError("All surfaces must have a material with an absorption coefficient defined.")
        coeffs = np.array([surface.get_material().get_absorption_coefficient() for surface in self.surfaces])
        areas = np.array([surface.get_area() for surface in self.surfaces])
        Aeq_octave = coeffs * areas[:, np.newaxis]
        Aeq = np.nansum(Aeq_octave, axis=0)
        nan_mask = np.isnan(Aeq_octave).any(axis=0)
        Aeq[nan_mask] = np.nan
        self.Aeq = Aeq
        return self.Aeq

    def calculate_reverberation_time(self):
        r"""
        Calculates the reverberation time of the room based on the extended Sabine formula, considering air damping if specified.

        The reverberation time is calculated using the formula:

        $$T = \frac{55.3 \cdot V}{A_{eq} \cdot c}$$

        where:

        - $T$ is the reverberation time in s
        - $V$ is the volume of the room in m³
        - $A_{eq}$ is the equivalent sound absorption area in m²
        - $c$ is the speed of sound in air in m/s

        If air damping is considered, the formula is corrected by the speed of sound and air damping:

        $$T = \frac{55.3}{c} \cdot \frac{V}{A_{eq} + 4 \cdot V \cdot m}$$

        where $m$ is the sound absorption coefficient of air in 1/m, calculated based on frequency, temperature, humidity, and pressure according to EN ISO 354 and ISO 9613-1.

        If a measured reverberation time is provided, its equivalent sound absorption area

        $$A_{eq, measured} = \frac{55.3 \cdot V}{T_{measured} \cdot c}$$

        is used to specify initial values for the extension with additional sound absorption areas. The reverberation time is then calculated as:

        $$T = \frac{55.3 \cdot V}{(A_{eq} + A_{eq, measured}) \cdot c}$$
        """
        # Calculate the reverberation time based on the optimized Sabine formula according to DIN EN ISO 354
        if self.air_damp_calc is True:
            # If air damping is considered, use the Sabine formula corrected by the speed of sound and air damping
            if self.meas_reverberation_time is not None:
                # If measured reverberation time is provided, use the calculated equivalent sound absorption area to correct the measured reverberation time
                Aeq_meas = ((55.3 / self.c) * (self.volume / (self.meas_reverberation_time))) - 4 * self.volume * self.air_damp.calculate_coefficient()
                self.reverberation_time = (55.3 / self.c) * (self.volume / (self.Aeq + Aeq_meas + 4 * self.volume * self.air_damp.calculate_coefficient()))
            else:
                self.reverberation_time = (55.3 / self.c) * (self.volume / (self.Aeq + 4 * self.volume * self.air_damp.calculate_coefficient()))

        if self.air_damp_calc == False:
            # If air damping is not considered, use the standard Sabine formula corrected by the speed of sound
            if self.meas_reverberation_time is not None:
                # If measured reverberation time is provided, use the calculated equivalent sound absorption area to correct the measured reverberation time
                Aeq_meas = (55.3 * self.volume) / (self.meas_reverberation_time * self.c)
                self.reverberation_time = (55.3 * self.volume) / ((self.Aeq + Aeq_meas) * self.c)
            else:
                self.reverberation_time = (55.3 * self.volume) / (self.Aeq * self.c)

__init__(calc_room, surfaces, air_damp_calc=True, meas_reverberation_time=None)

Initializes a reverberation_time object with a specified room, surfaces, and optional parameters for air damping calculation and measured reverberation time.

Parameters:

Name Type Description Default
calc_room room

The room for which the reverberation time is calculated, which is an instance of the room class.

required
surfaces list of surface

A list of surfaces in the room, each of which is an instance of the surface class.

required
air_damp_calc bool

A flag indicating whether air damping is considered in the calculation (default is True).

True
meas_reverberation_time list of int or float

A list of measured reverberation times of the room in s (default is None).

None

Raises:

Type Description
ValueError

If the room is not an instance of the room class.

TypeError

If the surfaces are not a list or if any surface is not an instance of the surface class.

ValueError

If the surfaces list is empty.

TypeError

If the air_damp_calc is not a boolean.

TypeError

If the measured reverberation time is not a list or if it contains non-numeric values.

ValueError

If the measured reverberation time list does not contain exactly 8 entries for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.

ValueError

If the measured reverberation time list is empty or if it contains negative values.

Source code in src/reverberation_calc.py
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
def __init__(self, calc_room, surfaces, air_damp_calc=True, meas_reverberation_time=None):
    """
    Initializes a reverberation_time object with a specified room, surfaces, and optional parameters for air damping calculation and measured reverberation time.

    Parameters
    ----------
    calc_room : room
        The room for which the reverberation time is calculated, which is an instance of the room class.
    surfaces : list of surface
        A list of surfaces in the room, each of which is an instance of the surface class.
    air_damp_calc : bool, optional
        A flag indicating whether air damping is considered in the calculation (default is True).
    meas_reverberation_time : list of int or float, optional
        A list of measured reverberation times of the room in s (default is None).

    Raises
    -------
    ValueError
        If the room is not an instance of the room class.
    TypeError
        If the surfaces are not a list or if any surface is not an instance of the surface class.
    ValueError
        If the surfaces list is empty.
    TypeError
        If the air_damp_calc is not a boolean.
    TypeError
        If the measured reverberation time is not a list or if it contains non-numeric values.
    ValueError
        If the measured reverberation time list does not contain exactly 8 entries for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.
    ValueError
        If the measured reverberation time list is empty or if it contains negative values.
    """
    if not isinstance(calc_room, room):
        raise TypeError("Room must be an instance of the room class.")
    if not isinstance(surfaces, list):
        raise TypeError("Surfaces must be a list.")
    if not all(isinstance(calc_surface, surface) for calc_surface in surfaces):
        raise TypeError("All surfaces must be instances of the surface class.")
    if len(surfaces) == 0:
        raise ValueError("Surfaces list cannot be empty.")
    if not isinstance(air_damp_calc, bool):
        raise TypeError("Air damping calculation flag must be a boolean.")
    if meas_reverberation_time is not None:
        if not isinstance(meas_reverberation_time, list):
            raise TypeError("Measured reverberation time must be a list.")
        if not all(isinstance(mrt, (int, float)) for mrt in meas_reverberation_time):
            raise ValueError("Measured reverberation time must be a list of numeric values.")
        if len(meas_reverberation_time) != 8:
            raise ValueError("Measured reverberation time must be a list containing 8 entries for the frequency bands 63, 125, 250, 500, 1000, 2000, 4000, and 8000 Hz.")
        if len(meas_reverberation_time) == 0:
            raise ValueError("Measured reverberation time list cannot be empty.")
        if any(mrt < 0 for mrt in meas_reverberation_time):
            raise ValueError("Measured reverberation time values must be non-negative.")


    self.calc_room = calc_room
    self.frequency_bands = [63, 125, 250, 500, 1000, 2000, 4000, 8000]
    self.surfaces = surfaces
    self.calculate_Aeq()
    self.c = calc_room.get_c()
    #self.materials = surfaces.materials
    self.volume = calc_room.volume
    self.air_damp_calc = air_damp_calc
    self.air_damp = air_damp(self.frequency_bands)
    self.air_damp.set_temperature(calc_room.get_temperature())
    self.air_damp.set_pressure(calc_room.get_pressure())
    self.air_damp.set_rel_humidity(calc_room.get_rel_humidity())
    if meas_reverberation_time is not None:
        self.meas_reverberation_time = np.array(meas_reverberation_time)
    else:
        self.meas_reverberation_time = None
    self.calculate_reverberation_time()

calculate_Aeq()

Calculates the equivalent sound absorption area (Aeq) in m\(^2\) of the room based on the surfaces and their materials. The equivalent sound absorption area is calculated as the sum of the product of the absorption coefficient and the area of each surface.

Returns:

Type Description
float

The equivalent sound absorption area of the room in m\(^2\).

Raises:

Type Description
ValueError

If any surface does not have a material with an absorption coefficient defined.

Source code in src/reverberation_calc.py
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
def calculate_Aeq(self):
    """
    Calculates the equivalent sound absorption area (Aeq) in m$^2$ of the room based on the surfaces and their materials.
    The equivalent sound absorption area is calculated as the sum of the product of the absorption coefficient and the area of each surface.

    Returns
    -------
    float
        The equivalent sound absorption area of the room in m$^2$.

    Raises
    -------
    ValueError
        If any surface does not have a material with an absorption coefficient defined.
    """
    if not all(hasattr(surface, 'get_material') and surface.get_material() is not None for surface in self.surfaces):
        raise ValueError("All surfaces must have a material with an absorption coefficient defined.")
    coeffs = np.array([surface.get_material().get_absorption_coefficient() for surface in self.surfaces])
    areas = np.array([surface.get_area() for surface in self.surfaces])
    Aeq_octave = coeffs * areas[:, np.newaxis]
    Aeq = np.nansum(Aeq_octave, axis=0)
    nan_mask = np.isnan(Aeq_octave).any(axis=0)
    Aeq[nan_mask] = np.nan
    self.Aeq = Aeq
    return self.Aeq

calculate_reverberation_time()

Calculates the reverberation time of the room based on the extended Sabine formula, considering air damping if specified.

The reverberation time is calculated using the formula:

\[T = \frac{55.3 \cdot V}{A_{eq} \cdot c}\]

where:

  • \(T\) is the reverberation time in s
  • \(V\) is the volume of the room in m³
  • \(A_{eq}\) is the equivalent sound absorption area in m²
  • \(c\) is the speed of sound in air in m/s

If air damping is considered, the formula is corrected by the speed of sound and air damping:

\[T = \frac{55.3}{c} \cdot \frac{V}{A_{eq} + 4 \cdot V \cdot m}\]

where \(m\) is the sound absorption coefficient of air in 1/m, calculated based on frequency, temperature, humidity, and pressure according to EN ISO 354 and ISO 9613-1.

If a measured reverberation time is provided, its equivalent sound absorption area

\[A_{eq, measured} = \frac{55.3 \cdot V}{T_{measured} \cdot c}\]

is used to specify initial values for the extension with additional sound absorption areas. The reverberation time is then calculated as:

\[T = \frac{55.3 \cdot V}{(A_{eq} + A_{eq, measured}) \cdot c}\]
Source code in src/reverberation_calc.py
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
def calculate_reverberation_time(self):
    r"""
    Calculates the reverberation time of the room based on the extended Sabine formula, considering air damping if specified.

    The reverberation time is calculated using the formula:

    $$T = \frac{55.3 \cdot V}{A_{eq} \cdot c}$$

    where:

    - $T$ is the reverberation time in s
    - $V$ is the volume of the room in m³
    - $A_{eq}$ is the equivalent sound absorption area in m²
    - $c$ is the speed of sound in air in m/s

    If air damping is considered, the formula is corrected by the speed of sound and air damping:

    $$T = \frac{55.3}{c} \cdot \frac{V}{A_{eq} + 4 \cdot V \cdot m}$$

    where $m$ is the sound absorption coefficient of air in 1/m, calculated based on frequency, temperature, humidity, and pressure according to EN ISO 354 and ISO 9613-1.

    If a measured reverberation time is provided, its equivalent sound absorption area

    $$A_{eq, measured} = \frac{55.3 \cdot V}{T_{measured} \cdot c}$$

    is used to specify initial values for the extension with additional sound absorption areas. The reverberation time is then calculated as:

    $$T = \frac{55.3 \cdot V}{(A_{eq} + A_{eq, measured}) \cdot c}$$
    """
    # Calculate the reverberation time based on the optimized Sabine formula according to DIN EN ISO 354
    if self.air_damp_calc is True:
        # If air damping is considered, use the Sabine formula corrected by the speed of sound and air damping
        if self.meas_reverberation_time is not None:
            # If measured reverberation time is provided, use the calculated equivalent sound absorption area to correct the measured reverberation time
            Aeq_meas = ((55.3 / self.c) * (self.volume / (self.meas_reverberation_time))) - 4 * self.volume * self.air_damp.calculate_coefficient()
            self.reverberation_time = (55.3 / self.c) * (self.volume / (self.Aeq + Aeq_meas + 4 * self.volume * self.air_damp.calculate_coefficient()))
        else:
            self.reverberation_time = (55.3 / self.c) * (self.volume / (self.Aeq + 4 * self.volume * self.air_damp.calculate_coefficient()))

    if self.air_damp_calc == False:
        # If air damping is not considered, use the standard Sabine formula corrected by the speed of sound
        if self.meas_reverberation_time is not None:
            # If measured reverberation time is provided, use the calculated equivalent sound absorption area to correct the measured reverberation time
            Aeq_meas = (55.3 * self.volume) / (self.meas_reverberation_time * self.c)
            self.reverberation_time = (55.3 * self.volume) / ((self.Aeq + Aeq_meas) * self.c)
        else:
            self.reverberation_time = (55.3 * self.volume) / (self.Aeq * self.c)

room

Defines a "room" object with properties such as volume, temperature, pressure, relative humidity, and speed of sound.

Parameters:

Name Type Description Default
volume int or float

The volume of the room in m\(^2\).

required

Attributes:

Name Type Description
volume int or float

The volume of the room in m\(^2\).

temperature int or float

The temperature of the room in °C (default is 20 °C).

pressure int or float

The pressure of the room in kPa (default is 101.325 kPa).

rel_humidity int or float

The relative humidity of the room in % (default is 50 %).

height int or float or None

The height of the room in m (default is None).

c int or float

The speed of sound in air in m/s, calculated based on temperature and relative humidity.

Source code in src/reverberation_calc.py
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
class room:
    """
    Defines a "room" object with properties such as volume, temperature, pressure, relative humidity, and speed of sound.

    Parameters
    ----------
    volume : int or float
        The volume of the room in m$^2$.

    Attributes
    ----------
    volume : int or float
        The volume of the room in m$^2$.
    temperature : int or float
        The temperature of the room in °C (default is 20 °C).
    pressure : int or float
        The pressure of the room in kPa (default is 101.325 kPa).
    rel_humidity : int or float
        The relative humidity of the room in % (default is 50 %).
    height : int or float or None
        The height of the room in m (default is None).
    c : int or float
        The speed of sound in air in m/s, calculated based on temperature and relative humidity.
    """

    def __init__(self, volume):
        """
        Initializes a room object with a specified volume and default values for temperature, pressure, relative humidity, and speed of sound.

        Parameters
        ----------
        volume : int or float 
            The volume of the room in m$^2$.

        Raises
        ------
        TypeError
            If the volume is not a number.
        ValueError
            If the volume is not positive.
        """
        if not isinstance(volume, (int, float)):
            raise TypeError("Volume must be an integer or float.")
        if volume <= 0:
            raise ValueError("Volume must be a positive value.")

        self.volume = volume
        self.temperature = 20           # Celsius
        self.pressure = 101.325         # kPa
        self.rel_humidity = 50          # percentage
        self.height = None              # meters
        self.c = self.get_c()           # Speed of sound in air in m/s

    def set_height(self, height):
        """
        Sets the height of the room in m.

        Parameters
        ----------
        height : int or float
            The height of the room in m.

        Raises
        -------
        TypeError
            If the height is not a number.
        ValueError
            If the height is not positive.
        """
        if not isinstance(height, (int, float)):
            raise TypeError("Height must be an integer or float.")
        if height <= 0:
            raise ValueError("Height must be a positive value.")
        self.height = height

    def get_height(self):
        """
        Returns the height of the room in m.

        Returns
        -------
        float or None
            The height of the room in m.
        """
        return self.height

    def set_volume(self, volume):
        """
        Sets the volume of the room in m$^2$.

        Parameters
        ----------
        volume : int or float
            The volume of the room in m$^2$.

        Raises
        -------
        TypeError
            If the volume is not an integer.
        ValueError
            If the volume is not a positive integer.
        """
        if not isinstance(volume, (int, float)):
            raise TypeError("Volume must be an integer or float.")
        if volume <= 0:
            raise ValueError("Volume must be a positive value.")
        self.volume = volume

    def get_volume(self):
        """
        Returns the volume of the room in m$^2$.

        Returns
        -------
        float
            The volume of the room in m$^2$.
        """
        return self.volume

    def set_temperature(self, temperature):
        """
        Sets the temperature of the room in °C.

        Parameters
        ----------
        temperature : int or float
            The temperature of the room in °C.

        Raises
        -------
        TypeError
            If the temperature is not a numeric value.
        ValueError
            If the temperature is not above absolute zero (-273.15 °C).
        """
        if not isinstance(temperature, (int, float)):
            raise TypeError("Temperature must be an integer or float.")
        if temperature < -273.15:
            raise ValueError("Temperature must be above absolute zero (-273.15 °C).")
        self.temperature = temperature

    def get_temperature(self):
        """
        Returns the temperature of the room in °C.

        Returns
        -------
        float
            The temperature of the room in °C.
        """
        return self.temperature

    def set_pressure(self, pressure):
        """
        Sets the pressure of the room in kPa.

        Parameters
        ----------
        pressure : int or float
            The pressure of the room in kPa.

        Raises
        -------
        TypeError
            If the pressure is not an integer or float.
        ValueError
            If the pressure is not a positive integer.
        """
        if not isinstance(pressure, (int, float)):
            raise TypeError("Pressure must be an integer or float.")
        if pressure <= 0:
            raise ValueError("Pressure must be a positive value.")
        self.pressure = pressure

    def get_pressure(self):
        """
        Returns the pressure of the room in kPa.

        Returns
        -------
        float
            The pressure of the room in kPA.
        """
        return self.pressure

    def set_rel_humidity(self, rel_humidity):
        """
        Sets the relative humidity of the room in %.

        Parameters
        ----------
        rel_humidity : int or float
            The relative humidity of the room in %.

        Raises
        -------
        TypeError
            If the relative humidity is not an integer or float.
        ValueError
            If the relative humidity is not in the range of 0 % - 100 %.
        """
        if not isinstance(rel_humidity, (int, float)):
            raise TypeError("Relative humidity must be an integer or float.")
        if rel_humidity < 0 or rel_humidity > 100:
            raise ValueError("Relative humidity must be between 0 and 100 %.")
        self.rel_humidity = rel_humidity

    def get_rel_humidity(self):
        """
        Returns the relative humidity of the room in %.

        Returns
        -------
        float
            The relative humidity of the room in %.
        """
        return self.rel_humidity

    def get_c(self):
        """
        Calculates and returns the speed of sound in air based on the current temperature and relative humidity according to DIN EN ISO 354.

        Returns
        -------
        float
            The speed of sound in air in m/s.
        """
        self.c = (331.6 + 0.6 * self.get_temperature())# * (1 + (self.get_rel_humidity() / 100)) ** 0.5 # automatisch ausgefüllt, kp wieso
        return self.c

__init__(volume)

Initializes a room object with a specified volume and default values for temperature, pressure, relative humidity, and speed of sound.

Parameters:

Name Type Description Default
volume int or float

The volume of the room in m\(^2\).

required

Raises:

Type Description
TypeError

If the volume is not a number.

ValueError

If the volume is not positive.

Source code in src/reverberation_calc.py
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def __init__(self, volume):
    """
    Initializes a room object with a specified volume and default values for temperature, pressure, relative humidity, and speed of sound.

    Parameters
    ----------
    volume : int or float 
        The volume of the room in m$^2$.

    Raises
    ------
    TypeError
        If the volume is not a number.
    ValueError
        If the volume is not positive.
    """
    if not isinstance(volume, (int, float)):
        raise TypeError("Volume must be an integer or float.")
    if volume <= 0:
        raise ValueError("Volume must be a positive value.")

    self.volume = volume
    self.temperature = 20           # Celsius
    self.pressure = 101.325         # kPa
    self.rel_humidity = 50          # percentage
    self.height = None              # meters
    self.c = self.get_c()           # Speed of sound in air in m/s

get_c()

Calculates and returns the speed of sound in air based on the current temperature and relative humidity according to DIN EN ISO 354.

Returns:

Type Description
float

The speed of sound in air in m/s.

Source code in src/reverberation_calc.py
222
223
224
225
226
227
228
229
230
231
232
def get_c(self):
    """
    Calculates and returns the speed of sound in air based on the current temperature and relative humidity according to DIN EN ISO 354.

    Returns
    -------
    float
        The speed of sound in air in m/s.
    """
    self.c = (331.6 + 0.6 * self.get_temperature())# * (1 + (self.get_rel_humidity() / 100)) ** 0.5 # automatisch ausgefüllt, kp wieso
    return self.c

get_height()

Returns the height of the room in m.

Returns:

Type Description
float or None

The height of the room in m.

Source code in src/reverberation_calc.py
79
80
81
82
83
84
85
86
87
88
def get_height(self):
    """
    Returns the height of the room in m.

    Returns
    -------
    float or None
        The height of the room in m.
    """
    return self.height

get_pressure()

Returns the pressure of the room in kPa.

Returns:

Type Description
float

The pressure of the room in kPA.

Source code in src/reverberation_calc.py
178
179
180
181
182
183
184
185
186
187
def get_pressure(self):
    """
    Returns the pressure of the room in kPa.

    Returns
    -------
    float
        The pressure of the room in kPA.
    """
    return self.pressure

get_rel_humidity()

Returns the relative humidity of the room in %.

Returns:

Type Description
float

The relative humidity of the room in %.

Source code in src/reverberation_calc.py
211
212
213
214
215
216
217
218
219
220
def get_rel_humidity(self):
    """
    Returns the relative humidity of the room in %.

    Returns
    -------
    float
        The relative humidity of the room in %.
    """
    return self.rel_humidity

get_temperature()

Returns the temperature of the room in °C.

Returns:

Type Description
float

The temperature of the room in °C.

Source code in src/reverberation_calc.py
145
146
147
148
149
150
151
152
153
154
def get_temperature(self):
    """
    Returns the temperature of the room in °C.

    Returns
    -------
    float
        The temperature of the room in °C.
    """
    return self.temperature

get_volume()

Returns the volume of the room in m\(^2\).

Returns:

Type Description
float

The volume of the room in m\(^2\).

Source code in src/reverberation_calc.py
112
113
114
115
116
117
118
119
120
121
def get_volume(self):
    """
    Returns the volume of the room in m$^2$.

    Returns
    -------
    float
        The volume of the room in m$^2$.
    """
    return self.volume

set_height(height)

Sets the height of the room in m.

Parameters:

Name Type Description Default
height int or float

The height of the room in m.

required

Raises:

Type Description
TypeError

If the height is not a number.

ValueError

If the height is not positive.

Source code in src/reverberation_calc.py
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
def set_height(self, height):
    """
    Sets the height of the room in m.

    Parameters
    ----------
    height : int or float
        The height of the room in m.

    Raises
    -------
    TypeError
        If the height is not a number.
    ValueError
        If the height is not positive.
    """
    if not isinstance(height, (int, float)):
        raise TypeError("Height must be an integer or float.")
    if height <= 0:
        raise ValueError("Height must be a positive value.")
    self.height = height

set_pressure(pressure)

Sets the pressure of the room in kPa.

Parameters:

Name Type Description Default
pressure int or float

The pressure of the room in kPa.

required

Raises:

Type Description
TypeError

If the pressure is not an integer or float.

ValueError

If the pressure is not a positive integer.

Source code in src/reverberation_calc.py
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
def set_pressure(self, pressure):
    """
    Sets the pressure of the room in kPa.

    Parameters
    ----------
    pressure : int or float
        The pressure of the room in kPa.

    Raises
    -------
    TypeError
        If the pressure is not an integer or float.
    ValueError
        If the pressure is not a positive integer.
    """
    if not isinstance(pressure, (int, float)):
        raise TypeError("Pressure must be an integer or float.")
    if pressure <= 0:
        raise ValueError("Pressure must be a positive value.")
    self.pressure = pressure

set_rel_humidity(rel_humidity)

Sets the relative humidity of the room in %.

Parameters:

Name Type Description Default
rel_humidity int or float

The relative humidity of the room in %.

required

Raises:

Type Description
TypeError

If the relative humidity is not an integer or float.

ValueError

If the relative humidity is not in the range of 0 % - 100 %.

Source code in src/reverberation_calc.py
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
def set_rel_humidity(self, rel_humidity):
    """
    Sets the relative humidity of the room in %.

    Parameters
    ----------
    rel_humidity : int or float
        The relative humidity of the room in %.

    Raises
    -------
    TypeError
        If the relative humidity is not an integer or float.
    ValueError
        If the relative humidity is not in the range of 0 % - 100 %.
    """
    if not isinstance(rel_humidity, (int, float)):
        raise TypeError("Relative humidity must be an integer or float.")
    if rel_humidity < 0 or rel_humidity > 100:
        raise ValueError("Relative humidity must be between 0 and 100 %.")
    self.rel_humidity = rel_humidity

set_temperature(temperature)

Sets the temperature of the room in °C.

Parameters:

Name Type Description Default
temperature int or float

The temperature of the room in °C.

required

Raises:

Type Description
TypeError

If the temperature is not a numeric value.

ValueError

If the temperature is not above absolute zero (-273.15 °C).

Source code in src/reverberation_calc.py
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
def set_temperature(self, temperature):
    """
    Sets the temperature of the room in °C.

    Parameters
    ----------
    temperature : int or float
        The temperature of the room in °C.

    Raises
    -------
    TypeError
        If the temperature is not a numeric value.
    ValueError
        If the temperature is not above absolute zero (-273.15 °C).
    """
    if not isinstance(temperature, (int, float)):
        raise TypeError("Temperature must be an integer or float.")
    if temperature < -273.15:
        raise ValueError("Temperature must be above absolute zero (-273.15 °C).")
    self.temperature = temperature

set_volume(volume)

Sets the volume of the room in m\(^2\).

Parameters:

Name Type Description Default
volume int or float

The volume of the room in m\(^2\).

required

Raises:

Type Description
TypeError

If the volume is not an integer.

ValueError

If the volume is not a positive integer.

Source code in src/reverberation_calc.py
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
def set_volume(self, volume):
    """
    Sets the volume of the room in m$^2$.

    Parameters
    ----------
    volume : int or float
        The volume of the room in m$^2$.

    Raises
    -------
    TypeError
        If the volume is not an integer.
    ValueError
        If the volume is not a positive integer.
    """
    if not isinstance(volume, (int, float)):
        raise TypeError("Volume must be an integer or float.")
    if volume <= 0:
        raise ValueError("Volume must be a positive value.")
    self.volume = volume

surface

Defines a "surface" object with properties such as name, area, and material.

Attributes:

Name Type Description
name str

The name of the surface.

area int or float

The area of the surface in m\(^2\).

material material

The material of the surface, which is an instance of the material class.

Source code in src/reverberation_calc.py
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
class surface:
    """
    Defines a "surface" object with properties such as name, area, and material.

    Attributes
    ----------
    name : str
        The name of the surface.
    area : int or float
        The area of the surface in m$^2$.
    material : material
        The material of the surface, which is an instance of the material class.
    """

    def __init__(self, name, area, material):
        """
        Initializes a surface object with a specified name, area, and material.

        Parameters
        ----------
        name : str
            The name of the surface.
        area : int or float
            The area of the surface in m$^2$.
        material : material 
            The material of the surface, which is an instance of the material class.

        Raises
        -------
        TypeError
            If the name is not a string or if the area is not a numeric value.
        ValueError
            If the area is not a positive numeric value.
        """
        if not isinstance(name, str):
            raise TypeError("Name must be a string.")
        if not isinstance(area, (int, float)):
            raise TypeError("Area must be an integer or float.")
        self.name = name
        self.area = area
        self.material = material

    def set_area(self, area):
        """
        Sets the area of the surface.

        Parameters
        ----------
        area : int or float
            The area of the surface in m$^2$.

        Raises
        -------
        TypeError
            If the area is not a numeric value.
        ValueError
            If the area is not a positive numeric value.
        """
        if not isinstance(area, (int, float)):
            raise TypeError("Area must be a numeric value.")
        if area <= 0:
            raise ValueError("Area must be a positive value.")
        self.area = area

    def get_area(self):
        """
        Returns the area of the surface.

        Returns
        -------
        float
            The area of the surface in m$^2$.
        """

        return self.area

    def set_material(self, material):
        """
        Sets the material of the surface.

        Parameters
        ----------
        material : material
            The material of the surface, which is an instance of the material class.

        Raises
        -------
        TypeError
            If the material is not an instance of the material class.
        ValueError
            If the material does not have an absorption coefficient defined.
        """
        if not isinstance(material, material):
            raise TypeError("Material must be an instance of the material class.")
        if not hasattr(material, 'absorption_coefficient'):
            raise ValueError("Material must have an absorption coefficient defined.")
        self.material = material

    def get_material(self):
        """
        Returns the material of the surface.

        Returns
        -------
        material
            The material of the surface, which is an instance of the material class.
        """
        return self.material

    def set_surface_name(self, name):
        """
        Sets the name of the surface.

        Parameters
        ----------
        name : str
            The name of the surface.

        Raises
        -------
        TypeError
            If the name is not a string.
        """
        if not isinstance(name, str):
            raise TypeError("Name must be a string.")
        self.name = name

    def get_surface_name(self):
        """
        Returns the name of the surface if it has been set.

        Returns
        -------
        str or None
            The name of the surface if it has been set.
        """
        return self.name if hasattr(self, 'name') else None

__init__(name, area, material)

Initializes a surface object with a specified name, area, and material.

Parameters:

Name Type Description Default
name str

The name of the surface.

required
area int or float

The area of the surface in m\(^2\).

required
material material

The material of the surface, which is an instance of the material class.

required

Raises:

Type Description
TypeError

If the name is not a string or if the area is not a numeric value.

ValueError

If the area is not a positive numeric value.

Source code in src/reverberation_calc.py
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
def __init__(self, name, area, material):
    """
    Initializes a surface object with a specified name, area, and material.

    Parameters
    ----------
    name : str
        The name of the surface.
    area : int or float
        The area of the surface in m$^2$.
    material : material 
        The material of the surface, which is an instance of the material class.

    Raises
    -------
    TypeError
        If the name is not a string or if the area is not a numeric value.
    ValueError
        If the area is not a positive numeric value.
    """
    if not isinstance(name, str):
        raise TypeError("Name must be a string.")
    if not isinstance(area, (int, float)):
        raise TypeError("Area must be an integer or float.")
    self.name = name
    self.area = area
    self.material = material

get_area()

Returns the area of the surface.

Returns:

Type Description
float

The area of the surface in m\(^2\).

Source code in src/reverberation_calc.py
713
714
715
716
717
718
719
720
721
722
723
def get_area(self):
    """
    Returns the area of the surface.

    Returns
    -------
    float
        The area of the surface in m$^2$.
    """

    return self.area

get_material()

Returns the material of the surface.

Returns:

Type Description
material

The material of the surface, which is an instance of the material class.

Source code in src/reverberation_calc.py
747
748
749
750
751
752
753
754
755
756
def get_material(self):
    """
    Returns the material of the surface.

    Returns
    -------
    material
        The material of the surface, which is an instance of the material class.
    """
    return self.material

get_surface_name()

Returns the name of the surface if it has been set.

Returns:

Type Description
str or None

The name of the surface if it has been set.

Source code in src/reverberation_calc.py
776
777
778
779
780
781
782
783
784
785
def get_surface_name(self):
    """
    Returns the name of the surface if it has been set.

    Returns
    -------
    str or None
        The name of the surface if it has been set.
    """
    return self.name if hasattr(self, 'name') else None

set_area(area)

Sets the area of the surface.

Parameters:

Name Type Description Default
area int or float

The area of the surface in m\(^2\).

required

Raises:

Type Description
TypeError

If the area is not a numeric value.

ValueError

If the area is not a positive numeric value.

Source code in src/reverberation_calc.py
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
def set_area(self, area):
    """
    Sets the area of the surface.

    Parameters
    ----------
    area : int or float
        The area of the surface in m$^2$.

    Raises
    -------
    TypeError
        If the area is not a numeric value.
    ValueError
        If the area is not a positive numeric value.
    """
    if not isinstance(area, (int, float)):
        raise TypeError("Area must be a numeric value.")
    if area <= 0:
        raise ValueError("Area must be a positive value.")
    self.area = area

set_material(material)

Sets the material of the surface.

Parameters:

Name Type Description Default
material material

The material of the surface, which is an instance of the material class.

required

Raises:

Type Description
TypeError

If the material is not an instance of the material class.

ValueError

If the material does not have an absorption coefficient defined.

Source code in src/reverberation_calc.py
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
def set_material(self, material):
    """
    Sets the material of the surface.

    Parameters
    ----------
    material : material
        The material of the surface, which is an instance of the material class.

    Raises
    -------
    TypeError
        If the material is not an instance of the material class.
    ValueError
        If the material does not have an absorption coefficient defined.
    """
    if not isinstance(material, material):
        raise TypeError("Material must be an instance of the material class.")
    if not hasattr(material, 'absorption_coefficient'):
        raise ValueError("Material must have an absorption coefficient defined.")
    self.material = material

set_surface_name(name)

Sets the name of the surface.

Parameters:

Name Type Description Default
name str

The name of the surface.

required

Raises:

Type Description
TypeError

If the name is not a string.

Source code in src/reverberation_calc.py
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
def set_surface_name(self, name):
    """
    Sets the name of the surface.

    Parameters
    ----------
    name : str
        The name of the surface.

    Raises
    -------
    TypeError
        If the name is not a string.
    """
    if not isinstance(name, str):
        raise TypeError("Name must be a string.")
    self.name = name