Coverage for kwave/kWaveSimulation_helper/set_sound_speed_ref.py: 28%

21 statements  

« prev     ^ index     » next       coverage.py v7.7.1, created at 2025-03-24 12:06 -0700

1import logging 

2 

3import numpy as np 

4 

5from kwave.kmedium import kWaveMedium 

6from kwave.options.simulation_options import SimulationType 

7 

8 

9def set_sound_speed_ref(medium: kWaveMedium, simulation_type: SimulationType): 

10 """ 

11 select the reference sound speed used in the k-space operator 

12 based on the heterogeneous sound speed map 

13 Args: 

14 medium: kWaveMedium object 

15 simulation_type: Simulation type (fluid, axisymmetric, elastic, elastic with k-space correction) 

16 Returns: 

17 

18 """ 

19 if not simulation_type.is_elastic_simulation(): 

20 return get_ordinary_sound_speed_ref(medium) 

21 elif simulation_type == SimulationType.ELASTIC: # pragma: no cover 

22 return get_pstd_elastic_sound_speed_ref(medium) 

23 elif simulation_type == SimulationType.ELASTIC_WITH_KSPACE_CORRECTION: # pragma: no cover 

24 return get_kspace_elastic_sound_speed_ref(medium) 

25 else: 

26 raise NotImplementedError("Non-supported simulation type: " + str(simulation_type)) 

27 

28 

29def get_ordinary_sound_speed_ref(medium): 

30 """ 

31 calculate the reference sound speed for the fluid code, using the 

32 maximum by default which ensures the model is unconditionally stable 

33 Args: 

34 medium: 

35 

36 Returns: 

37 

38 """ 

39 c_ref = _get_sound_speed_ref(medium.sound_speed_ref, medium.sound_speed) 

40 logging.log(logging.INFO, f" reference sound speed: {c_ref} m/s") 

41 return c_ref, None, None 

42 

43 

44def get_pstd_elastic_sound_speed_ref(medium: kWaveMedium): # pragma: no cover 

45 """ 

46 in the pstd elastic case, the reference sound speed is only used to 

47 calculate the PML absorption, so just use the compressional wave speed 

48 Args: 

49 medium: 

50 

51 Returns: 

52 

53 """ 

54 c_ref = _get_sound_speed_ref(medium.sound_speed_ref, medium.sound_speed_compression) 

55 logging.log(logging.INFO, f" reference sound speed: {c_ref} m/s") 

56 return c_ref, None, None 

57 

58 

59def get_kspace_elastic_sound_speed_ref(medium: kWaveMedium): # pragma: no cover 

60 """ 

61 in the k-space elastic case, there are two reference sound speeds for 

62 the compressional and shear waves, so compute them separately 

63 Args: 

64 medium: 

65 

66 Returns: 

67 

68 """ 

69 c_ref_compression = _get_sound_speed_ref(medium.sound_speed_ref_compression, medium.sound_speed_compression) 

70 logging.log(logging.INFO, f" reference sound speed (compression): {c_ref_compression} m/s") 

71 

72 c_ref_shear = _get_sound_speed_ref(medium.sound_speed_ref_shear, medium.sound_speed_shear) 

73 logging.log(logging.INFO, f" reference sound speed (shear): {c_ref_shear} m/s") 

74 

75 return None, c_ref_compression, c_ref_shear 

76 

77 

78def _get_sound_speed_ref(reference, speed): 

79 reductions = {"min": np.min, "max": np.max, "mean": np.mean} 

80 

81 if reference is not None: 

82 # if reference is defined, check whether it is a scalar or 'reduction' 

83 if np.isscalar(reference): 

84 c_ref = reference 

85 else: 

86 c_ref = reductions[reference](speed) 

87 else: 

88 c_ref = reductions["max"](speed) 

89 

90 logging.log(logging.INFO, f" reference sound speed: {c_ref} m/s") 

91 return float(c_ref)