python: massive improvements to documentation

Signed-off-by: Thorsten Liebig <Thorsten.Liebig@gmx.de>
python
Thorsten Liebig 2016-09-10 23:55:11 +02:00
parent c943590548
commit b45b615f7e
29 changed files with 449 additions and 62 deletions

1
.gitignore vendored
View File

@ -28,3 +28,4 @@ localConfig.cmake
python/**/*.cpp
!python/doc
python/doc/_build
python/doc/Tutorials/__*

View File

@ -0,0 +1,9 @@
Antennas
--------
.. toctree::
:maxdepth: 1
Simple_Patch_Antenna
Helical_Antenna
Bent_Patch_Antenna

View File

@ -0,0 +1,35 @@
Bent Patch Antenna
==================
* Setup & Simulate a bent patch antenna using a cylindrical mesh
Introduction
-------------
**This tutorial covers:**
* Setup of a Bent Patch Antenna (see for comparison: :ref:`simple_patch_antenna`)
* setup of a *cylindrical FDTD mesh*.
* Calculate the S-Parameter and input impedance
* Calculate far-field pattern 2D/3D
Python Script
-------------
Get the latest version `from git <http://www.openems.de/gitweb/?p=openEMS.git;a=blob_plain;f=matlab/Tutorials/Bent_Patch_Antenna.m;hb=refs/heads/master>`_.
.. include:: ./__Bent_Patch_Antenna.txt
Images
-------------
.. figure:: images/Bent_Patch.png
:width: 49%
:alt: alternate text
3D view of the Bent Patch Antenna (AppCSXCAD)
.. figure:: images/Bent_Patch_Pattern.png
:width: 80%
:alt: Farfield pattern
Farfield pattern on an xy- and xz-plane

View File

@ -0,0 +1,32 @@
Helical Antenna
===============
Introduction
-------------
**This tutorial covers:**
* setup of a helix using the wire primitive
* setup a lumped feeding port (R_in = 120 Ohms)
* adding a near-field to far-field (nf2ff) box using an efficient subsampling
* calculate the S-Parameter of the antenna
* calculate and plot the far-field pattern
Python Script
-------------
Get the latest version `from git <http://www.openems.de/gitweb/?p=openEMS.git;a=blob_plain;f=matlab/Tutorials/Helical_Antenna.m;hb=refs/heads/master>`_.
.. include:: ./__Helical_Antenna.txt
Images
-------------
.. figure:: images/Helix_Ant.png
:width: 49%
:alt: alternate text
3D view of the Helical Antenna (AppCSXCAD)
.. figure:: images/Helix_Ant_Pattern.png
:width: 49%
:alt: alternate text
Far-Field pattern showing a right-handed circular polarization.

View File

@ -0,0 +1,10 @@
.. _intro_tutorials:
Introductional Tutorials
------------------------
.. toctree::
Rect_Waveguide
MSL_NotchFilter

View File

@ -0,0 +1,27 @@
Microstrip Notch Filter
=======================
* A straight MSL line with a open-ended stub to create a simple microwave filter.
Introduction
-------------
**This tutorial covers:**
* Setup a mircostrip line (MSL) and MSL port
* Apply an inhomogeneous mesh used for improved accuracy and simulation speed
* Calculate the S-Parameter of the filter
Python Script
-------------
Get the latest version `from git <http://openems.de/gitweb/?p=openEMS.git;a=blob_plain;f=matlab/Tutorials/MSL_NotchFilter.m;hb=HEAD>`_.
.. include:: ./__MSL_NotchFilter.txt
Images
-------------
.. figure:: images/Notch_Filter_SPara.png
:width: 49%
:alt: S-Parameter over Frequency
S-Parameter over Frequency

View File

@ -0,0 +1,27 @@
Rectangular Waveguide
=====================
* A simple rectangular waveguide, showing the openEMS mode profile capabilities.
Introduction
-------------
**This tutorial covers:**
* Setup a mode profile excitation
* Create voltage and current probes using the mode profile
* Calculate the waveguide impedance and S-Parameter
Python Script
-------------
Get the latest version `from git <http://openems.de/gitweb/?p=openEMS.git;a=blob_plain;f=matlab/Tutorials/Rect_Waveguide.m;hb=HEAD>`_.
.. include:: ./__Rect_Waveguide.txt
Images
-------------
.. figure:: images/Rect_WG_SPara.png
:width: 49%
:alt: S-Parameter over Frequency
S-Parameter over Frequency

View File

@ -0,0 +1,42 @@
.. _simple_patch_antenna:
Simple Patch Antenna
====================
Introduction
------------
A simple patch antenna for 2.4 GHz.
**This tutorial covers:**
* Setup a patch, substrate and ground.
* Setup of a lumped feeding port.
* Adding a near-field to far-field (nf2ff) recording box.
* Calculate the S-Parameter of the antenna.
* Calculate and plot the far-field pattern
Python Script
-------------
Get the latest version `from git <http://www.openems.de/gitweb/?p=openEMS.git;a=blob_plain;f=matlab/Tutorials/Simple_Patch_Antenna.m;hb=refs/heads/master>`_.
.. include:: ./__Simple_Patch_Antenna.txt
Images
------
.. figure:: images/Simp_Patch_S11.png
:width: 49%
:alt: S11 over Frequency
S-Parameter over Frequency
.. figure:: images/Simp_Patch_Zin.png
:width: 49%
:alt: Input Impedance
Antenna Input Impedance
.. figure:: images/Simp_Patch_Pattern.png
:width: 49%
:alt: Farfield pattern
Farfield pattern for the xy- and yz-plane.

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -0,0 +1,11 @@
.. _tutorials:
#########
Tutorials
#########
.. toctree::
:maxdepth: 2
Intro_Tutorials
Antenna_Tutorials

View File

@ -291,6 +291,7 @@ texinfo_documents = [
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
numpydoc_show_class_members = False
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'CSXCAD': ('http://openems.de/doc/CSXCAD/', None)}

View File

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
"""
Created on Sat Sep 10 17:12:53 2016
@author: thorsten
"""
import os
import glob
DOC_DIR = os.path.dirname(__file__)
ROOT_DIR = os.path.join(DOC_DIR, '..')
def main():
in_path = os.path.join(ROOT_DIR, 'Tutorials')
fns = glob.glob(os.path.join(in_path, '*.py'))
for fn in fns:
bn = os.path.basename(fn)
out_fn = os.path.join(DOC_DIR, 'Tutorials', '__' + bn.replace('.py', '.txt'))
in_code_block = False
in_ignore_block = False
out_fh = open(out_fn, 'w')
for line in open(fn, 'r'):
if in_ignore_block==False and line.startswith('"""'):
in_ignore_block = True
in_code_block = False
continue
elif in_ignore_block==True and line.startswith('"""'):
in_ignore_block = False
in_code_block = False
continue
elif in_ignore_block==True:
in_code_block = False
continue
elif line.startswith('# -*-'):
continue
elif not line.startswith('##'):
if not in_code_block:
if len(line.strip())==0:
continue
out_fh.write('\n.. code-block:: python\n\n')
in_code_block = True
out_fh.write(' ' + line)
elif line.startswith('###'):
if in_code_block:
out_fh.write('\n')
in_code_block = False
line = line.replace('#','').strip()
out_fh.write('**' + line + '**\n\n')
# out_fh.write('"'*len(line) + '\n')
elif line.startswith('##'):
if in_code_block:
out_fh.write('\n')
in_code_block = False
out_fh.write(line.replace('#','').strip() + '\n')
out_fh.close()
if __name__ == '__main__':
main()

View File

@ -9,9 +9,11 @@ Welcome to openEMS's documentation!
Contents:
.. toctree::
:maxdepth: 4
:maxdepth: 3
Tutorials/index
openEMS_API
openEMS
Indices and tables
==================

16
python/doc/nf2ff.rst Normal file
View File

@ -0,0 +1,16 @@
.. _nf2ff:
NF2FF
-----
.. automodule:: openEMS.nf2ff
NF2FF
-----
.. autoclass:: nf2ff
:members:
NF2FF Results
-----------------
.. autoclass:: nf2ff_results
:members:

View File

@ -1,59 +1,8 @@
openEMS Python Interface
========================
.. _openems:
openEMS
-------
.. automodule:: openEMS.openEMS
.. automodule:: openEMS
:members: openEMS
:undoc-members:
Ports
-----
.. automodule:: openEMS.ports
Port (Base Class)
-----------------
.. autoclass:: Port
:members:
:show-inheritance:
Lumped Port
-----------
.. autoclass:: LumpedPort
:members:
:show-inheritance:
MSL Port
--------
.. autoclass:: MSLPort
:members:
:show-inheritance:
Waveguide Port
--------------
.. autoclass:: WaveguidePort
:members:
:show-inheritance:
Rect Waveguide Port
-------------------
.. autoclass:: RectWGPort
:members:
:show-inheritance:
NF2FF
-----
.. automodule:: openEMS.nf2ff
NF2FF
-----
.. autoclass:: nf2ff
:members:
NF2FF Results
-----------------
.. autoclass:: nf2ff_results
:members:

View File

@ -0,0 +1,11 @@
.. _openems_api:
openEMS Python Interface
========================
.. toctree::
openEMS
ports
nf2ff

37
python/doc/ports.rst Normal file
View File

@ -0,0 +1,37 @@
.. _ports:
Ports
-----
.. automodule:: openEMS.ports
Port (Base Class)
-----------------
.. autoclass:: Port
:members:
:show-inheritance:
Lumped Port
-----------
.. autoclass:: LumpedPort
:members:
:show-inheritance:
MSL Port
--------
.. autoclass:: MSLPort
:members:
:show-inheritance:
Waveguide Port
--------------
.. autoclass:: WaveguidePort
:members:
:show-inheritance:
Rect Waveguide Port
-------------------
.. autoclass:: RectWGPort
:members:
:show-inheritance:

View File

@ -23,6 +23,17 @@ from openEMS import _nf2ff
from openEMS import utilities
class nf2ff:
"""
Create an nf2ff recording box. The nf2ff can either record in time-domain
or frequency-domain. Further more certain directions and boundary condition
mirroring can be enabled/disabled.
:param name: str -- Name for this recording box.
:param start/stop: (3,) array -- Box start/stop coordinates.
:param directions: (6,) bool array -- Enable/Disables directions.
:param mirror: (6,) int array -- 0 (Off), 1 (PEC) or 2 (PMC) boundary mirroring
:param frequency: array like -- List of frequencies (FD-domain recording)
"""
def __init__(self, CSX, name, start, stop, **kw):
self.CSX = CSX
self.name = name
@ -81,6 +92,20 @@ class nf2ff:
CSX.AddBox(self.h_dump, l_start, l_stop)
def CalcNF2FF(self, sim_path, freq, theta, phi, center=[0,0,0], outfile=None, read_cached=True, verbose=0):
""" CalcNF2FF(sim_path, freq, theta, phi, center=[0,0,0], outfile=None, read_cached=True, verbose=0):
Calculate the far-field after the simulation is done.
:param sim_path: str -- Simulation path
:param freq: array like -- list of frequency for transformation
:param theta/phi: array like -- Theta/Phi angles to calculate the far-field
:param center: (3,) array -- phase center, must be inside the recording box
:param outfile: str -- File to save results in. (defaults to recording name)
:param read_cached: bool -- enable/disable read already existing results
:param verbose: int -- set verbose level
:returns: nf2ff_results class instance
"""
if np.isscalar(freq):
freq = [freq]
self.freq = freq
@ -119,6 +144,27 @@ class nf2ff:
return result
class nf2ff_results:
"""
nf2ff result class containing all results obtained by the nf2ff calculation.
Usueally returned from nf2ff.CalcNF2FF
Available attributes:
* `fn` : file name
* `theta`: theta angles
* `phi` : phi angles
* `r` : radius
* `freq` : frequencies
* `Dmax` : directivity over frequency
* `Prad` : total radiated power over frequency
* `E_theta` : theta component of electric field over frequency/theta/phi
* `E_phi` : phi component of electric field over frequency/theta/phi
* `E_norm` : abs component of electric field over frequency/theta/phi
* `E_cprh` : theta component of electric field over frequency/theta/phi
* `E_cplh` : theta component of electric field over frequency/theta/phi
* `P_rad` : radiated power (S) over frequency/theta/phi
"""
def __init__(self, fn):
self.fn = fn
h5_file = h5py.File(fn, 'r')

View File

@ -24,6 +24,30 @@ from . import ports, nf2ff
cdef class openEMS:
""" openEMS
This class is the main control class for the FDTD options and setup and
to run the final simulation.
Examples
--------
>>> CSX = CSXCAD.ContinuousStructure()
>>>
>>> grid = CSX.GetGrid()
>>> grid.SetLines('x', np.arange(-50,50,1))
>>> grid.SetLines('y', np.arange(-50,50,1))
>>> grid.SetLines('z', np.arange(-2,2.1,1))
>>> grid.SetDeltaUnit(1e-3)
>>>
>>> FDTD = openEMS(NrTS=1e4, EndCriteria=1e-4)
>>>
>>> FDTD.SetCSX(CSX)
>>> FDTD.SetBoundaryCond(['PML_8', 'PML_8', 'PML_8', 'PML_8', 'PEC', 'PEC'])
>>> FDTD.SetGaussExcite(0, 10e9)
>>>
>>> FDTD.AddLumpedPort(port_nr=1, R=50, start=[10, 0, -2], stop=[10, 0, 2], p_dir='z', excite=1)
>>>
>>> FDTD.Run(sim_path='/tmp/test')
:param NrTS: max. number of timesteps to simulate (e.g. default=1e9)
:param EndCriteria: end criteria, e.g. 1e-5, simulations stops if energy has decayed by this value (<1e-4 is recommended, default=1e-5)
:param MaxTime: max. real time in seconds to simulate
@ -300,7 +324,7 @@ cdef class openEMS:
See Also
--------
CSXCAD.CSXCAD.ContinuousStructure
CSXCAD.ContinuousStructure
"""
self.__CSX = CSX
self.thisptr.SetCSX(CSX.thisptr)

View File

@ -41,6 +41,19 @@ class UI_data:
# Port Base-Class
class Port:
"""
The port base class.
:param CSX: Continuous Structure
:param port_nr: int -- port number
:param R: float -- port reference impedance, e.g. 50 (Ohms)
:param start, stop: (3,) array -- Start/Stop box coordinates
:param p_dir: int -- port direction
:param excite: float -- port excitation amplitude
:param priority: int -- priority of all contained primtives
:param PortNamePrefix: str -- a prefix for all ports-names
:param delay: float -- a positiv delay value to e.g. emulate a phase shift
"""
def __init__(self, CSX, port_nr, start, stop, excite, **kw):
self.CSX = CSX
self.number = port_nr
@ -123,12 +136,9 @@ class LumpedPort(Port):
"""
The lumped port.
:param CSX: Continuous Structure
:param port_nr: int -- port number
:param R: float -- port reference impedance, e.g. 50 (Ohms)
:param start, stop: (3,) array -- Start/Stop box coordinates
:param p_dir: int -- port direction
:param excite: float -- port excitation amplitude
See Also
--------
Port
"""
def __init__(self, CSX, port_nr, R, start, stop, exc_dir, excite=0, **kw):
super(LumpedPort, self).__init__(CSX, port_nr=port_nr, start=start, stop=stop, excite=excite, **kw)
@ -175,6 +185,15 @@ class LumpedPort(Port):
super(LumpedPort, self).CalcPort(sim_path, freq, ref_impedance, ref_plane_shift, signal_type)
class MSLPort(Port):
"""
The microstrip transmission line port.
:param prop_dir: int/str -- direction of propagation
See Also
--------
Port
"""
def __init__(self, CSX, port_nr, metal_prop, start, stop, prop_dir, exc_dir, excite=0, **kw):
super(MSLPort, self).__init__(CSX, port_nr=port_nr, start=start, stop=stop, excite=excite, **kw)
self.exc_ny = CheckNyDir(exc_dir)
@ -287,6 +306,16 @@ class MSLPort(Port):
self.Z_ref = np.sqrt(Et * dEt / (Ht * dHt))
class WaveguidePort(Port):
"""
Base class for any waveguide port.
:param mode_name: str -- Mode name, e.g. TE11 or TM10
See Also
--------
Port, RectWGPort
"""
def __init__(self, CSX, port_nr, start, stop, exc_dir, mode_name, excite=0, **kw):
super(WaveguidePort, self).__init__(CSX, port_nr=port_nr, start=start, stop=stop, excite=excite, **kw)
self.exc_ny = CheckNyDir(exc_dir)
@ -324,6 +353,9 @@ class WaveguidePort(Port):
CSX.AddBox(i_probe, m_start, m_stop)
def InitMode(self, wg_mode):
"""
Init/Define waveguide mode, e.g. TE11, TM10.
"""
self.WG_mode = wg_mode
assert len(self.WG_mode)==4, 'Invalid mode definition'
self.unit = self.CSX.GetGrid().GetDeltaUnit()
@ -348,11 +380,24 @@ class WaveguidePort(Port):
super(WaveguidePort, self).CalcPort(sim_path, freq, ref_impedance, ref_plane_shift, signal_type)
class RectWGPort(WaveguidePort):
"""
Rectangular waveguide port.
:param a,b: float -- Width/Height of rectangular waveguide port
See Also
--------
Port, WaveguidePort
"""
def __init__(self, CSX, port_nr, start, stop, exc_dir, a, b, mode_name, excite=0, **kw):
self.WG_size = [a, b]
super(RectWGPort, self).__init__(CSX, port_nr=port_nr, start=start, stop=stop, exc_dir=exc_dir, mode_name=mode_name, excite=excite, **kw)
def InitMode(self, wg_mode):
"""
Init/Define rectangular waveguide mode, e.g. TE11, TM10.
"""
super(RectWGPort, self).InitMode(wg_mode)
assert self.TE, 'Currently only TE-modes are supported! Mode found: {}'.format(self.WG_mode)