Skip to content

Commit

Permalink
Merge branch 'release-3.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
camUrban committed Jun 22, 2023
2 parents 49a95c7 + 872e5b6 commit d60a060
Show file tree
Hide file tree
Showing 40 changed files with 5,063 additions and 352 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,10 @@ cython_debug/
/tests/integration/fixtures/_trial_temp/
/tests/unit/_trial_temp/
/tests/unit/fixtures/_trial_temp/

# These are folders and files created by releasing.

/build
/dist
/Output
.spec
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/psf/black
rev: 22.6.0
rev: 23.3.0
hooks:
- id: black
language_version: python3.8
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ before_install:
- git clone --depth 1 https://github.com/pyvista/gl-ci-helpers.git
- source ./gl-ci-helpers/travis/setup_headless_display.sh
install:
- pip install -r requirements.txt
- pip install -r requirements_dev.txt
- pip install -r requirements_ci.txt
script:
- coverage run --source=pterasoftware -m unittest discover -s tests
- codecov
27 changes: 27 additions & 0 deletions BUILD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Packaging

There are 2 available packaging formats: Installer or wheel. The former is what is distributed, while the latter is
required for use of the CLI for instance.

When packaging don't forget to check versions in both `setup.py` and `make_installer.iss` and ensure they match!

### Installer

**Currently, this is only supported on Windows.**

The installer uses `PyInstaller` to extract all the dependencies and `InnoSetup` to create a Windows installer package
out of them.

1. Ensure you have installed `InnoSetup` [here](https://jrsoftware.org/isdl.php).

2. Inside the root repository directory with the virtualenv active:

```commandline
python -O -m PyInstaller --noconfirm "pterasoftware.spec"
```

We run `python` with the first level optimise flag `-O` to slim down some now unnecessary debug code. *Do not use second
level optimisation `-OO`, as this removes some docstrings that break dependencies.*

3. Open `make_installer.iss` in InnoSetup and run the packaging process. This can take a while, but should output an
installer in the `Output` folder.
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 Cameron Urban
Copyright (c) 2023 Cameron Urban

Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
Expand Down
82 changes: 45 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

***

![build](https://img.shields.io/travis/camUrban/PteraSoftware/master)
![build](https://app.travis-ci.com/camUrban/PteraSoftware.svg?branch=master)
![coverage](https://img.shields.io/codecov/c/gh/camUrban/PteraSoftware/master)
![code quality](https://img.shields.io/codefactor/grade/github/camUrban/PteraSoftware/master)
![source rank](https://img.shields.io/librariesio/sourcerank/pypi/PteraSoftware?color=blue&label=source%20rank)
Expand Down Expand Up @@ -38,6 +38,10 @@ born. It is an easy-to-use, open-source, and actively-maintained UVLM package ca
of analyzing flapping-wing flight. Moreover, it's written in Python, is well
documented, tested, and validated.

Beginning with version 3.0.0, Ptera Software also includes a GUI developed by Zach Tait.
Although it is still rudimentary, we hope that it will help make this tool accessible to
even more users.

With your help, I hope we will increase the open-source community's interest and
understanding of biological flight.

Expand Down Expand Up @@ -77,7 +81,10 @@ understanding of biological flight.
* Ptera Software is focused on developing features to facilitate designing
flapping-wing vehicles.
* For example, use the functions in the trim module to automatically search for a
trim operating point for steady and unsteady simulations of aircraft.
trim operating point for steady and unsteady simulations of aircraft.
8. A Basic GUI
* This is still in its beta stage, but we will be adding more functionality over the
next several releases.

## Installation and Use

Expand Down Expand Up @@ -143,49 +150,51 @@ contribute to this, feel free to open a feature request issue and start a conver

### What If I'm Having Trouble Getting Set Up?

Not to worry! I am working on a video that walks through getting Ptera Software up and
running. It will include every step, from downloading Python for the first time to
setting up your IDE to running the software. In the meantime, feel free to open an
issue for guidance.
Not to worry! I've made [a video](https://www.youtube.com/watch?v=oX8u2ZflJM4) that walks through getting Ptera Software up and
running. It includes every step, from downloading Python for the first time to setting
up your IDE to running the software. If you still run into problems, feel free to open
an issue for guidance.

## Example Code

The following code snippet is all that is needed (after running pip install
pterasoftware) to run the steady horseshoe solver on a custom airplane object.
pterasoftware) to run the steady horseshoe solver on an airplane with custom geometry.

```
import pterasoftware as ps
example_airplane = ps.geometry.Airplane(
airplane = ps.geometry.Airplane(
wings=[
ps.geometry.Wing(
symmetric=True,
wing_cross_sections=[
ps.geometry.WingCrossSection(
airfoil=ps.geometry.Airfoil(name="naca2412",),
airfoil=ps.geometry.Airfoil(name="naca2412"),
),
ps.geometry.WingCrossSection(
y_le=5.0, airfoil=ps.geometry.Airfoil(name="naca2412",),
y_le=5.0,
airfoil=ps.geometry.Airfoil(name="naca2412"),
),
],
),
],
)
example_operating_point = ps.operating_point.OperatingPoint()
operating_point = ps.operating_point.OperatingPoint()
example_problem = ps.problems.SteadyProblem(
airplane=example_airplane,
operating_point=example_operating_point
problem = ps.problems.SteadyProblem(
airplanes=[airplane], operating_point=operating_point
)
example_solver = ps.steady_horseshoe_vortex_lattice_method.SteadyHorseshoeVortexLatticeMethodSolver(
steady_problem=example_problem
solver = (
ps.steady_horseshoe_vortex_lattice_method.SteadyHorseshoeVortexLatticeMethodSolver(
steady_problem=problem
)
)
example_solver.run()
solver.run()
ps.output.draw(solver=example_solver, show_delta_pressures=True, show_streamlines=True)
ps.output.draw(solver=solver, scalar_type="lift", show_streamlines=True)
```

## Example Output
Expand Down Expand Up @@ -214,24 +223,26 @@ examples of the output you can expect to receive from each of them.

Here are the requirements necessary to run Ptera Software:

* matplotlib >= 3.5.2, < 4.0.0
* numpy >= 1.22.4, < 1.24.0
* pyvista >= 0.34.1, < 1.0.0
* scipy >= 1.8.1, < 2.0.0
* numba >= 0.55.2, < 1.0.0
* cmocean >= 2.0.0, < 3.0.0
* tqdm >= 4.64.0, < 5.0.0
* webp >= 0.1.4, < 1.0.0
* matplotlib >= 3.7.1, < 4.0.0
* numpy >= 1.24.3, < 1.25.0
* pyvista >= 0.39.1, < 1.0.0
* scipy >= 1.10.1, < 2.0.0
* numba >= 0.57.1, < 1.0.0
* cmocean >= 3.0.3, < 4.0.0
* tqdm >= 4.65.0, < 5.0.0
* webp >= 0.1.6, < 1.0.0
* PySide2 >= 5.15.2.1, < 6.0.0.0

Additionally, these packages are useful for continued development of the software:

* codecov >= 2.1.12, < 3.0.0
* black >= 22.6.0, < 23.0.0
* pre-commit >= 2.19.0, < 3.0.0
* build >= 0.8.0, < 1.0.0
* twine >= 4.0.1, < 5.0.0
* setuptools >= 62.6.0, < 63.0.0
* wheel >= 0.37.1, < 0.38.0
* codecov >= 2.1.13, < 3.0.0
* black >= 23.3.0, < 24.0.0
* pre-commit >= 3.3.3, < 4.0.0
* build >= 0.10.0, < 1.0.0
* twine >= 4.0.2, < 5.0.0
* PyInstaller >= 5.12.0, < 6.0.0
* setuptools >= 68.0.0, < 69.0.0
* wheel >= 0.40.0, < 1.0.0

## Validation

Expand Down Expand Up @@ -265,13 +276,9 @@ results. This means getting rid of all the "test_method_does_not_throw" tests.

### Features

* We should create a setup tutorial video and add it to the documentation. This should
be geared toward a user who doesn't have Python, an IDE, or Ptera Software installed on
their computer yet.
* We should implement a leading-edge model to account for flow separation. See
"Modified Unsteady Vortex-Lattice Method to Study Flapping Wings in Hover Flight." by
Bruno Roccia, Sergio Preidikman, Julio Massa, and Dean Mook for details.
* We should create a command-line interface or GUI.
* We should try to implement aeroelastic effects in Ptera Software's solvers.
* Flapping wing controls is both fascinating and complicated. We should try to create a
workflow in Ptera Software for controls systems identification for flapping-wing
Expand All @@ -285,6 +292,7 @@ where applicable.

* Suhas Kodali
* Peter Sharpe
* Zach Tait
* Ramesh Agarwal
* Joseph Katz
* Allen Plotkin
Expand Down
Empty file added benchmarks/__init__.py
Empty file.
Binary file added docs/Black_Text_Logo.ico
Binary file not shown.
Binary file added docs/Black_Text_Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/Logo.ico
Binary file not shown.
Empty file added docs/__init__.py
Empty file.
Empty file added examples/__init__.py
Empty file.
Empty file added formation flight/__init__.py
Empty file.
109 changes: 109 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
"""This script opens the GUI to demonstrate Ptera Software analyzing example models.
It is in development and will be able to run custom models in the future"""

import os
import sys
import time
import importlib

print("Builtin modules imported")
from PySide2.QtCore import Qt

print("QTCore imported")
from PySide2.QtGui import QPixmap

print("QtGUI imported")
from PySide2.QtWidgets import QMainWindow, QApplication, QSplashScreen, QDialog

from pterasoftware.ui_resources.main_window import Ui_MainWindowDesign
from pterasoftware.ui_resources.textdialog import Ui_TextAboutDialog


class TextAboutDialog(QDialog):
def __init__(self, title):
super(TextAboutDialog, self).__init__()
self.ui = Ui_TextAboutDialog()
self.ui.setupUi(self)
self.setWindowTitle(title)


class MainWindow(QMainWindow, Ui_MainWindowDesign):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)

self.actionExample_1.triggered.connect(lambda x: self.exampleMenu(0))
self.actionExample_2.triggered.connect(lambda x: self.exampleMenu(1))
self.actionExample_3.triggered.connect(lambda x: self.exampleMenu(2))
self.actionExample_4.triggered.connect(lambda x: self.exampleMenu(3))
self.actionExample_5.triggered.connect(lambda x: self.exampleMenu(4))
self.actionExample_6.triggered.connect(lambda x: self.exampleMenu(5))
self.actionExample_7.triggered.connect(lambda x: self.exampleMenu(6))
self.actionExample_8.triggered.connect(lambda x: self.exampleMenu(7))
self.actionExample_9.triggered.connect(lambda x: self.exampleMenu(8))
self.actionExample_10.triggered.connect(lambda x: self.exampleMenu(9))

self.actionAbout.triggered.connect(self.menuREADME)

self.displayText = ""

def exampleMenu(self, ex_num):

files = []
for i, filename in enumerate(os.listdir("examples")):
f = "examples." + filename
files.append(f)
file = files[ex_num]
file = file.replace(".py", "")
self.printTerminalOutput(f"Example {ex_num + 1} executed")
print(file)
importlib.import_module(file)

def printTerminalOutput(self, text):
print("Printing terminal output")
self.terminalOutput.addItem(f"{text}")
self.terminalOutput.scrollToBottom()

def updateDisplayText(self, text):
self.displayText = text
self.printTerminalOutput(self, text)

def menuREADME(self):
from PySide2.QtGui import QTextDocument

self.dialog = TextAboutDialog("About Ptera Software")
doc = QTextDocument()
doc.setMarkdown(self._read_file("README.md"))
self.dialog.ui.textEdit.setDocument(doc)
self.dialog.show()

def _read_file(self, file_path: str) -> str:
from PySide2.QtCore import QFile
from PySide2.QtCore import QTextStream
from PySide2.QtCore import QIODevice

file = QFile(file_path)
file.open(QIODevice.ReadOnly)
ts = QTextStream(file)
string = ts.readAll()
return string


if __name__ == "__main__":
app = QApplication(sys.argv)
pixmap = QPixmap("docs/logo.png")
splash = QSplashScreen(pixmap)
splash.setWindowFlags(Qt.WindowStaysOnTopHint)
splash.setEnabled(False)
splash.setMask(pixmap.mask())
splash.show()
time.sleep(1)
app.processEvents()

window = MainWindow()
window.show()
window.raise_()
window.activateWindow()
splash.finish(window)
sys.exit(app.exec_())
print("Exiting")
59 changes: 59 additions & 0 deletions make_installer.iss
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "PteraSoftware"
#define MyAppVersion "3.0.0"
#define MyAppPublisher "CamUrban"
#define MyAppURL "https://github.com/camUrban/PteraSoftware"
#define MyAppExeName "PteraSoftware.exe"
#define MyAppAssocName MyAppName + " File"
#define MyAppAssocExt ".myp"
#define MyAppAssocKey StringChange(MyAppAssocName, " ", "") + MyAppAssocExt

[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{F8405B7D-3F5B-4F81-BD8B-7C5D1F052165}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppName}
ChangesAssociations=yes
DisableProgramGroupPage=yes
LicenseFile=C:\Users\zacht\PycharmProjects\PteraSoftware\LICENSE.txt
; Uncomment the following line to run in non administrative install mode (install for current user only.)
;PrivilegesRequired=lowest
OutputBaseFilename=PteraSoftware_installer
Compression=lzma
SolidCompression=yes
WizardStyle=modern

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: "C:\Users\zacht\PycharmProjects\PteraSoftware\dist\main\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Users\zacht\PycharmProjects\PteraSoftware\dist\main\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Registry]
Root: HKA; Subkey: "Software\Classes\{#MyAppAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#MyAppAssocKey}"; ValueData: ""; Flags: uninsdeletevalue
Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#MyAppAssocName}"; Flags: uninsdeletekey
Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""
Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".myp"; ValueData: ""

[Icons]
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

Loading

0 comments on commit d60a060

Please sign in to comment.