src.acoustools.HighLevel.Contexts
1from acoustools.Solvers import wgs 2from acoustools.Utilities import create_points, TRANSDUCERS, transducers 3from acoustools.Visualiser import Visualise, ABC 4from acoustools.Levitator import LevitatorController 5 6from acoustools.Mesh import load_scatterer, translate 7from acoustools.BEM import get_cache_or_compute_H, propagate_BEM_pressure, compute_E 8 9import torch 10from torch import Tensor 11 12from typing import Iterable, Self 13 14from vedo.mesh import Mesh 15 16from vedo.mesh import Mesh 17 18 19class AcousToolsContext(): 20 21 def __init__(self, origin:Iterable|Tensor=(0,0,0)) -> None: 22 ''' 23 Base Class for AcousTools Context Objects \n 24 :param origin: The position of the origin for the setup \n 25 26 Should be used in a `with` block 27 ''' 28 29 if type(origin) is not Tensor: 30 self.origin: Tensor = create_points(1,1,origin[0], origin[1], origin[2]) 31 32 self.lev = None 33 34 self.solution=None 35 36 def __enter__(self) -> Self: 37 return self 38 39 def __exit__(self, exc_type, exc_value, traceback) -> None: 40 if self.lev is not None: 41 self.lev.disconnect() 42 43 44 45class TopBottomContext(AcousToolsContext): 46 47 48 def __init__(self, origin:Iterable|Tensor=(0,0,0), default_solver=wgs) -> None: 49 ''' 50 AcousTools Context Objects for 2 boards with a seperation of 23.65cm\n 51 :param origin: The position of the origin for the setup \n 52 :param default_solver: The solver to use when creating a focus, default wgs 53 54 Should be used in a `with` block eg 55 ``` 56 from acoustools.HighLevel import TopBottomContext 57 58 with TopBottomContext() as ctx: 59 ctx.create_focus() 60 ctx.send_solution() 61 ``` 62 ''' 63 64 super().__init__(origin) 65 66 self.solver = default_solver 67 self.board: Tensor = TRANSDUCERS 68 69 70 def create_focus(self, location:None|Tensor|Iterable = None) -> None: 71 ''' 72 Create a focus at `location` using the default solver defined in class creation and stores the result in the object. \n 73 The user does not need to know how the focus is created or what the ouput of the computation is \n 74 Should be called before `send_solution` or `visualise` 75 :param location: The location of the focus 76 ''' 77 78 if type(location) not in (None, Tensor, Iterable): 79 raise TypeError("Locations should be one of None, Tensor, Iterable") 80 81 if location is None: 82 location: Tensor = self.origin 83 84 if type(location) is not Tensor: 85 location: Tensor = create_points(1,1,location[0], location[1], location[2]) 86 87 self.solution = self.solver(location, board = self.board) 88 89 def visualise(self, size:float=0.03, origin:Tensor=None, plane:str='xz') -> None: 90 ''' 91 Visualises the sound field that has been previously computed, see `acoustools.Visualise.Visualiser` for parameter details \n 92 :param size: Size of the visualisation window from the origin (window will be 2*size) 93 :param origin: Central point of the visualisation 94 :param plane: Plane to visulaise in 95 ''' 96 if self.solution is None: 97 raise ValueError("No solution found, call `create_focus` before use") 98 abc: tuple[Tensor] = ABC(size, origin=origin, plane=plane) 99 Visualise(*abc, self.solution) 100 101 102 def send_solution(self, ids=(1000,999)) -> None: 103 ''' 104 Sends the solution to a connected physical device 105 :param ids: The ids for the device connected 106 ''' 107 if self.solution is None: 108 raise ValueError("No solution found, call `create_focus` before use") 109 110 if self.lev is None: self.lev = LevitatorController(ids=ids) 111 112 self.lev.levitate(self.solution) 113 114 115 116class TopWithReflectorContext(AcousToolsContext): 117 118 119 def __init__(self, origin:Iterable|Tensor=(0,0,0), default_solver=wgs, path:str='../BEMMedia/', reflector_path:str = './flat-lam2.stl', height:float = 0.12) -> None: 120 ''' 121 AcousTools Context Objects for 1 board above a reflector\n 122 :param origin: The position of the origin for the setup \n 123 :param default_solver: The solver to use when creating a focus, default wgs 124 :param path: The path where BEM Medis is stored, this folder should have a subfolder called BEMCache 125 :param reflector_path: The Path to the reflector to use 126 :param height: The seperation to use 127 128 Should be used in a `with` block eg 129 ``` 130 from acoustools.HighLevel import TopWithReflectorContext 131 132 with TopWithReflectorContext() as ctx: 133 tb.create_focus() 134 tb.send_solution() 135 ``` 136 ''' 137 super().__init__(origin) 138 139 self.solver = default_solver 140 self.board: Tensor = transducers(16, z=height/2) 141 142 self.path: str = path 143 self.reflector: Mesh = load_scatterer(path + reflector_path) 144 translate(self.reflector, dz=-1*height/2) 145 146 147 self.H: Tensor = get_cache_or_compute_H(self.reflector, self.board, path=path) 148 149 150 def create_focus(self, location:None|Tensor|Iterable = None) -> None: 151 ''' 152 Create a focus at `location` using the default solver defined in class creation and stores the result in the object. \n 153 The user does not need to know how the focus is created or what the ouput of the computation is \n 154 Should be called before `send_solution` or `visualise` 155 :param location: The location of the focus 156 ''' 157 if location is None: 158 location: Tensor = self.origin 159 160 if type(location) is not Tensor: 161 location: Tensor = create_points(1,1,location[0], location[1], location[2]) 162 163 164 E: Tensor = compute_E(self.reflector, location, self.board, path=self.path, H=self.H) 165 self.solution = self.solver(location, board = self.board, A=E) 166 167 168 def visualise(self, size:float=0.03, origin:Tensor=None, plane:str='xz') -> None: 169 ''' 170 Visualises the sound field that has been previously computed, see `acoustools.Visualise.Visualiser` for parameter details \n 171 :param size: Size of the visualisation window from the origin (window will be 2*size) 172 :param origin: Central point of the visualisation 173 :param plane: Plane to visulaise in 174 ''' 175 abc: tuple[Tensor] = ABC(size, origin=origin, plane=plane) 176 Visualise(*abc, self.solution, colour_functions=[propagate_BEM_pressure], colour_function_args=[{'path':self.path, "H":self.H, 'board':self.board, 'scatterer':self.reflector}]) 177 178 def send_solution(self, ids=(1000)) -> None: 179 ''' 180 Sends the solution to a connected physical device 181 :param ids: The ids for the device connected 182 ''' 183 if self.lev is None: self.lev = LevitatorController(ids=ids) 184 185 self.lev.levitate(self.solution) 186 187 188 189class BottomWithReflectorContext(TopWithReflectorContext): 190 191 def __init__(self, origin:Iterable|Tensor=(0,0,0), default_solver=wgs, path='../BEMMedia/', reflector_path = './flat-lam2.stl', height = 0.12) -> None: 192 ''' 193 AcousTools Context Objects for 1 board below a reflector\n 194 :param origin: The position of the origin for the setup \n 195 :param default_solver: The solver to use when creating a focus, default wgs 196 :param path: The path where BEM Medis is stored, this folder should have a subfolder called BEMCache 197 :param reflector_path: The Path to the reflector to use 198 :param height: The seperation to use 199 200 Should be used in a `with` block eg 201 ``` 202 from acoustools.HighLevel import TopWithReflectorContext 203 204 with TopWithReflectorContext() as ctx: 205 tb.create_focus() 206 tb.send_solution() 207 ``` 208 ''' 209 super().__init__(origin, default_solver, path, reflector_path, height) 210 211 self.board: Tensor = transducers(16, z=-1*height/2) 212 213 self.reflector: Mesh = load_scatterer(path + reflector_path) 214 translate(self.reflector, dz=height/2) 215 216 217 self.H: Tensor = get_cache_or_compute_H(self.reflector, self.board, path=path)
20class AcousToolsContext(): 21 22 def __init__(self, origin:Iterable|Tensor=(0,0,0)) -> None: 23 ''' 24 Base Class for AcousTools Context Objects \n 25 :param origin: The position of the origin for the setup \n 26 27 Should be used in a `with` block 28 ''' 29 30 if type(origin) is not Tensor: 31 self.origin: Tensor = create_points(1,1,origin[0], origin[1], origin[2]) 32 33 self.lev = None 34 35 self.solution=None 36 37 def __enter__(self) -> Self: 38 return self 39 40 def __exit__(self, exc_type, exc_value, traceback) -> None: 41 if self.lev is not None: 42 self.lev.disconnect()
22 def __init__(self, origin:Iterable|Tensor=(0,0,0)) -> None: 23 ''' 24 Base Class for AcousTools Context Objects \n 25 :param origin: The position of the origin for the setup \n 26 27 Should be used in a `with` block 28 ''' 29 30 if type(origin) is not Tensor: 31 self.origin: Tensor = create_points(1,1,origin[0], origin[1], origin[2]) 32 33 self.lev = None 34 35 self.solution=None
Base Class for AcousTools Context Objects
Parameters
- origin: The position of the origin for the setup
Should be used in a with block
46class TopBottomContext(AcousToolsContext): 47 48 49 def __init__(self, origin:Iterable|Tensor=(0,0,0), default_solver=wgs) -> None: 50 ''' 51 AcousTools Context Objects for 2 boards with a seperation of 23.65cm\n 52 :param origin: The position of the origin for the setup \n 53 :param default_solver: The solver to use when creating a focus, default wgs 54 55 Should be used in a `with` block eg 56 ``` 57 from acoustools.HighLevel import TopBottomContext 58 59 with TopBottomContext() as ctx: 60 ctx.create_focus() 61 ctx.send_solution() 62 ``` 63 ''' 64 65 super().__init__(origin) 66 67 self.solver = default_solver 68 self.board: Tensor = TRANSDUCERS 69 70 71 def create_focus(self, location:None|Tensor|Iterable = None) -> None: 72 ''' 73 Create a focus at `location` using the default solver defined in class creation and stores the result in the object. \n 74 The user does not need to know how the focus is created or what the ouput of the computation is \n 75 Should be called before `send_solution` or `visualise` 76 :param location: The location of the focus 77 ''' 78 79 if type(location) not in (None, Tensor, Iterable): 80 raise TypeError("Locations should be one of None, Tensor, Iterable") 81 82 if location is None: 83 location: Tensor = self.origin 84 85 if type(location) is not Tensor: 86 location: Tensor = create_points(1,1,location[0], location[1], location[2]) 87 88 self.solution = self.solver(location, board = self.board) 89 90 def visualise(self, size:float=0.03, origin:Tensor=None, plane:str='xz') -> None: 91 ''' 92 Visualises the sound field that has been previously computed, see `acoustools.Visualise.Visualiser` for parameter details \n 93 :param size: Size of the visualisation window from the origin (window will be 2*size) 94 :param origin: Central point of the visualisation 95 :param plane: Plane to visulaise in 96 ''' 97 if self.solution is None: 98 raise ValueError("No solution found, call `create_focus` before use") 99 abc: tuple[Tensor] = ABC(size, origin=origin, plane=plane) 100 Visualise(*abc, self.solution) 101 102 103 def send_solution(self, ids=(1000,999)) -> None: 104 ''' 105 Sends the solution to a connected physical device 106 :param ids: The ids for the device connected 107 ''' 108 if self.solution is None: 109 raise ValueError("No solution found, call `create_focus` before use") 110 111 if self.lev is None: self.lev = LevitatorController(ids=ids) 112 113 self.lev.levitate(self.solution)
49 def __init__(self, origin:Iterable|Tensor=(0,0,0), default_solver=wgs) -> None: 50 ''' 51 AcousTools Context Objects for 2 boards with a seperation of 23.65cm\n 52 :param origin: The position of the origin for the setup \n 53 :param default_solver: The solver to use when creating a focus, default wgs 54 55 Should be used in a `with` block eg 56 ``` 57 from acoustools.HighLevel import TopBottomContext 58 59 with TopBottomContext() as ctx: 60 ctx.create_focus() 61 ctx.send_solution() 62 ``` 63 ''' 64 65 super().__init__(origin) 66 67 self.solver = default_solver 68 self.board: Tensor = TRANSDUCERS
AcousTools Context Objects for 2 boards with a seperation of 23.65cm
Parameters
origin: The position of the origin for the setup
default_solver: The solver to use when creating a focus, default wgs
Should be used in a with block eg
from acoustools.HighLevel import TopBottomContext
with TopBottomContext() as ctx:
ctx.create_focus()
ctx.send_solution()
71 def create_focus(self, location:None|Tensor|Iterable = None) -> None: 72 ''' 73 Create a focus at `location` using the default solver defined in class creation and stores the result in the object. \n 74 The user does not need to know how the focus is created or what the ouput of the computation is \n 75 Should be called before `send_solution` or `visualise` 76 :param location: The location of the focus 77 ''' 78 79 if type(location) not in (None, Tensor, Iterable): 80 raise TypeError("Locations should be one of None, Tensor, Iterable") 81 82 if location is None: 83 location: Tensor = self.origin 84 85 if type(location) is not Tensor: 86 location: Tensor = create_points(1,1,location[0], location[1], location[2]) 87 88 self.solution = self.solver(location, board = self.board)
Create a focus at location using the default solver defined in class creation and stores the result in the object.
The user does not need to know how the focus is created or what the ouput of the computation is
Should be called before send_solution or visualise
Parameters
- location: The location of the focus
90 def visualise(self, size:float=0.03, origin:Tensor=None, plane:str='xz') -> None: 91 ''' 92 Visualises the sound field that has been previously computed, see `acoustools.Visualise.Visualiser` for parameter details \n 93 :param size: Size of the visualisation window from the origin (window will be 2*size) 94 :param origin: Central point of the visualisation 95 :param plane: Plane to visulaise in 96 ''' 97 if self.solution is None: 98 raise ValueError("No solution found, call `create_focus` before use") 99 abc: tuple[Tensor] = ABC(size, origin=origin, plane=plane) 100 Visualise(*abc, self.solution)
Visualises the sound field that has been previously computed, see acoustools.Visualise.Visualiser for parameter details
Parameters
- size: Size of the visualisation window from the origin (window will be 2*size)
- origin: Central point of the visualisation
- plane: Plane to visulaise in
103 def send_solution(self, ids=(1000,999)) -> None: 104 ''' 105 Sends the solution to a connected physical device 106 :param ids: The ids for the device connected 107 ''' 108 if self.solution is None: 109 raise ValueError("No solution found, call `create_focus` before use") 110 111 if self.lev is None: self.lev = LevitatorController(ids=ids) 112 113 self.lev.levitate(self.solution)
Sends the solution to a connected physical device
Parameters
- ids: The ids for the device connected
Inherited Members
117class TopWithReflectorContext(AcousToolsContext): 118 119 120 def __init__(self, origin:Iterable|Tensor=(0,0,0), default_solver=wgs, path:str='../BEMMedia/', reflector_path:str = './flat-lam2.stl', height:float = 0.12) -> None: 121 ''' 122 AcousTools Context Objects for 1 board above a reflector\n 123 :param origin: The position of the origin for the setup \n 124 :param default_solver: The solver to use when creating a focus, default wgs 125 :param path: The path where BEM Medis is stored, this folder should have a subfolder called BEMCache 126 :param reflector_path: The Path to the reflector to use 127 :param height: The seperation to use 128 129 Should be used in a `with` block eg 130 ``` 131 from acoustools.HighLevel import TopWithReflectorContext 132 133 with TopWithReflectorContext() as ctx: 134 tb.create_focus() 135 tb.send_solution() 136 ``` 137 ''' 138 super().__init__(origin) 139 140 self.solver = default_solver 141 self.board: Tensor = transducers(16, z=height/2) 142 143 self.path: str = path 144 self.reflector: Mesh = load_scatterer(path + reflector_path) 145 translate(self.reflector, dz=-1*height/2) 146 147 148 self.H: Tensor = get_cache_or_compute_H(self.reflector, self.board, path=path) 149 150 151 def create_focus(self, location:None|Tensor|Iterable = None) -> None: 152 ''' 153 Create a focus at `location` using the default solver defined in class creation and stores the result in the object. \n 154 The user does not need to know how the focus is created or what the ouput of the computation is \n 155 Should be called before `send_solution` or `visualise` 156 :param location: The location of the focus 157 ''' 158 if location is None: 159 location: Tensor = self.origin 160 161 if type(location) is not Tensor: 162 location: Tensor = create_points(1,1,location[0], location[1], location[2]) 163 164 165 E: Tensor = compute_E(self.reflector, location, self.board, path=self.path, H=self.H) 166 self.solution = self.solver(location, board = self.board, A=E) 167 168 169 def visualise(self, size:float=0.03, origin:Tensor=None, plane:str='xz') -> None: 170 ''' 171 Visualises the sound field that has been previously computed, see `acoustools.Visualise.Visualiser` for parameter details \n 172 :param size: Size of the visualisation window from the origin (window will be 2*size) 173 :param origin: Central point of the visualisation 174 :param plane: Plane to visulaise in 175 ''' 176 abc: tuple[Tensor] = ABC(size, origin=origin, plane=plane) 177 Visualise(*abc, self.solution, colour_functions=[propagate_BEM_pressure], colour_function_args=[{'path':self.path, "H":self.H, 'board':self.board, 'scatterer':self.reflector}]) 178 179 def send_solution(self, ids=(1000)) -> None: 180 ''' 181 Sends the solution to a connected physical device 182 :param ids: The ids for the device connected 183 ''' 184 if self.lev is None: self.lev = LevitatorController(ids=ids) 185 186 self.lev.levitate(self.solution)
120 def __init__(self, origin:Iterable|Tensor=(0,0,0), default_solver=wgs, path:str='../BEMMedia/', reflector_path:str = './flat-lam2.stl', height:float = 0.12) -> None: 121 ''' 122 AcousTools Context Objects for 1 board above a reflector\n 123 :param origin: The position of the origin for the setup \n 124 :param default_solver: The solver to use when creating a focus, default wgs 125 :param path: The path where BEM Medis is stored, this folder should have a subfolder called BEMCache 126 :param reflector_path: The Path to the reflector to use 127 :param height: The seperation to use 128 129 Should be used in a `with` block eg 130 ``` 131 from acoustools.HighLevel import TopWithReflectorContext 132 133 with TopWithReflectorContext() as ctx: 134 tb.create_focus() 135 tb.send_solution() 136 ``` 137 ''' 138 super().__init__(origin) 139 140 self.solver = default_solver 141 self.board: Tensor = transducers(16, z=height/2) 142 143 self.path: str = path 144 self.reflector: Mesh = load_scatterer(path + reflector_path) 145 translate(self.reflector, dz=-1*height/2) 146 147 148 self.H: Tensor = get_cache_or_compute_H(self.reflector, self.board, path=path)
AcousTools Context Objects for 1 board above a reflector
Parameters
origin: The position of the origin for the setup
default_solver: The solver to use when creating a focus, default wgs
- path: The path where BEM Medis is stored, this folder should have a subfolder called BEMCache
- reflector_path: The Path to the reflector to use
- height: The seperation to use
Should be used in a with block eg
from acoustools.HighLevel import TopWithReflectorContext
with TopWithReflectorContext() as ctx:
tb.create_focus()
tb.send_solution()
151 def create_focus(self, location:None|Tensor|Iterable = None) -> None: 152 ''' 153 Create a focus at `location` using the default solver defined in class creation and stores the result in the object. \n 154 The user does not need to know how the focus is created or what the ouput of the computation is \n 155 Should be called before `send_solution` or `visualise` 156 :param location: The location of the focus 157 ''' 158 if location is None: 159 location: Tensor = self.origin 160 161 if type(location) is not Tensor: 162 location: Tensor = create_points(1,1,location[0], location[1], location[2]) 163 164 165 E: Tensor = compute_E(self.reflector, location, self.board, path=self.path, H=self.H) 166 self.solution = self.solver(location, board = self.board, A=E)
Create a focus at location using the default solver defined in class creation and stores the result in the object.
The user does not need to know how the focus is created or what the ouput of the computation is
Should be called before send_solution or visualise
Parameters
- location: The location of the focus
169 def visualise(self, size:float=0.03, origin:Tensor=None, plane:str='xz') -> None: 170 ''' 171 Visualises the sound field that has been previously computed, see `acoustools.Visualise.Visualiser` for parameter details \n 172 :param size: Size of the visualisation window from the origin (window will be 2*size) 173 :param origin: Central point of the visualisation 174 :param plane: Plane to visulaise in 175 ''' 176 abc: tuple[Tensor] = ABC(size, origin=origin, plane=plane) 177 Visualise(*abc, self.solution, colour_functions=[propagate_BEM_pressure], colour_function_args=[{'path':self.path, "H":self.H, 'board':self.board, 'scatterer':self.reflector}])
Visualises the sound field that has been previously computed, see acoustools.Visualise.Visualiser for parameter details
Parameters
- size: Size of the visualisation window from the origin (window will be 2*size)
- origin: Central point of the visualisation
- plane: Plane to visulaise in
179 def send_solution(self, ids=(1000)) -> None: 180 ''' 181 Sends the solution to a connected physical device 182 :param ids: The ids for the device connected 183 ''' 184 if self.lev is None: self.lev = LevitatorController(ids=ids) 185 186 self.lev.levitate(self.solution)
Sends the solution to a connected physical device
Parameters
- ids: The ids for the device connected
Inherited Members
190class BottomWithReflectorContext(TopWithReflectorContext): 191 192 def __init__(self, origin:Iterable|Tensor=(0,0,0), default_solver=wgs, path='../BEMMedia/', reflector_path = './flat-lam2.stl', height = 0.12) -> None: 193 ''' 194 AcousTools Context Objects for 1 board below a reflector\n 195 :param origin: The position of the origin for the setup \n 196 :param default_solver: The solver to use when creating a focus, default wgs 197 :param path: The path where BEM Medis is stored, this folder should have a subfolder called BEMCache 198 :param reflector_path: The Path to the reflector to use 199 :param height: The seperation to use 200 201 Should be used in a `with` block eg 202 ``` 203 from acoustools.HighLevel import TopWithReflectorContext 204 205 with TopWithReflectorContext() as ctx: 206 tb.create_focus() 207 tb.send_solution() 208 ``` 209 ''' 210 super().__init__(origin, default_solver, path, reflector_path, height) 211 212 self.board: Tensor = transducers(16, z=-1*height/2) 213 214 self.reflector: Mesh = load_scatterer(path + reflector_path) 215 translate(self.reflector, dz=height/2) 216 217 218 self.H: Tensor = get_cache_or_compute_H(self.reflector, self.board, path=path)
192 def __init__(self, origin:Iterable|Tensor=(0,0,0), default_solver=wgs, path='../BEMMedia/', reflector_path = './flat-lam2.stl', height = 0.12) -> None: 193 ''' 194 AcousTools Context Objects for 1 board below a reflector\n 195 :param origin: The position of the origin for the setup \n 196 :param default_solver: The solver to use when creating a focus, default wgs 197 :param path: The path where BEM Medis is stored, this folder should have a subfolder called BEMCache 198 :param reflector_path: The Path to the reflector to use 199 :param height: The seperation to use 200 201 Should be used in a `with` block eg 202 ``` 203 from acoustools.HighLevel import TopWithReflectorContext 204 205 with TopWithReflectorContext() as ctx: 206 tb.create_focus() 207 tb.send_solution() 208 ``` 209 ''' 210 super().__init__(origin, default_solver, path, reflector_path, height) 211 212 self.board: Tensor = transducers(16, z=-1*height/2) 213 214 self.reflector: Mesh = load_scatterer(path + reflector_path) 215 translate(self.reflector, dz=height/2) 216 217 218 self.H: Tensor = get_cache_or_compute_H(self.reflector, self.board, path=path)
AcousTools Context Objects for 1 board below a reflector
Parameters
origin: The position of the origin for the setup
default_solver: The solver to use when creating a focus, default wgs
- path: The path where BEM Medis is stored, this folder should have a subfolder called BEMCache
- reflector_path: The Path to the reflector to use
- height: The seperation to use
Should be used in a with block eg
from acoustools.HighLevel import TopWithReflectorContext
with TopWithReflectorContext() as ctx:
tb.create_focus()
tb.send_solution()