fullwave25 1.0.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fullwave25 might be problematic. Click here for more details.

Files changed (225) hide show
  1. fullwave/__init__.py +28 -0
  2. fullwave/constants/__init__.py +5 -0
  3. fullwave/constants/material_properties.py +112 -0
  4. fullwave/grid.py +222 -0
  5. fullwave/medium.py +1042 -0
  6. fullwave/medium_builder/__init__.py +12 -0
  7. fullwave/medium_builder/domain.py +151 -0
  8. fullwave/medium_builder/medium_builder.py +198 -0
  9. fullwave/medium_builder/presets/__init__.py +8 -0
  10. fullwave/medium_builder/presets/data/.keep +0 -0
  11. fullwave/medium_builder/presets/data/abdominal_wall/i2365f_etfw1.mat +0 -0
  12. fullwave/medium_builder/presets/domain_abdominal_wall.py +293 -0
  13. fullwave/medium_builder/presets/domain_background.py +140 -0
  14. fullwave/medium_builder/presets/domain_scatterer.py +179 -0
  15. fullwave/medium_builder/presets/domain_simple.py +92 -0
  16. fullwave/medium_builder/presets/domain_water_gel.py +1 -0
  17. fullwave/sensor.py +161 -0
  18. fullwave/solver/__init__.py +1 -0
  19. fullwave/solver/bins/database/relaxation_params_database_num_relax=2_20251027_1437.mat +0 -0
  20. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenu +0 -0
  21. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_100_cuda129 +0 -0
  22. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_101_cuda129 +0 -0
  23. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_120_cuda129 +0 -0
  24. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_61_cuda118 +0 -0
  25. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_61_cuda124 +0 -0
  26. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_61_cuda126 +0 -0
  27. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_61_cuda129 +0 -0
  28. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_70_cuda118 +0 -0
  29. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_70_cuda124 +0 -0
  30. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_70_cuda126 +0 -0
  31. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_70_cuda129 +0 -0
  32. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_75_cuda118 +0 -0
  33. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_75_cuda124 +0 -0
  34. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_75_cuda126 +0 -0
  35. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_75_cuda129 +0 -0
  36. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_80_cuda118 +0 -0
  37. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_80_cuda124 +0 -0
  38. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_80_cuda126 +0 -0
  39. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_80_cuda129 +0 -0
  40. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_86_cuda118 +0 -0
  41. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_86_cuda124 +0 -0
  42. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_86_cuda126 +0 -0
  43. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_86_cuda129 +0 -0
  44. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_89_cuda118 +0 -0
  45. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_89_cuda126 +0 -0
  46. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_89_cuda129 +0 -0
  47. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_90_cuda118 +0 -0
  48. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_90_cuda124 +0 -0
  49. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_90_cuda126 +0 -0
  50. fullwave/solver/bins/exponential_attenuation/gpu/2d/fullwave2_2d_exponential_attenuation_gpu_sm_90_cuda129 +0 -0
  51. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_100_cuda129 +0 -0
  52. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_101_cuda129 +0 -0
  53. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_120_cuda129 +0 -0
  54. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_61_cuda118 +0 -0
  55. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_61_cuda124 +0 -0
  56. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_61_cuda126 +0 -0
  57. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_61_cuda129 +0 -0
  58. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_70_cuda118 +0 -0
  59. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_70_cuda124 +0 -0
  60. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_70_cuda126 +0 -0
  61. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_70_cuda129 +0 -0
  62. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_75_cuda118 +0 -0
  63. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_75_cuda124 +0 -0
  64. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_75_cuda126 +0 -0
  65. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_75_cuda129 +0 -0
  66. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_80_cuda118 +0 -0
  67. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_80_cuda124 +0 -0
  68. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_80_cuda126 +0 -0
  69. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_80_cuda129 +0 -0
  70. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_86_cuda118 +0 -0
  71. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_86_cuda124 +0 -0
  72. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_86_cuda126 +0 -0
  73. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_86_cuda129 +0 -0
  74. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_89_cuda118 +0 -0
  75. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_89_cuda124 +0 -0
  76. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_89_cuda126 +0 -0
  77. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_89_cuda129 +0 -0
  78. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_90_cuda118 +0 -0
  79. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_90_cuda124 +0 -0
  80. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_90_cuda126 +0 -0
  81. fullwave/solver/bins/exponential_attenuation/gpu/3d/fullwave2_3d_exponential_attenuation_gpu_sm_90_cuda129 +0 -0
  82. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_100_cuda129 +0 -0
  83. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_101_cuda129 +0 -0
  84. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_120_cuda129 +0 -0
  85. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_61_cuda118 +0 -0
  86. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_61_cuda124 +0 -0
  87. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_61_cuda126 +0 -0
  88. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_61_cuda129 +0 -0
  89. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_70_cuda118 +0 -0
  90. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_70_cuda124 +0 -0
  91. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_70_cuda126 +0 -0
  92. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_70_cuda129 +0 -0
  93. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_75_cuda118 +0 -0
  94. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_75_cuda124 +0 -0
  95. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_75_cuda126 +0 -0
  96. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_75_cuda129 +0 -0
  97. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_80_cuda118 +0 -0
  98. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_80_cuda124 +0 -0
  99. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_80_cuda126 +0 -0
  100. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_80_cuda129 +0 -0
  101. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_86_cuda118 +0 -0
  102. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_86_cuda124 +0 -0
  103. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_86_cuda126 +0 -0
  104. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_86_cuda129 +0 -0
  105. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_89_cuda118 +0 -0
  106. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_89_cuda124 +0 -0
  107. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_89_cuda126 +0 -0
  108. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_89_cuda129 +0 -0
  109. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_90_cuda118 +0 -0
  110. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_90_cuda124 +0 -0
  111. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_90_cuda126 +0 -0
  112. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_isotropic_multi_gpu_sm_90_cuda129 +0 -0
  113. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_100_cuda129 +0 -0
  114. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_101_cuda129 +0 -0
  115. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_120_cuda129 +0 -0
  116. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_61_cuda118 +0 -0
  117. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_61_cuda124 +0 -0
  118. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_61_cuda126 +0 -0
  119. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_61_cuda129 +0 -0
  120. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_70_cuda118 +0 -0
  121. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_70_cuda124 +0 -0
  122. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_70_cuda126 +0 -0
  123. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_70_cuda129 +0 -0
  124. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_75_cuda118 +0 -0
  125. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_75_cuda124 +0 -0
  126. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_75_cuda126 +0 -0
  127. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_75_cuda129 +0 -0
  128. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_80_cuda118 +0 -0
  129. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_80_cuda124 +0 -0
  130. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_80_cuda126 +0 -0
  131. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_80_cuda129 +0 -0
  132. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_86_cuda118 +0 -0
  133. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_86_cuda124 +0 -0
  134. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_86_cuda126 +0 -0
  135. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_86_cuda129 +0 -0
  136. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_89_cuda118 +0 -0
  137. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_89_cuda124 +0 -0
  138. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_89_cuda126 +0 -0
  139. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_89_cuda129 +0 -0
  140. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_90_cuda118 +0 -0
  141. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_90_cuda124 +0 -0
  142. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_90_cuda126 +0 -0
  143. fullwave/solver/bins/gpu/2d/num_relax=2/fullwave2_2d_2_relax_multi_gpu_sm_90_cuda129 +0 -0
  144. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_100_cuda129 +0 -0
  145. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_101_cuda129 +0 -0
  146. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_120_cuda129 +0 -0
  147. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_61_cuda118 +0 -0
  148. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_61_cuda124 +0 -0
  149. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_61_cuda126 +0 -0
  150. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_61_cuda129 +0 -0
  151. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_70_cuda118 +0 -0
  152. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_70_cuda124 +0 -0
  153. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_70_cuda126 +0 -0
  154. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_70_cuda129 +0 -0
  155. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_75_cuda118 +0 -0
  156. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_75_cuda124 +0 -0
  157. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_75_cuda126 +0 -0
  158. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_75_cuda129 +0 -0
  159. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_80_cuda118 +0 -0
  160. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_80_cuda124 +0 -0
  161. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_80_cuda126 +0 -0
  162. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_80_cuda129 +0 -0
  163. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_86_cuda118 +0 -0
  164. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_86_cuda124 +0 -0
  165. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_86_cuda126 +0 -0
  166. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_86_cuda129 +0 -0
  167. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_89_cuda118 +0 -0
  168. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_89_cuda124 +0 -0
  169. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_89_cuda126 +0 -0
  170. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_89_cuda129 +0 -0
  171. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_90_cuda118 +0 -0
  172. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_90_cuda124 +0 -0
  173. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_90_cuda126 +0 -0
  174. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_isotropic_multi_gpu_sm_90_cuda129 +0 -0
  175. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_100_cuda129 +0 -0
  176. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_101_cuda129 +0 -0
  177. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_120_cuda129 +0 -0
  178. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_61_cuda118 +0 -0
  179. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_61_cuda124 +0 -0
  180. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_61_cuda126 +0 -0
  181. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_61_cuda129 +0 -0
  182. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_70_cuda118 +0 -0
  183. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_70_cuda124 +0 -0
  184. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_70_cuda126 +0 -0
  185. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_70_cuda129 +0 -0
  186. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_75_cuda118 +0 -0
  187. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_75_cuda124 +0 -0
  188. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_75_cuda126 +0 -0
  189. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_75_cuda129 +0 -0
  190. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_80_cuda118 +0 -0
  191. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_80_cuda124 +0 -0
  192. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_80_cuda126 +0 -0
  193. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_80_cuda129 +0 -0
  194. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_86_cuda118 +0 -0
  195. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_86_cuda124 +0 -0
  196. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_86_cuda126 +0 -0
  197. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_86_cuda129 +0 -0
  198. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_89_cuda118 +0 -0
  199. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_89_cuda124 +0 -0
  200. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_89_cuda126 +0 -0
  201. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_89_cuda129 +0 -0
  202. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_90_cuda118 +0 -0
  203. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_90_cuda124 +0 -0
  204. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_90_cuda126 +0 -0
  205. fullwave/solver/bins/gpu/3d/num_relax=2/fullwave2_3d_2_relax_multi_gpu_sm_90_cuda129 +0 -0
  206. fullwave/solver/cuda_utils.py +392 -0
  207. fullwave/solver/input_file_writer.py +853 -0
  208. fullwave/solver/launcher.py +134 -0
  209. fullwave/solver/pml_builder.py +1923 -0
  210. fullwave/solver/solver.py +750 -0
  211. fullwave/solver/utils.py +83 -0
  212. fullwave/source.py +173 -0
  213. fullwave/transducer.py +1003 -0
  214. fullwave/utils/__init__.py +12 -0
  215. fullwave/utils/check_functions.py +48 -0
  216. fullwave/utils/coordinates.py +155 -0
  217. fullwave/utils/memory_tempfile.py +439 -0
  218. fullwave/utils/numerical.py +111 -0
  219. fullwave/utils/plot_utils.py +1122 -0
  220. fullwave/utils/pulse.py +72 -0
  221. fullwave/utils/relaxation_parameters.py +212 -0
  222. fullwave/utils/signal_process.py +197 -0
  223. fullwave25-1.0.7.dist-info/METADATA +292 -0
  224. fullwave25-1.0.7.dist-info/RECORD +225 -0
  225. fullwave25-1.0.7.dist-info/WHEEL +4 -0
@@ -0,0 +1,750 @@
1
+ """solver module."""
2
+
3
+ import logging
4
+ from pathlib import Path
5
+
6
+ import numpy as np
7
+ from numpy.typing import NDArray
8
+
9
+ import fullwave
10
+ from fullwave.solver.input_file_writer import InputFileWriter
11
+ from fullwave.solver.launcher import Launcher
12
+ from fullwave.solver.pml_builder import PMLBuilder, PMLBuilderExponentialAttenuation
13
+ from fullwave.utils import (
14
+ MemoryTempfile,
15
+ check_functions,
16
+ )
17
+
18
+ from .cuda_utils import get_cuda_architecture, retrieve_cuda_version
19
+
20
+ logger = logging.getLogger("__main__." + __name__)
21
+
22
+ COMPATIBLE_CUDA_ARCHITECTURES = [
23
+ "sm_61", # Pascal: GTX 10*0
24
+ "sm_70", # Volta: V100, GTX 1180
25
+ "sm_75", # Turing: RTX 20*0
26
+ "sm_80", # Ampere: A100
27
+ "sm_86", # Ampere: RTX 3080, RTX 3090, etc
28
+ "sm_89", # Ada: RTX 4090, L40, RTX6000
29
+ "sm_90", # Hopper: H100, H200
30
+ "sm_100", # Blackwell: RTX 50 series
31
+ "sm_101", # Blackwell: RTX 50 series
32
+ "sm_120", # Blackwell: RTX 50 series
33
+ ]
34
+
35
+ VERIFIED_CUDA_ARCHITECTURES = [
36
+ "sm_80", # Ampere: A100
37
+ "sm_89", # Ada: RTX 4090, L40, RTX6000
38
+ "sm_120", # Blackwell: RTX 50 series
39
+ ]
40
+
41
+ COMPATIBLE_CUDA_VERSIONS = [
42
+ 11.8,
43
+ 12.4,
44
+ 12.6,
45
+ 12.9,
46
+ ]
47
+
48
+ COMPATIBLE_CUDA_RANGES = [
49
+ (11.8, 12.9),
50
+ ]
51
+
52
+ VERIFIED_CUDA_VERSIONS = [
53
+ 12.6,
54
+ 12.9,
55
+ ]
56
+
57
+ COMPATIBLE_CUDA_VERSIONS_ARCHITECTURES_set = {
58
+ (11.8, "sm_61"),
59
+ (11.8, "sm_70"),
60
+ (11.8, "sm_75"),
61
+ (11.8, "sm_80"),
62
+ (11.8, "sm_86"),
63
+ (11.8, "sm_89"),
64
+ (11.8, "sm_90"),
65
+ # ---
66
+ (12.4, "sm_61"),
67
+ (12.4, "sm_70"),
68
+ (12.4, "sm_75"),
69
+ (12.4, "sm_80"),
70
+ (12.4, "sm_86"),
71
+ (12.4, "sm_89"),
72
+ (12.4, "sm_90"),
73
+ # ---
74
+ (12.6, "sm_61"),
75
+ (12.6, "sm_70"),
76
+ (12.6, "sm_75"),
77
+ (12.6, "sm_80"),
78
+ (12.6, "sm_86"),
79
+ (12.6, "sm_89"),
80
+ (12.6, "sm_90"),
81
+ # ---
82
+ (12.9, "sm_61"),
83
+ (12.9, "sm_70"),
84
+ (12.9, "sm_75"),
85
+ (12.9, "sm_80"),
86
+ (12.9, "sm_86"),
87
+ (12.9, "sm_89"),
88
+ (12.9, "sm_90"),
89
+ (12.9, "sm_100"),
90
+ (12.9, "sm_101"),
91
+ (12.9, "sm_120"),
92
+ }
93
+
94
+
95
+ def _make_cuda_arch_option(*, use_gpu: bool = True) -> str:
96
+ cuda_archtecture_dict = get_cuda_architecture()[0] # Get the first device's architecture
97
+ arch_option = (
98
+ "sm_"
99
+ + str(cuda_archtecture_dict["compute_capability"][0])
100
+ + str(cuda_archtecture_dict["compute_capability"][1])
101
+ )
102
+
103
+ if use_gpu and arch_option not in COMPATIBLE_CUDA_ARCHITECTURES:
104
+ error_msg = (
105
+ f"CUDA architecture {arch_option} is not compatible. "
106
+ f"Please use one of the following architectures: "
107
+ f"{COMPATIBLE_CUDA_ARCHITECTURES}"
108
+ )
109
+ raise ValueError(error_msg)
110
+ if use_gpu and arch_option not in VERIFIED_CUDA_ARCHITECTURES:
111
+ warning_msg = (
112
+ f"Warning: CUDA architecture {arch_option} is not verified. "
113
+ f"Verified architectures are: {VERIFIED_CUDA_ARCHITECTURES}. "
114
+ "The simulation may not run correctly."
115
+ )
116
+ logger.warning(warning_msg)
117
+ return arch_option
118
+
119
+
120
+ def _make_cuda_version_option(*, use_gpu: bool = True) -> tuple[str, float]:
121
+ cuda_version: float = retrieve_cuda_version()
122
+ if use_gpu and cuda_version == -1:
123
+ error_msg = (
124
+ "Could not retrieve CUDA version. "
125
+ "Please ensure that the CUDA toolkit is properly installed."
126
+ )
127
+ raise ValueError(error_msg)
128
+
129
+ # range check
130
+ if use_gpu and not any(start <= cuda_version <= end for start, end in COMPATIBLE_CUDA_RANGES):
131
+ error_msg = (
132
+ f"CUDA version {cuda_version} is not in the compatible ranges: "
133
+ f"{COMPATIBLE_CUDA_RANGES}. Please install a compatible CUDA version."
134
+ )
135
+ raise ValueError(error_msg)
136
+
137
+ # find the a compatible cuda version below the system cuda
138
+ if use_gpu and cuda_version not in COMPATIBLE_CUDA_VERSIONS:
139
+ compatible_versions_below = [v for v in COMPATIBLE_CUDA_VERSIONS if v < cuda_version]
140
+ if compatible_versions_below:
141
+ closest_version = max(compatible_versions_below)
142
+ warning_msg = (
143
+ f"CUDA version {cuda_version} is not in the compatible versions: "
144
+ f"{COMPATIBLE_CUDA_VERSIONS}. "
145
+ f"Using the closest compatible version {closest_version} instead."
146
+ )
147
+ logger.warning(warning_msg)
148
+ cuda_version = closest_version
149
+ else:
150
+ error_msg = (
151
+ f"No compatible CUDA versions found below {cuda_version}. "
152
+ "Please install a compatible CUDA version."
153
+ )
154
+ raise ValueError(error_msg)
155
+
156
+ if use_gpu and cuda_version not in VERIFIED_CUDA_VERSIONS:
157
+ warning_msg = (
158
+ f"Warning: CUDA version {cuda_version} is not in the verified versions: "
159
+ f"{VERIFIED_CUDA_VERSIONS}. The simulation may not run correctly."
160
+ )
161
+ logger.warning(warning_msg)
162
+
163
+ return ("cuda" + str(cuda_version).replace(".", ""), cuda_version)
164
+
165
+
166
+ def _check_compatible_set(cuda_version: float, cuda_arch: str) -> bool:
167
+ return (cuda_version, cuda_arch) in COMPATIBLE_CUDA_VERSIONS_ARCHITECTURES_set
168
+
169
+
170
+ def _retrieve_fullwave_simulation_path(
171
+ *,
172
+ use_gpu: bool = True,
173
+ is_3d: bool = False,
174
+ use_exponential_attenuation: bool = False,
175
+ use_isotropic_relaxation: bool = True,
176
+ n_relax_mechanisms: int = 2,
177
+ ) -> Path:
178
+ arch_option = _make_cuda_arch_option(use_gpu=use_gpu)
179
+ cuda_version_option, cuda_version = _make_cuda_version_option(use_gpu=use_gpu)
180
+ isotropic_str = "_isotropic" if use_isotropic_relaxation else ""
181
+
182
+ _check_compatible_set(
183
+ cuda_version=cuda_version,
184
+ cuda_arch=arch_option,
185
+ )
186
+ if use_exponential_attenuation:
187
+ if is_3d and use_gpu:
188
+ path_fullwave_simulation_bin = (
189
+ Path(__file__).parent
190
+ / "bins"
191
+ / "exponential_attenuation"
192
+ / "gpu"
193
+ / "3d"
194
+ / f"fullwave2_3d_exponential_attenuation_gpu_{arch_option}_{cuda_version_option}"
195
+ )
196
+ elif not is_3d and use_gpu:
197
+ path_fullwave_simulation_bin = (
198
+ Path(__file__).parent
199
+ / "bins"
200
+ / "exponential_attenuation"
201
+ / "gpu"
202
+ / "2d"
203
+ / f"fullwave2_2d_exponential_attenuation_gpu_{arch_option}_{cuda_version_option}"
204
+ )
205
+ else:
206
+ error_msg = (
207
+ "Currently, exponential attenuation model is only supported in GPU mode. "
208
+ "Please use GPU mode for exponential attenuation simulations."
209
+ )
210
+ raise NotImplementedError(error_msg)
211
+ elif is_3d:
212
+ if use_gpu:
213
+ if n_relax_mechanisms != 2:
214
+ error_msg = (
215
+ "Currently, only 2 relaxation mechanisms are supported in 3D simulations. "
216
+ "Please set n_relax_mechanisms to 2 for 3D simulations."
217
+ )
218
+ raise NotImplementedError(error_msg)
219
+
220
+ path_fullwave_simulation_bin = (
221
+ Path(__file__).parent
222
+ / "bins"
223
+ / "gpu"
224
+ / "3d"
225
+ / f"num_relax={n_relax_mechanisms}"
226
+ / (
227
+ f"fullwave2_3d_{n_relax_mechanisms}_relax{isotropic_str}"
228
+ f"_multi_gpu_{arch_option}_{cuda_version_option}"
229
+ )
230
+ )
231
+ else:
232
+ path_fullwave_simulation_bin = (
233
+ Path(__file__).parent / "bins" / "cpu" / "3d" / "fullwave2_3d_2_relax_multi_cpu"
234
+ )
235
+ error_msg = (
236
+ "Currently, 3D simulation is not supported in CPU mode. "
237
+ "Please use GPU mode for 3D simulations."
238
+ )
239
+ raise NotImplementedError(error_msg)
240
+ else: # noqa: PLR5501
241
+ if use_gpu:
242
+ path_fullwave_simulation_bin = (
243
+ Path(__file__).parent
244
+ / "bins"
245
+ / "gpu"
246
+ / "2d"
247
+ / f"num_relax={n_relax_mechanisms}"
248
+ / (
249
+ f"fullwave2_2d_{n_relax_mechanisms}_relax{isotropic_str}"
250
+ f"_multi_gpu_{arch_option}_{cuda_version_option}"
251
+ )
252
+ )
253
+ else:
254
+ path_fullwave_simulation_bin = (
255
+ Path(__file__).parent / "bins" / "cpu" / "2d" / "fullwave2_2d_2_relax_multi_cpu"
256
+ )
257
+ error_msg = (
258
+ "Currently, 2D simulation is not supported in CPU mode. "
259
+ "Please use GPU mode for 3D simulations."
260
+ )
261
+ raise NotImplementedError(error_msg)
262
+ return path_fullwave_simulation_bin
263
+
264
+
265
+ class Solver:
266
+ """Solver for fullwave simulation tasks.
267
+
268
+ The Solver class manages the setup, input validation, and execution of a fullwave simulation.
269
+ It configures the simulation environment based on the provided
270
+ grid, medium, source, sensor, or transducer,
271
+ generates the required input files, and runs the simulation executable.
272
+ """
273
+
274
+ def __init__( # noqa: PLR0912, PLR0915, C901
275
+ self,
276
+ work_dir: Path,
277
+ grid: fullwave.Grid,
278
+ medium: fullwave.Medium,
279
+ source: fullwave.Source | None = None,
280
+ sensor: fullwave.Sensor | None = None,
281
+ *,
282
+ transducer: fullwave.Transducer | None = None,
283
+ path_fullwave_simulation_bin: Path | None = None,
284
+ use_pml: bool = True,
285
+ m_spatial_order: int = 8,
286
+ pml_layer_thickness_px: int | None = None,
287
+ n_transition_layer: int | None = None,
288
+ run_on_memory: bool = False,
289
+ use_gpu: bool = True,
290
+ use_exponential_attenuation: bool = False,
291
+ use_isotropic_relaxation: bool = True,
292
+ ) -> None:
293
+ """Initialize a Solver instance for the fullwave simulation.
294
+
295
+ This initializer sets up the simulation
296
+ by assigning the provided grid, medium, source, sensor, and
297
+ transducer (if provided).
298
+ It validates input consistency, generates necessary working directories,
299
+ and prepares the input generator and simulation launcher.
300
+
301
+ Parameters
302
+ ----------
303
+ work_dir : (Path)
304
+ Directory to store simulation data and temporary files.
305
+ grid : (fullwave.Grid)
306
+ Instance representing the simulation computational grid.
307
+ medium : (fullwave.MediumRelaxationMaps)
308
+ Instance representing the physical medium where simulations occur.
309
+ source : (fullwave.Source, optional)
310
+ Source defining the simulation input. Optional if a transducer is given.
311
+ sensor : (fullwave.Sensor, optional)
312
+ Sensor defining the simulation output. Optional if a transducer is given.
313
+ transducer : (fullwave.Transducer, optional)
314
+ Transducer instance combining source and sensor information.
315
+ Must not be provided together with source or sensor.
316
+ path_fullwave_simulation_bin : (Path, optional):
317
+ Path to the fullwave simulation binary executable.
318
+ Defaults to a binary in the 'bins' directory relative to this file.
319
+ use_pml : (bool, optional)
320
+ Flag indicating whether to use Perfectly Matched Layer (PML) boundaries.
321
+ Defaults to True.
322
+ m_spatial_order : int, optional
323
+ fullwave simulation's spatial order (default is 8).
324
+ It depends on the fullwave simulation binary version.
325
+ Fullwave simulation has 2M th order spatial accuracy and fourth order accuracy in time.
326
+ see Pinton, G. (2021) http://arxiv.org/abs/2106.11476 for more detail.
327
+ pml_layer_thickness_px : int, optional
328
+ PML layer thickness (default is 3 ppw).
329
+ n_transition_layer : int, optional
330
+ Number of transition layers (default is 3 ppw).
331
+ run_on_memory : bool, optional
332
+ Flag indicating whether to run the simulation in memory.
333
+ If True, a temporary directory is created in memory.
334
+ it uses the /run/user/{uid} directory if available.
335
+ the maximum size depends on the system configuration.
336
+ if needed, increase the size of /run/user/{uid} using the following website:
337
+ https://wiki.archlinux.org/title/Profile-sync-daemon#Allocate_more_memory_to_accommodate_profiles_in_/run/user/xxxx
338
+ If False, a temporary directory is created on disk.
339
+ Defaults to False.
340
+ use_gpu : bool, optional
341
+ Whether to use GPU for the simulation.
342
+ Currently, only GPU version is supported.
343
+ Defaults to True.
344
+ In the future support the simulation will be run on multi-core CPU version if False.
345
+ use_exponential_attenuation : bool, optional
346
+ Whether to use exponential attenuation model.
347
+ Defaults to False. If True, the simulation will use exponential attenuation.
348
+ Exponential attenuation is memory efficient and faster
349
+ than the relaxation mechanism model at the cost of attenuation accuracy.
350
+ The exponential attenuation model does not use relaxation mechanisms
351
+ and does not supports frequency power law attenuation.
352
+ use_isotropic_relaxation : bool, optional
353
+ Whether to use isotropic relaxation mechanisms for attenuation modeling
354
+ to reduce memory usage while retaining accuracy.
355
+ For 2D it will reduce the GPU memory usage by approximately 15%.
356
+ For 3D it will reduce the GPU memory usage by approximately 30%
357
+ and CPU memory usage by approximately 20%.
358
+ This option omits the anisotropic relaxation mechanisms to model the attenuation.
359
+ We usually recommend using isotropic relaxation mechanisms
360
+ unless the anisotropic attenuation is required for the simulation.
361
+
362
+ Raises
363
+ ------
364
+ ValueError:
365
+ If neither a source nor a transducer is provided,
366
+ if neither a sensor nor a transducer is provided,
367
+ or if both source and transducer (or sensor
368
+ and transducer) are defined simultaneously.
369
+
370
+ """
371
+ # type hints
372
+ self.source: fullwave.Source
373
+ self.sensor: fullwave.Sensor
374
+ self.medium: fullwave.Medium
375
+ self.grid: fullwave.Grid
376
+ self.input_file_writer: InputFileWriter
377
+
378
+ if run_on_memory:
379
+ message = (
380
+ "\nrun_on_memory is set to True."
381
+ "\nThis simulation will be executed in RAM-based temporary directory. "
382
+ "\n"
383
+ "\nIt speeds up the simulation significantly, "
384
+ "\nhowever you need to ensure that sufficient memory"
385
+ "is available for the simulation. "
386
+ "\n"
387
+ "\nIf you encounter memory issues, consider setting run_on_memory to False. "
388
+ "\n"
389
+ "\nThe temporary directory will be created in /run/user/{uid} if available. "
390
+ f"\nThe simulation output will not be saved in {work_dir}. "
391
+ "\n"
392
+ "\nThe maximum size depends on the system configuration. "
393
+ "\nIf needed, increase the size of /run/user/{uid} using the following website: "
394
+ "\nhttps://wiki.archlinux.org/title/Profile-sync-daemon#Allocate_more_memory_to_accommodate_profiles_in_/run/user/xxxx"
395
+ "\n"
396
+ )
397
+ logger.warning(message)
398
+ self.tempfile = MemoryTempfile(
399
+ preferred_paths=["/run/user/{uid}"],
400
+ remove_paths=["/dev/shm", "/run/shm"], # noqa: S108
401
+ additional_paths=["/var/run"],
402
+ filesystem_types=["tmpfs"],
403
+ fallback=True,
404
+ )
405
+ self.tempdir = self.tempfile.TemporaryDirectory()
406
+ self.work_dir = Path(self.tempdir.name)
407
+ else:
408
+ self.work_dir = work_dir
409
+ self.work_dir.mkdir(exist_ok=True, parents=True)
410
+
411
+ self.grid = grid
412
+ self.is_3d = grid.is_3d
413
+ self.use_gpu = use_gpu
414
+ self.use_exponential_attenuation = use_exponential_attenuation
415
+ self.use_isotropic_relaxation = use_isotropic_relaxation
416
+
417
+ self.n_relax_mechanisms = medium.n_relaxation_mechanisms
418
+
419
+ if path_fullwave_simulation_bin is None:
420
+ path_fullwave_simulation_bin = _retrieve_fullwave_simulation_path(
421
+ use_gpu=use_gpu,
422
+ is_3d=self.is_3d,
423
+ use_exponential_attenuation=self.use_exponential_attenuation,
424
+ use_isotropic_relaxation=use_isotropic_relaxation,
425
+ n_relax_mechanisms=self.n_relax_mechanisms,
426
+ )
427
+ else:
428
+ check_functions.check_path_exists(path_fullwave_simulation_bin)
429
+
430
+ self._check_input(
431
+ grid,
432
+ medium,
433
+ source,
434
+ sensor,
435
+ transducer,
436
+ path_fullwave_simulation_bin,
437
+ )
438
+
439
+ self.medium = medium
440
+ self.use_pml = use_pml
441
+ if not use_pml:
442
+ pml_layer_thickness_px = 0
443
+ n_transition_layer = 0
444
+
445
+ if pml_layer_thickness_px is None:
446
+ pml_layer_thickness_px = self.grid.ppw * 3
447
+ if n_transition_layer is None:
448
+ n_transition_layer = self.grid.ppw * 3
449
+
450
+ if source is not None:
451
+ self.source = source
452
+ elif transducer is not None:
453
+ self.source = transducer.source
454
+ else:
455
+ error_msg = "source or transducer must be provided"
456
+ raise ValueError(error_msg)
457
+
458
+ if sensor is not None:
459
+ self.sensor = sensor
460
+ elif transducer is not None:
461
+ self.sensor = transducer.sensor
462
+ else:
463
+ error_msg = "sensor or transducer must be provided"
464
+ raise ValueError(error_msg)
465
+
466
+ self.transducer: fullwave.Transducer | None = transducer
467
+
468
+ self.path_fullwave_simulation_bin = path_fullwave_simulation_bin
469
+
470
+ self.fullwave_launcher = Launcher(
471
+ path_fullwave_simulation_bin,
472
+ is_3d=self.is_3d,
473
+ use_gpu=self.use_gpu,
474
+ )
475
+
476
+ if use_exponential_attenuation:
477
+ self.pml_builder = PMLBuilderExponentialAttenuation(
478
+ grid=self.grid,
479
+ medium=self.medium,
480
+ source=self.source,
481
+ sensor=self.sensor,
482
+ m_spatial_order=m_spatial_order,
483
+ n_pml_layer=pml_layer_thickness_px,
484
+ )
485
+ else:
486
+ self.pml_builder = PMLBuilder(
487
+ grid=self.grid,
488
+ medium=self.medium,
489
+ source=self.source,
490
+ sensor=self.sensor,
491
+ m_spatial_order=m_spatial_order,
492
+ n_pml_layer=pml_layer_thickness_px,
493
+ n_transition_layer=n_transition_layer,
494
+ use_isotropic_relaxation=use_isotropic_relaxation,
495
+ )
496
+
497
+ @staticmethod
498
+ def _check_input(
499
+ grid: fullwave.Grid,
500
+ medium: fullwave.Medium,
501
+ source: fullwave.Source | None,
502
+ sensor: fullwave.Sensor | None,
503
+ transducer: fullwave.Transducer | None,
504
+ path_fullwave_simulation_bin: Path,
505
+ ) -> None:
506
+ """Check the input values.
507
+
508
+ Raises
509
+ ------
510
+ ValueError
511
+ If neither source nor transducer is defined,
512
+ if neither sensor nor transducer is defined,
513
+ or if both source and transducer (or sensor and transducer) are defined simultaneously.
514
+
515
+ """
516
+ # check if the source and sensor have value or transducer has value
517
+ if source is None and transducer is None:
518
+ error_msg = "source or transducer must be defined"
519
+ raise ValueError(error_msg)
520
+ if sensor is None and transducer is None:
521
+ error_msg = "sensor or transducer must be defined"
522
+ raise ValueError(error_msg)
523
+ if transducer is not None and source is not None:
524
+ error_msg = "source and transducer cannot be defined at the same time"
525
+ raise ValueError(error_msg)
526
+
527
+ if transducer is not None and sensor is not None:
528
+ warning_msg = (
529
+ "sensor and transducer are defined at the same time. "
530
+ "It uses sensor instead of transducer.sensor."
531
+ )
532
+ logger.warning(warning_msg)
533
+
534
+ if source is not None and transducer is None:
535
+ check_functions.check_instance(source, fullwave.Source)
536
+ if sensor is not None and transducer is None:
537
+ check_functions.check_instance(sensor, fullwave.Sensor)
538
+ if transducer is not None:
539
+ check_functions.check_instance(transducer, fullwave.Transducer)
540
+
541
+ # validate the instances
542
+ check_functions.check_instance(grid, fullwave.Grid)
543
+ check_functions.check_instance(medium, fullwave.Medium)
544
+
545
+ if source is not None:
546
+ grid_shape = (grid.nx, grid.ny, grid.nz) if grid.is_3d else (grid.nx, grid.ny)
547
+ source.validate(grid_shape=grid_shape)
548
+ if sensor is not None:
549
+ grid_shape = (grid.nx, grid.ny, grid.nz) if grid.is_3d else (grid.nx, grid.ny)
550
+ sensor.validate(grid_shape=grid_shape)
551
+
552
+ error_msg = f"{path_fullwave_simulation_bin} does not exist"
553
+ assert path_fullwave_simulation_bin.exists(), error_msg
554
+
555
+ @staticmethod
556
+ def _reshape_sensor_data(
557
+ raw_sensor_output: NDArray[np.float64],
558
+ sensor: fullwave.Sensor,
559
+ ) -> NDArray[np.float64]:
560
+ """Reshape the raw sensor output data.
561
+
562
+ Parameters
563
+ ----------
564
+ raw_sensor_output: NDArray[np.float64]
565
+ The raw sensor output data from the simulation. [nt*ncoordsout, 1]
566
+ sensor: fullwave.Sensor
567
+ The sensor object used in the simulation.
568
+
569
+ Returns
570
+ -------
571
+ NDArray[np.float64]: The reshaped sensor output data. [ncoordsout, nt]
572
+
573
+ """
574
+ return raw_sensor_output.reshape(-1, sensor.n_sensors).T
575
+
576
+ def run(
577
+ self,
578
+ simulation_dir_name: str | Path = "txrx_0",
579
+ *,
580
+ is_static_map: bool = False,
581
+ recalculate_pml: bool = True,
582
+ record_whole_domain: bool = False,
583
+ sampling_modulus_time_whole_domain: int = 1,
584
+ load_results: bool = True,
585
+ ) -> NDArray[np.float64] | Path:
586
+ r"""Run the fullwave simulation and return the result as a NumPy array.
587
+
588
+ This method generates the simulation input via the input generator,
589
+ launches the simulation through the external executable,
590
+ and retrieves the output data.
591
+ The simulation directory may be customized,
592
+ and additional parameters control the simulation behavior
593
+ such as static map generation
594
+ and recalculation of the Perfectly Matched Layer (PML).
595
+
596
+ Parameters
597
+ ----------
598
+ simulation_dir_name : Path
599
+ The directory name where simulation files will be stored.
600
+ The directory will be created under the work directory.
601
+ This is the directory, where Fullwave2 will be executed
602
+ is_static_map : bool
603
+ Flag indicating if a static map is used.\n
604
+ static map is a map that does not change
605
+ during the transmission events such as plane wave and synthetic aperture sequence.\n
606
+ non-static map is a map that changes
607
+ during the transmission events such as walking aperture implementation
608
+ for focused transmit implementation.\n
609
+ if it is a static map, the input files are stored inside the work directory and
610
+ symbolic links are created in the simulation directory.\n
611
+ recalculate_pml : bool
612
+ Flag indicating whether to re-calculate PML parameters.
613
+ default is True.
614
+ you can store the value false
615
+ if you are using the same PML parameters in case of static map simulation.
616
+ set True if you are using different PML parameters for each transmit event
617
+ such as walking aperture.
618
+ set False if you are using the same PML parameters for each transmit event
619
+ such as plane wave
620
+ AND this is the second or later transmit event.
621
+ record_whole_domain : bool
622
+ Flag indicating whether to record the whole domain.
623
+ If True, the simulation will record data for the entire grid.
624
+ sampling_modulus_time_whole_domain : int
625
+ Sampling modulus in time. Default is 1 (record at every time step).
626
+ Changing this value to n will record the pressure every n time steps.
627
+ It reduces the size of the output data.
628
+ This will only change the sensor class if record_whole_domain is True.
629
+ If record_whole_domain is False,
630
+ the sampling sampling_modulus_time_whole_domain is ignored.
631
+ load_results : bool
632
+ Whether to load the results from genout.dat after the simulation.
633
+ Default is True. If set to False, it returns the genout.dat file path instead.
634
+
635
+ Returns
636
+ -------
637
+ NDArray[np.float64]: The simulation output data as a NumPy array.
638
+
639
+ """
640
+ # self._save_data_for_beamforming()
641
+
642
+ # pml setup
643
+ extended_medium = self.pml_builder.run(use_pml=self.use_pml)
644
+ if sampling_modulus_time_whole_domain != 1 and record_whole_domain is False:
645
+ warning_msg = (
646
+ f"sampling_modulus_time_whole_domain value "
647
+ f"{sampling_modulus_time_whole_domain} is ignored "
648
+ "when record_whole_domain is False. "
649
+ f"The sampling_modulus_time {self.sensor.sampling_modulus_time} "
650
+ "in the sensor object is prioritized."
651
+ )
652
+ logger.warning(warning_msg)
653
+
654
+ sensor_mask: NDArray[np.bool_]
655
+ if record_whole_domain:
656
+ if self.is_3d:
657
+ sensor_mask = np.zeros(
658
+ (
659
+ self.pml_builder.extended_grid.nx,
660
+ self.pml_builder.extended_grid.ny,
661
+ self.pml_builder.extended_grid.nz,
662
+ ),
663
+ dtype=bool,
664
+ )
665
+ else:
666
+ sensor_mask = np.zeros(
667
+ (self.pml_builder.extended_grid.nx, self.pml_builder.extended_grid.ny),
668
+ dtype=bool,
669
+ )
670
+ sensor_mask[:, :] = True
671
+ sensor = fullwave.Sensor(
672
+ mask=sensor_mask,
673
+ sampling_modulus_time=sampling_modulus_time_whole_domain,
674
+ )
675
+ else:
676
+ sensor = self.pml_builder.extended_sensor
677
+
678
+ input_file_writer = InputFileWriter(
679
+ work_dir=self.work_dir,
680
+ grid=self.pml_builder.extended_grid,
681
+ medium=extended_medium,
682
+ source=self.pml_builder.extended_source,
683
+ sensor=sensor,
684
+ path_fullwave_simulation_bin=self.path_fullwave_simulation_bin,
685
+ use_exponential_attenuation=self.use_exponential_attenuation,
686
+ use_isotropic_relaxation=self.use_isotropic_relaxation,
687
+ )
688
+ simulation_dir = input_file_writer.run(
689
+ simulation_dir_name,
690
+ is_static_map=is_static_map,
691
+ recalculate_pml=recalculate_pml,
692
+ )
693
+ sim_result = self.fullwave_launcher.run(
694
+ simulation_dir,
695
+ load_results=load_results,
696
+ )
697
+ if load_results:
698
+ return self._reshape_sensor_data(
699
+ sim_result,
700
+ sensor=sensor,
701
+ )
702
+ # if load_results is False, return the raw result
703
+ # which is a list of file names
704
+ return sim_result
705
+
706
+ def print_info(self) -> None:
707
+ """Print the Solver instance information."""
708
+ print(str(self))
709
+
710
+ def summary(self) -> None:
711
+ """Alias for print_info."""
712
+ self.print_info()
713
+
714
+ def __str__(self) -> str:
715
+ """Return a string representation of the Solver instance.
716
+
717
+ Returns
718
+ -------
719
+ str
720
+ A formatted string containing the Solver's attributes.
721
+
722
+ """
723
+ return (
724
+ f"\nSolver(\n"
725
+ f" work_dir={self.work_dir}\n\n"
726
+ f" medium={self.medium}\n"
727
+ f" source={self.source}\n"
728
+ f" sensor={self.sensor}\n"
729
+ f" transducer={self.transducer}\n\n"
730
+ f" path_fullwave_simulation_bin={self.path_fullwave_simulation_bin}\n"
731
+ f" use_pml={self.use_pml}\n"
732
+ f" pml_thickness_px={self.pml_builder.n_pml_layer}\n"
733
+ f" n_transition_layer={self.pml_builder.n_transition_layer}\n"
734
+ f" is_3d={self.is_3d}\n"
735
+ f" use_gpu={self.use_gpu}\n"
736
+ f" use_exponential_attenuation={self.use_exponential_attenuation}\n"
737
+ f" use_isotropic_relaxation={self.use_isotropic_relaxation}\n"
738
+ f")"
739
+ )
740
+
741
+ def __repr__(self) -> str:
742
+ """Return a string representation of the Solver instance.
743
+
744
+ Returns
745
+ -------
746
+ str
747
+ A formatted string containing the Solver's attributes.
748
+
749
+ """
750
+ return self.__str__()