|
| 1 | +Application Interface Abstraction |
| 2 | +================================= |
| 3 | +Many Ansys applications are designed around user interaction within a |
| 4 | +desktop GUI-based environment. Consequently, scripts are recorded |
| 5 | +directly from user sessions and are in the context of manipulating the |
| 6 | +desktop application. Instead, scripts should be written for an API |
| 7 | +that is structured around data represented as classes and methods. |
| 8 | + |
| 9 | +PyAnsys seeks to make the API a "first class citizen" in regard to |
| 10 | +interacting with an Ansys product by presenting the product as a |
| 11 | +stateful data model. Consider the following comparison between using a |
| 12 | +recorded script from AEDT versus using the PyAEDT libary to create an |
| 13 | +open region in the active editor: |
| 14 | + |
| 15 | ++------------------------------------------------------+----------------------------------------------+ |
| 16 | +| Using AEDT with MS COM Methods | Using AEDT with the `PyAEDT`_ Library | |
| 17 | ++------------------------------------------------------+----------------------------------------------+ |
| 18 | +| .. code:: python | .. code:: python | |
| 19 | +| | | |
| 20 | +| import sys | from pyaedt import Hfss | |
| 21 | +| import pythoncom | | |
| 22 | +| import win32com.client | hfss = Hfss() | |
| 23 | +| | hfss.create_open_region(frequency="1GHz") | |
| 24 | +| # initialize the desktop using pythoncom | | |
| 25 | +| Module = sys.modules['__main__'] | | |
| 26 | +| oDesktop = Module.oDesktop | | |
| 27 | +| oProject = oDesktop.SetActiveProject("Project1") | | |
| 28 | +| oDesign = oProject.SetActiveDesign("HFSSDesign1") | | |
| 29 | +| oEditor = oDesign.SetActiveEditor("3D Modeler") | | |
| 30 | +| oModule = oDesign.GetModule("BoundarySetup") | | |
| 31 | +| | | |
| 32 | +| # create an open region | | |
| 33 | +| parm = [ | | |
| 34 | +| "NAME:Settings", | | |
| 35 | +| "OpFreq:=", "1GHz", | | |
| 36 | +| "Boundary:=", "Radition", | | |
| 37 | +| "ApplyInfiniteGP:=", False | | |
| 38 | +| ] | | |
| 39 | +| oModule.CreateOpenRegion(parm) | | |
| 40 | ++------------------------------------------------------+----------------------------------------------+ |
| 41 | + |
| 42 | +Besides length and readability, the biggest difference between the two |
| 43 | +approaches is how the methods and attributes from the ``Hfss`` class |
| 44 | +are encapsulated. For example, AEDT no longer needs to be |
| 45 | +explicitly instantiated and is hidden as a protected attribute |
| 46 | +``_desktop``. The connection to the application takes place |
| 47 | +automatically when ``Hfss`` is instantiated, and the active AEDT |
| 48 | +project, editor, and module are automatically used to create the |
| 49 | +open region. |
| 50 | + |
| 51 | +Furthermore, the ``create_open_region`` method within ``Hfss`` |
| 52 | +contains a full Python documentation string with keyword arguments, |
| 53 | +clear ``numpydoc`` parameters and returns, and a basic example. |
| 54 | +These are unavailable when directly using COM methods, preventing |
| 55 | +the use of contextual help from within a Python IDE. |
| 56 | + |
| 57 | +The source of the ``hfss.py`` method within`PyAEDT`_ follows. |
| 58 | +Note how calls to the COM object are all encapsulated |
| 59 | +within this method. |
| 60 | + |
| 61 | +.. code:: python |
| 62 | +
|
| 63 | + def create_open_region(self, frequency="1GHz", boundary="Radiation", |
| 64 | + apply_infinite_gp=False, gp_axis="-z"): |
| 65 | + """Create an open region on the active editor. |
| 66 | +
|
| 67 | + Parameters |
| 68 | + ---------- |
| 69 | + frequency : str, optional |
| 70 | + Frequency with units. The default is ``"1GHz"``. |
| 71 | + boundary : str, optional |
| 72 | + Type of the boundary. The default is ``"Radiation"``. |
| 73 | + apply_infinite_gp : bool, optional |
| 74 | + Whether to apply an infinite ground plane. The default is ``False``. |
| 75 | + gp_axis : str, optional |
| 76 | + The default is ``"-z"``. |
| 77 | +
|
| 78 | + Returns |
| 79 | + ------- |
| 80 | + bool |
| 81 | + ``True`` when successful, ``False`` when failed. |
| 82 | +
|
| 83 | + Examples |
| 84 | + -------- |
| 85 | + Create an open region in the active editor at 1 GHz. |
| 86 | +
|
| 87 | + >>> hfss.create_open_region(frequency="1GHz") |
| 88 | + |
| 89 | + """ |
| 90 | + vars = [ |
| 91 | + "NAME:Settings", |
| 92 | + "OpFreq:=", frequency, |
| 93 | + "Boundary:=", boundary, |
| 94 | + "ApplyInfiniteGP:=", apply_infinite_gp |
| 95 | + ] |
| 96 | + if apply_infinite_gp: |
| 97 | + vars.append("Direction:=") |
| 98 | + vars.append(gp_axis) |
| 99 | +
|
| 100 | + self._omodelsetup.CreateOpenRegion(vars) |
| 101 | + return True |
| 102 | +
|
| 103 | +Here, the COM ``CreateOpenRegion`` method is abstracted, encapsulating |
| 104 | +the model setup object. There's no reason why a user needs direct |
| 105 | +access to ``_omodelsetup``, which is why it's protected in the |
| 106 | +``Hfss`` class. Additionally, calling the method is simplified by |
| 107 | +providing (and documenting) the defaults using keyword arguments and |
| 108 | +placing them into the ``vars`` list, all while following the `Style |
| 109 | +Guide for Python Code (PEP8)`_. |
| 110 | + |
| 111 | +.. _PyAEDT: https://github.com/pyansys/PyAEDT |
| 112 | +.. _Style Guide for Python Code (PEP8): https://www.python.org/dev/peps/pep-0008 |
0 commit comments