src.acoustools.Utilities.Forward_models
1import torch 2from torch import Tensor 3 4from acoustools.Utilities.Boards import TRANSDUCERS 5from acoustools.Utilities.Utilities import is_batched_points 6from acoustools.Utilities.Setup import device, DTYPE 7import acoustools.Constants as Constants 8 9 10def forward_model(points:Tensor, transducers:Tensor|None = None, p_ref = Constants.P_ref, norms:Tensor=None, k=Constants.k, transducer_radius = Constants.radius) -> Tensor: 11 ''' 12 Create the piston model forward propagation matrix for points and transducers\\ 13 :param points: Point position to compute propagation to \\ 14 :param transducers: The Transducer array, default two 16x16 arrays \\ 15 :param p_ref: The value to use for p_ref\\ 16 :param norms: Tensor of normals for transduers\\ 17 Returns forward propagation matrix \\ 18 ''' 19 if transducers is None: 20 transducers = TRANSDUCERS 21 22 if norms is None: 23 norms = (torch.zeros_like(transducers) + torch.tensor([0,0,1], device=device)) * torch.sign(transducers[:,2].real).unsqueeze(1).to(DTYPE) 24 25 if is_batched_points(points): 26 return forward_model_batched(points, transducers, p_ref=p_ref,norms=norms, k=k, transducer_radius=transducer_radius).to(DTYPE) 27 else: 28 return forward_model_unbatched(points, transducers, p_ref=p_ref,norms=norms, k=k, transducer_radius=transducer_radius).to(DTYPE) 29 30def forward_model_unbatched(points, transducers = TRANSDUCERS, p_ref = Constants.P_ref,norms:Tensor|None=None, k=Constants.k, transducer_radius = Constants.radius): 31 ''' 32 @private 33 Compute the piston model for acoustic wave propagation NOTE: Unbatched, use `forward_model_batched` for batched computation \\ 34 `points` Point position to compute propagation to \\ 35 `transducers` The Transducer array, default two 16x16 arrays \\ 36 :param p_ref: The value to use for p_ref\\ 37 :param norms: Tensor of normals for transduers\\ 38 Returns forward propagation matrix \\ 39 Written by Giorgos Christopoulos, 2022 40 ''' 41 42 if norms is None: 43 norms = (torch.zeros_like(transducers) + torch.tensor([0,0,1], device=device)) * torch.sign(transducers[:,2].real).unsqueeze(1).to(DTYPE) 44 45 m=points.size()[1] 46 n=transducers.size()[0] 47 48 transducers_x=torch.reshape(transducers[:,0],(n,1)) 49 transducers_y=torch.reshape(transducers[:,1],(n,1)) 50 transducers_z=torch.reshape(transducers[:,2],(n,1)) 51 52 53 points_x=torch.reshape(points[0,:],(m,1)) 54 points_y=torch.reshape(points[1,:],(m,1)) 55 points_z=torch.reshape(points[2,:],(m,1)) 56 57 dx = (transducers_x.T-points_x) **2 58 dy = (transducers_y.T-points_y) **2 59 dz = (transducers_z.T-points_z) **2 60 61 distance=torch.sqrt(dx+dy+dz) 62 63 distance_axis_sub = torch.sub(points,transducers).to(DTYPE) 64 norms = norms.unsqueeze(3).expand( m, 3, n) 65 sine_angle = torch.norm(torch.cross(distance_axis_sub, norms, dim=1),2, dim=1) / distance 66 67 68 bessel_arg=k*transducer_radius*sine_angle #planar_dist / dist = sin(theta) 69 70 directivity=1/2-torch.pow(bessel_arg,2)/16+torch.pow(bessel_arg,4)/384 71 72 p = 1j*k*distance 73 phase = torch.exp(p) 74 75 trans_matrix=2*p_ref*torch.multiply(torch.divide(phase,distance),directivity) 76 return trans_matrix 77 78def forward_model_batched(points, transducers = TRANSDUCERS, p_ref = Constants.P_ref,norms:Tensor|None=None, k=Constants.k, transducer_radius=Constants.radius): 79 80 ''' 81 @private 82 computed batched piston model for acoustic wave propagation 83 `points` Point position to compute propagation to \\ 84 `transducers` The Transducer array, default two 16x16 arrays \\ 85 :param p_ref: The value to use for p_ref\\ 86 :param norms: Tensor of normals for transduers\\ 87 Returns forward propagation matrix \\ 88 ''' 89 B = points.shape[0] 90 N = points.shape[2] 91 M = transducers.shape[0] 92 93 if norms is None: 94 norms = (torch.zeros_like(transducers) + torch.tensor([0,0,1], device=device)) * torch.sign(transducers[:,2].real).unsqueeze(1).to(DTYPE) 95 96 # p = torch.permute(points,(0,2,1)) 97 transducers = torch.unsqueeze(transducers,2) 98 transducers = transducers.expand((B,-1,-1,N)) 99 points = torch.unsqueeze(points,1) 100 points = points.expand((-1,M,-1,-1)) 101 102 # distance_axis = (transducers - points) **2 103 # distance_axis_sub = transducers - points 104 distance_axis_sub = torch.sub(points,transducers).to(DTYPE) 105 distance_axis = distance_axis_sub * distance_axis_sub 106 distance = torch.sqrt(torch.sum(distance_axis,dim=2)) 107 108 # sine_angle = torch.divide(planar_distance,distance) 109 norms = norms.unsqueeze(0).unsqueeze(3).expand(B, M, 3, N) 110 111 sine_angle = torch.norm(torch.cross(distance_axis_sub, norms, dim=2),2, dim=2) / distance 112 113 114 115 116 bessel_arg=k*transducer_radius*sine_angle 117 directivity=1/2-torch.pow(bessel_arg,2)/16+torch.pow(bessel_arg,4)/384 118 119 p = 1j*k*distance 120 phase = torch.exp(p) 121 122 trans_matrix=2*p_ref*torch.multiply(torch.divide(phase,distance),directivity) 123 124 return trans_matrix.permute((0,2,1)).to(DTYPE).to(device) 125 126def green_propagator(points:Tensor, board:Tensor, k:float=Constants.k) -> Tensor: 127 ''' 128 Computes the Green's function propagation matrix from `board` to `points` \n 129 :param points: Points to use 130 :param board: transducers to use 131 :param k: Wavenumber of sound to use 132 :return: Green propagation matrix 133 ''' 134 135 B = points.shape[0] 136 N = points.shape[2] 137 M = board.shape[0] 138 board = board.unsqueeze(0).unsqueeze_(3) 139 points = points.unsqueeze(1) 140 141 # distances_axis = torch.abs(points-board) 142 distances_axis = (points-board)**2 143 distances = torch.sqrt(torch.sum(distances_axis, dim=2)) 144 145 146 147 # green = -1* (torch.exp(1j*k*distances)) / (4 * Constants.pi *distances) 148 green = -1* (torch.exp(1j*k*distances)) / (4 * Constants.pi *distances) 149 150 151 return green.mT
def
forward_model( points: torch.Tensor, transducers: torch.Tensor | None = None, p_ref=3.4000000000000004, norms: torch.Tensor = None, k=732.7329804081634, transducer_radius=0.0045) -> torch.Tensor:
11def forward_model(points:Tensor, transducers:Tensor|None = None, p_ref = Constants.P_ref, norms:Tensor=None, k=Constants.k, transducer_radius = Constants.radius) -> Tensor: 12 ''' 13 Create the piston model forward propagation matrix for points and transducers\\ 14 :param points: Point position to compute propagation to \\ 15 :param transducers: The Transducer array, default two 16x16 arrays \\ 16 :param p_ref: The value to use for p_ref\\ 17 :param norms: Tensor of normals for transduers\\ 18 Returns forward propagation matrix \\ 19 ''' 20 if transducers is None: 21 transducers = TRANSDUCERS 22 23 if norms is None: 24 norms = (torch.zeros_like(transducers) + torch.tensor([0,0,1], device=device)) * torch.sign(transducers[:,2].real).unsqueeze(1).to(DTYPE) 25 26 if is_batched_points(points): 27 return forward_model_batched(points, transducers, p_ref=p_ref,norms=norms, k=k, transducer_radius=transducer_radius).to(DTYPE) 28 else: 29 return forward_model_unbatched(points, transducers, p_ref=p_ref,norms=norms, k=k, transducer_radius=transducer_radius).to(DTYPE)
Create the piston model forward propagation matrix for points and transducers\
Parameters
- points: Point position to compute propagation to \
- transducers: The Transducer array, default two 16x16 arrays \
- p_ref: The value to use for p_ref\
- norms: Tensor of normals for transduers\ Returns forward propagation matrix \
def
green_propagator( points: torch.Tensor, board: torch.Tensor, k: float = 732.7329804081634) -> torch.Tensor:
127def green_propagator(points:Tensor, board:Tensor, k:float=Constants.k) -> Tensor: 128 ''' 129 Computes the Green's function propagation matrix from `board` to `points` \n 130 :param points: Points to use 131 :param board: transducers to use 132 :param k: Wavenumber of sound to use 133 :return: Green propagation matrix 134 ''' 135 136 B = points.shape[0] 137 N = points.shape[2] 138 M = board.shape[0] 139 board = board.unsqueeze(0).unsqueeze_(3) 140 points = points.unsqueeze(1) 141 142 # distances_axis = torch.abs(points-board) 143 distances_axis = (points-board)**2 144 distances = torch.sqrt(torch.sum(distances_axis, dim=2)) 145 146 147 148 # green = -1* (torch.exp(1j*k*distances)) / (4 * Constants.pi *distances) 149 green = -1* (torch.exp(1j*k*distances)) / (4 * Constants.pi *distances) 150 151 152 return green.mT
Computes the Green's function propagation matrix from board to points
Parameters
- points: Points to use
- board: transducers to use
- k: Wavenumber of sound to use
Returns
Green propagation matrix