Skip to content

Commit

Permalink
Moved excitation_function to the emfunctions collection in order to a…
Browse files Browse the repository at this point in the history
…llow use without the create of an antenna structure class object, while still supporting convenient use within the antenna class.
  • Loading branch information
LyceanEM committed Dec 4, 2024
1 parent cf70603 commit e82959f
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 42 deletions.
61 changes: 19 additions & 42 deletions lyceanem/base_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,56 +429,33 @@ def export_all_points(self, point_index=None):

return point_cloud

def excitation_function(
self,
desired_e_vector,
point_index=None,
phase_shift="none",
wavelength=1.0,
steering_vector=np.zeros((1, 3)),
transmit_power=1.0,
local_projection=True
):
def excitation_function(self,
desired_e_vector,
point_index=None,
phase_shift="none",
wavelength=1.0,
steering_vector=np.zeros((1, 3)),
transmit_power=1.0,
local_projection=True
):
# generate the local excitation function and then convert into the global coordinate frame.
if point_index == None:
aperture_points = self.export_all_points()
else:
aperture_points = self.export_all_points(point_index=point_index)

if local_projection:
# as export all points imposes the transformation from local to global frame on the points and associated normal vectors, no rotation is required within calculate_conformalVectors
aperture_weights = EM.calculate_conformalVectors(
desired_e_vector, aperture_points.point_data["Normals"], np.eye(3)
)
else:
aperture_weights=np.repeat(desired_e_vector,aperture_points.points.shape[0],axis=0)

if phase_shift == "wavefront":
source_points = np.asarray(aperture_points.points)
phase_weights = BM.WavefrontWeights(
source_points, steering_vector, wavelength
)
aperture_weights = aperture_weights * phase_weights.reshape(-1, 1)
if phase_shift == "coherence":
source_points = np.asarray(aperture_points.points)
phase_weights = BM.ArbitaryCoherenceWeights(
source_points, steering_vector, wavelength
)
aperture_weights = aperture_weights * phase_weights.reshape(-1, 1)

from .utility.math_functions import discrete_transmit_power
from .electromagnetics.emfunctions import excitation_function

if "Area" in aperture_points.point_data.keys():
areas = aperture_points.point_data["Area"]
else:
areas = np.zeros((aperture_points.points.shape[0]))
areas[:] = (wavelength * 0.5) ** 2

calibrated_amplitude_weights = discrete_transmit_power(
aperture_weights, areas, transmit_power
)
return calibrated_amplitude_weights
excitation_weights=excitation_function(
aperture_points,
desired_e_vector,
phase_shift=phase_shift,
wavelength=wavelength,
steering_vector=steering_vector,
transmit_power=transmit_power,
local_projection=local_projection)

return excitation_weights
def export_all_structures(self):
#objects = copy.deepcopy(self.structures.solids)
for item in range(len(self.structures.solids)):
Expand Down
50 changes: 50 additions & 0 deletions lyceanem/electromagnetics/emfunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,56 @@
import pyvista as pv


def excitation_function(
aperture_points,
desired_e_vector,
phase_shift="none",
wavelength=1.0,
steering_vector=np.zeros((1, 3)),
transmit_power=1.0,
local_projection=True
):
"""
Calculate the excitation function for the given aperture points, desired electric field vector, phase shift, wavelength, steering vector, transmit power, and local projection. This will generate the normalised field intensities for the desired total transmit power, and beamforming algorithm. The aperture mesh should have Normals and Area associated with each point for full functionality.
"""


if local_projection:
# as export all points imposes the transformation from local to global frame on the points and associated normal vectors, no rotation is required within calculate_conformalVectors
from .empropagation import calculate_conformalVectors
aperture_weights = calculate_conformalVectors(
desired_e_vector, aperture_points.point_data["Normals"], np.eye(3)
)
else:
aperture_weights = np.repeat(desired_e_vector, aperture_points.points.shape[0], axis=0)

if phase_shift == "wavefront":
from .beamforming import WavefrontWeights
source_points = np.asarray(aperture_points.points)
phase_weights = WavefrontWeights(
source_points, steering_vector, wavelength
)
aperture_weights = aperture_weights * phase_weights.reshape(-1, 1)
if phase_shift == "coherence":
from .beamforming import ArbitaryCoherenceWeights
source_points = np.asarray(aperture_points.points)
phase_weights = ArbitaryCoherenceWeights(
source_points, steering_vector, wavelength
)
aperture_weights = aperture_weights * phase_weights.reshape(-1, 1)

from ..utility.math_functions import discrete_transmit_power

if "Area" in aperture_points.point_data.keys():
areas = aperture_points.point_data["Area"]
else:
areas = np.zeros((aperture_points.points.shape[0]))
areas[:] = (wavelength * 0.5) ** 2

calibrated_amplitude_weights = discrete_transmit_power(
aperture_weights, areas, transmit_power
)
return calibrated_amplitude_weights
def fresnel_zone(pointA, pointB, wavelength, zone=1):
# based on the provided points, wavelength, and zone number, calculate the fresnel zone. This is defined as an ellipsoid for which the difference in distance between the line AB (line of sight), and AP+PB (reflected wave) is a constant multiple of ($n\dfrac{\lambda}{2}$).
foci = np.stack([pointA, pointB])
Expand Down

0 comments on commit e82959f

Please sign in to comment.