
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "auto_examples/06_farfield_polarisation.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        Click :ref:`here <sphx_glr_download_auto_examples_06_farfield_polarisation.py>`
        to download the full example code

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_auto_examples_06_farfield_polarisation.py:


Modelling Different Farfield Polarisations
======================================================

This example uses the frequency domain :func:`lyceanem.models.frequency_domain.calculate_farfield` function to predict
the farfield pattern for a linearly polarised aperture. This could represent an antenna array without any beamforming
weights.

.. GENERATED FROM PYTHON SOURCE LINES 13-17

.. code-block:: default

    import numpy as np
    import open3d as o3d
    import copy








.. GENERATED FROM PYTHON SOURCE LINES 18-27

Setting Farfield Resolution and Wavelength
-------------------------------------------
LyceanEM uses Elevation and Azimuth to record spherical coordinates, ranging from -180 to 180 degrees in azimuth,
and from -90 to 90 degrees in elevation. In order to launch the aperture projection function, the resolution in
both azimuth and elevation is requried.
In order to ensure a fast example, 37 points have been used here for both, giving a total of 1369 farfield points.

The wavelength of interest is also an important variable for antenna array analysis, so we set it now for 10GHz,
an X band aperture.

.. GENERATED FROM PYTHON SOURCE LINES 27-32

.. code-block:: default


    az_res = 37
    elev_res = 37
    wavelength = 3e8 / 10e9








.. GENERATED FROM PYTHON SOURCE LINES 33-35

Generating consistent point source to explore farfield polarisations, and rotating the source
----------------------------------------------------------------------------------------------

.. GENERATED FROM PYTHON SOURCE LINES 35-50

.. code-block:: default


    from lyceanem.base_classes import points,structures,antenna_structures

    aperture_coords=o3d.geometry.PointCloud()
    point1=np.asarray([0.0,0,0]).reshape(1,3)
    normal1=np.asarray([0,0,1.0]).reshape(1,3)
    aperture_coords.points=o3d.utility.Vector3dVector(point1)
    aperture_coords.normals=o3d.utility.Vector3dVector(normal1)
    aperture=points([aperture_coords])
    blockers=structures([None])
    point_antenna=antenna_structures(blockers, aperture)


    from lyceanem.models.frequency_domain import calculate_farfield








.. GENERATED FROM PYTHON SOURCE LINES 51-52

The first source polarisation is based upon the u-vector of the source point. When the excitation_function method of the antenna structure class is used, it will calculate the appropriate polarisation vectors based upon the local normal vectors.

.. GENERATED FROM PYTHON SOURCE LINES 52-67

.. code-block:: default


    desired_E_axis = np.zeros((1, 3), dtype=np.complex64)
    desired_E_axis[0, 0] = 1.0
    Etheta, Ephi = calculate_farfield(
        point_antenna.export_all_points(),
        point_antenna.export_all_structures(),
        point_antenna.excitation_function(desired_e_vector=desired_E_axis),
        az_range=np.linspace(-180, 180, az_res),
        el_range=np.linspace(-90, 90, elev_res),
        wavelength=wavelength,
        farfield_distance=20,
        elements=False,
        project_vectors=False,
    )





.. rst-class:: sphx-glr-script-out

 Out:

 .. code-block:: none

    Structure does not exist
    no structures
    /home/timtitan/anaconda3/envs/EMDevelopment/lib/python3.8/site-packages/numba/cuda/compiler.py:726: NumbaPerformanceWarning: Grid size (6) < 2 * SM count (28) will likely result in GPU under utilization due to low occupancy.
      warn(NumbaPerformanceWarning(msg))
    /home/timtitan/anaconda3/envs/EMDevelopment/lib/python3.8/site-packages/numba/cuda/compiler.py:726: NumbaPerformanceWarning: Grid size (6) < 2 * SM count (28) will likely result in GPU under utilization due to low occupancy.
      warn(NumbaPerformanceWarning(msg))
    /home/timtitan/anaconda3/envs/EMDevelopment/lib/python3.8/site-packages/numba/cuda/cudadrv/devicearray.py:885: NumbaPerformanceWarning: Host array used in CUDA kernel will incur copy overhead to/from device.
      warn(NumbaPerformanceWarning(msg))




.. GENERATED FROM PYTHON SOURCE LINES 68-70

Antenna Pattern class is used to manipulate and record antenna patterns
------------------------------------------------------------------------

.. GENERATED FROM PYTHON SOURCE LINES 70-81

.. code-block:: default



    from lyceanem.base_classes import antenna_pattern

    u_pattern = antenna_pattern(
        azimuth_resolution=az_res, elevation_resolution=elev_res
    )
    u_pattern.pattern[:, :, 0] = Etheta
    u_pattern.pattern[:, :, 1] = Ephi
    u_pattern.display_pattern(desired_pattern='Power')




.. image-sg:: /auto_examples/images/sphx_glr_06_farfield_polarisation_001.png
   :alt: Power Pattern
   :srcset: /auto_examples/images/sphx_glr_06_farfield_polarisation_001.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 82-83

The second source polarisation is based upon the v-vector of the source point.

.. GENERATED FROM PYTHON SOURCE LINES 83-106

.. code-block:: default


    desired_E_axis = np.zeros((1, 3), dtype=np.complex64)
    desired_E_axis[0, 1] = 1.0
    Etheta, Ephi = calculate_farfield(
        point_antenna.export_all_points(),
        point_antenna.export_all_structures(),
        point_antenna.excitation_function(desired_e_vector=desired_E_axis),
        az_range=np.linspace(-180, 180, az_res),
        el_range=np.linspace(-90, 90, elev_res),
        wavelength=wavelength,
        farfield_distance=20,
        elements=False,
        project_vectors=False,
    )


    v_pattern = antenna_pattern(
        azimuth_resolution=az_res, elevation_resolution=elev_res
    )
    v_pattern.pattern[:, :, 0] = Etheta
    v_pattern.pattern[:, :, 1] = Ephi
    v_pattern.display_pattern(desired_pattern='Power')




.. image-sg:: /auto_examples/images/sphx_glr_06_farfield_polarisation_002.png
   :alt: Power Pattern
   :srcset: /auto_examples/images/sphx_glr_06_farfield_polarisation_002.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 Out:

 .. code-block:: none

    Structure does not exist
    no structures
    /home/timtitan/anaconda3/envs/EMDevelopment/lib/python3.8/site-packages/numba/cuda/compiler.py:726: NumbaPerformanceWarning: Grid size (6) < 2 * SM count (28) will likely result in GPU under utilization due to low occupancy.
      warn(NumbaPerformanceWarning(msg))
    /home/timtitan/anaconda3/envs/EMDevelopment/lib/python3.8/site-packages/numba/cuda/cudadrv/devicearray.py:885: NumbaPerformanceWarning: Host array used in CUDA kernel will incur copy overhead to/from device.
      warn(NumbaPerformanceWarning(msg))
    /home/timtitan/Documents/10-19-Research-Projects/14-Electromagnetics-Modelling/14.04-Python-Development/LyceanEM/lyceanem/electromagnetics/beamforming.py:1083: RuntimeWarning: divide by zero encountered in log10
      logdata = 20 * np.log10(data)




.. GENERATED FROM PYTHON SOURCE LINES 107-108

The third source polarisation is based upon the n-vector of the source point. Aligned with the source point normal.

.. GENERATED FROM PYTHON SOURCE LINES 108-130

.. code-block:: default


    desired_E_axis = np.zeros((1, 3), dtype=np.complex64)
    desired_E_axis[0, 2] = 1.0
    Etheta, Ephi = calculate_farfield(
        point_antenna.export_all_points(),
        point_antenna.export_all_structures(),
        point_antenna.excitation_function(desired_e_vector=desired_E_axis),
        az_range=np.linspace(-180, 180, az_res),
        el_range=np.linspace(-90, 90, elev_res),
        wavelength=wavelength,
        farfield_distance=20,
        elements=False,
        project_vectors=False,
    )

    n_pattern = antenna_pattern(
        azimuth_resolution=az_res, elevation_resolution=elev_res
    )
    n_pattern.pattern[:, :, 0] = Etheta
    n_pattern.pattern[:, :, 1] = Ephi
    n_pattern.display_pattern(desired_pattern='Power')




.. image-sg:: /auto_examples/images/sphx_glr_06_farfield_polarisation_003.png
   :alt: Power Pattern
   :srcset: /auto_examples/images/sphx_glr_06_farfield_polarisation_003.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 Out:

 .. code-block:: none

    Structure does not exist
    no structures
    /home/timtitan/anaconda3/envs/EMDevelopment/lib/python3.8/site-packages/numba/cuda/compiler.py:726: NumbaPerformanceWarning: Grid size (6) < 2 * SM count (28) will likely result in GPU under utilization due to low occupancy.
      warn(NumbaPerformanceWarning(msg))
    /home/timtitan/anaconda3/envs/EMDevelopment/lib/python3.8/site-packages/numba/cuda/cudadrv/devicearray.py:885: NumbaPerformanceWarning: Host array used in CUDA kernel will incur copy overhead to/from device.
      warn(NumbaPerformanceWarning(msg))




.. GENERATED FROM PYTHON SOURCE LINES 131-132

The point source can then be rotated, by providing a rotation matrix, and the u,v,n directions are moved with it in a consistent way.

.. GENERATED FROM PYTHON SOURCE LINES 132-186

.. code-block:: default


    point_antenna.rotate_antenna(o3d.geometry.get_rotation_matrix_from_axis_angle(np.radians(np.asarray([90.0,0.0,0.0]))))

    desired_E_axis = np.zeros((1, 3), dtype=np.complex64)
    desired_E_axis[0, 0] = 1.0
    Etheta, Ephi = calculate_farfield(
        point_antenna.export_all_points(),
        point_antenna.export_all_structures(),
        point_antenna.excitation_function(desired_e_vector=desired_E_axis),
        az_range=np.linspace(-180, 180, az_res),
        el_range=np.linspace(-90, 90, elev_res),
        wavelength=wavelength,
        farfield_distance=20,
        elements=False,
        project_vectors=False,
    )
    u_pattern.pattern[:, :, 0] = Etheta
    u_pattern.pattern[:, :, 1] = Ephi
    u_pattern.display_pattern(desired_pattern='Power')


    desired_E_axis = np.zeros((1, 3), dtype=np.complex64)
    desired_E_axis[0, 1] = 1.0
    Etheta, Ephi = calculate_farfield(
        point_antenna.export_all_points(),
        point_antenna.export_all_structures(),
        point_antenna.excitation_function(desired_e_vector=desired_E_axis),
        az_range=np.linspace(-180, 180, az_res),
        el_range=np.linspace(-90, 90, elev_res),
        wavelength=wavelength,
        farfield_distance=20,
        elements=False,
        project_vectors=False,
    )
    v_pattern.pattern[:, :, 0] = Etheta
    v_pattern.pattern[:, :, 1] = Ephi
    v_pattern.display_pattern(desired_pattern='Power')


    desired_E_axis = np.zeros((1, 3), dtype=np.complex64)
    desired_E_axis[0, 2] = 1.0
    Etheta, Ephi = calculate_farfield(
        point_antenna.export_all_points(),
        point_antenna.export_all_structures(),
        point_antenna.excitation_function(desired_e_vector=desired_E_axis),
        az_range=np.linspace(-180, 180, az_res),
        el_range=np.linspace(-90, 90, elev_res),
        wavelength=wavelength,
        farfield_distance=20,
        elements=False,
        project_vectors=False,
    )
    n_pattern.pattern[:, :, 0] = Etheta
    n_pattern.pattern[:, :, 1] = Ephi
    n_pattern.display_pattern(desired_pattern='Power')


.. rst-class:: sphx-glr-horizontal


    *

      .. image-sg:: /auto_examples/images/sphx_glr_06_farfield_polarisation_004.png
         :alt: Power Pattern
         :srcset: /auto_examples/images/sphx_glr_06_farfield_polarisation_004.png
         :class: sphx-glr-multi-img

    *

      .. image-sg:: /auto_examples/images/sphx_glr_06_farfield_polarisation_005.png
         :alt: Power Pattern
         :srcset: /auto_examples/images/sphx_glr_06_farfield_polarisation_005.png
         :class: sphx-glr-multi-img

    *

      .. image-sg:: /auto_examples/images/sphx_glr_06_farfield_polarisation_006.png
         :alt: Power Pattern
         :srcset: /auto_examples/images/sphx_glr_06_farfield_polarisation_006.png
         :class: sphx-glr-multi-img


.. rst-class:: sphx-glr-script-out

 Out:

 .. code-block:: none

    Structure does not exist
    no structures
    /home/timtitan/anaconda3/envs/EMDevelopment/lib/python3.8/site-packages/numba/cuda/compiler.py:726: NumbaPerformanceWarning: Grid size (6) < 2 * SM count (28) will likely result in GPU under utilization due to low occupancy.
      warn(NumbaPerformanceWarning(msg))
    /home/timtitan/anaconda3/envs/EMDevelopment/lib/python3.8/site-packages/numba/cuda/cudadrv/devicearray.py:885: NumbaPerformanceWarning: Host array used in CUDA kernel will incur copy overhead to/from device.
      warn(NumbaPerformanceWarning(msg))
    /home/timtitan/Documents/10-19-Research-Projects/14-Electromagnetics-Modelling/14.04-Python-Development/LyceanEM/lyceanem/electromagnetics/beamforming.py:1083: RuntimeWarning: divide by zero encountered in log10
      logdata = 20 * np.log10(data)
    Structure does not exist
    no structures
    Structure does not exist
    no structures





.. rst-class:: sphx-glr-timing

   **Total running time of the script:** ( 0 minutes  28.870 seconds)


.. _sphx_glr_download_auto_examples_06_farfield_polarisation.py:


.. only :: html

 .. container:: sphx-glr-footer
    :class: sphx-glr-footer-example



  .. container:: sphx-glr-download sphx-glr-download-python

     :download:`Download Python source code: 06_farfield_polarisation.py <06_farfield_polarisation.py>`



  .. container:: sphx-glr-download sphx-glr-download-jupyter

     :download:`Download Jupyter notebook: 06_farfield_polarisation.ipynb <06_farfield_polarisation.ipynb>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
