An open source physical optics tool coded in Matlab for reflector antenna analysis
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


POpen is a tool coded in Matlab, initiated at Heriot-Watt University based on the PhD thesis by Salvador Mercader-Pellicier with continued development by Salvador Mercader-Pellicier, Francesco Rigobello and Louis Dufour.

It provides analysis capabilities for single and multiple reflector configurations, with symmetric or offset configuration. It also allows non-canonical reflector shapes to be used and as such can be used for reflector and subreflector shaping/contouring.

The analysis of a reflector antenna system starts with the definition of the geometrical objects (reflectors, subreflectors, feeds, etc.) on which operations are applied (a feed illuminating a reflector, a reflector radiating to the far-field, etc.). Every geometrical objects and operations are defined as classes.

A graphical user interface, which is linked to GRAPS (student version, to install separately and change path in the code) and allows to run limited simulation scenarios (PEC only, Gaussian feed (Huygens Source) but with both offset and dual configuration reflector) using a graphical user interface.

Run setPathPO to add all required files to the current path.

Revision history

  • v.1.0 : Initial release

External libraries

Some external libraries are used in this project :

  • mesh2d for the triangular mesh generation. The toolbox supports user-defined sizing function as a function of the position for the mesh. Modify then the file setPathPO
  • the student version of GRASP TICRA is used in the GUI to make comparisons between GRASP and POpen. The path of TICRA must then be updated in GUI/solveGrasp.m

Quick start

  • 0: add mesh2d if you want to use triangular meshing. Then update the path in setPathPO. This step is required only if you wish to use the triangular meshes.
  • 1: run setPathPO to add master and all subfolders to the path.
  • 2: run any of the demos (dual_reflector_offset, dual_reflector_sym, single_configuration)

List of available geometrical objects

Here is a list of all available classes, and a brief description. The detailed documentation is to be found in the other chapters of this wiki (links given in the list).


See Reflector Creation Classes

A reflector is defined by a class inherited from POReflector (Abstract). This defines the position and orientation, along with the reflector rim. The reflector surface and meshing are defined separately in classes inherited from POReflectorMesh (Abstract) and POReflectorSurf (Abstract) respectively. Examples of inherited classes available:


A feed is defined as a class inherited from POFeed (Abstract). Examples of inherited classes available:

  • Inherited from POFeed (Abstract)
    • HuygensSourceFeed
    • FFField where the field is calculated from the far-field, and the illuminated target assumed to be in the far field.

List of available operations

Illuminating an object with a feed or a subreflector POSurfaceCurrents

With defaults actions for the reflector to be a PEC, but also works with FSS. Detects atomatically if the illuminating object is a feed or POSurfacecurrent object of a subreflector (the currents on the subreflector must have been calculated beforehand).

Calculating the far field from surface currents Currents2Farfield

⚠️ The far field is always calculated in the reflector CS. The rotation of the u,v coefficients from global CS to reflector CS is not yet implemented: so when you prescribe u,v's you are prescribing them in the CS of the reflector over which you are integrating the far field

Example - single configuration reflector antenna

First, we create a reflector, in this case a reflector centered at the origin, of diameter d:

reflector = CircleReflector(d,0,0,0);

Then, we create the surface and mesh we want to associate to this reflector. We create a parabolic surface, and a triangular mesh with 4 Gauss integration points per triangle and a custom size function for the mesh element sizes:

surface = ParabSurface(f, x_c, h);
hfun = @(PP) lambda_0/2/40 + (sqrt(PP(:,1).^2 + PP(:,2).^2)/d).^(1/3)*39*lambda_0/2/40;
mesh = TriangularMeshGauss([], 4);

And link the reflector to the surface and the mesh:


Now that the reflector has a surface and a mesh, we can actually mesh the reflector and set its surface:


Now we create the feed, here a Huygens source:

feed = HuygensSourceFeed(-x_c,0,z_f,feed_ex, feed_ey, feed_ez);
feed.setParameters(LPCP,beta_0,taper,k_0,eta_0, phase_yn, CP_constr, theta_feed);

Both geometrical objects have now been created : a feed and a reflector. The first operation will be to illuminate the reflector with the feed, to calculate the surface currents induced on the reflector surface by the feed :

currents = POSurfaceCurrents(reflector, feed);

The second operation is to calculate the far field from the surface currents (which are induced on the reflector surface by the field illumination) just calculated:

farfield = Currents2Farfield(currents);
[u,v] = meshgrid(sin(linspace(-20/180*pi,20/180*pi,200)));

And the results are stored into farfield:

D_RHCP_dB = farfield2.D_RHCP_dB;
D_LHCP_dB = farfield2.D_LHCP_dB;
D_V_dB = farfield2.D_V_dB;
D_H_dB = farfield2.D_H_dB;