New features
- New option in MPLOT interface to export MSES field data and airfoil geometry to either/both a Tecplot (`.dat`) file or Paraview XML (`.vtp` and `.vts`) ASCII files
- Added the ability to modify only one side of a Bézier curve joint when applying a radius of curvature constraint. This is useful when one of the two curves must remain fixed. In this case, the default value used for the radius of curvature in the GUI when applying an `ROCConstraint` is simply the value of the radius of curvature at the endpoint of the curve being fixed rather than the average radius of curvature value at the endpoints of both curves. Instructions for how to apply the constraint this way appear in the status bar (lower left-hand part of the GUI)
- Added normalization options to `pymead.post.mses_field.generate_field_matplotlib`
- Added an experimental rational Bézier curve class to the API (see the `pymead.core.rbezier` module)
- Added an experimental B-spline class to the API (see the `pymead.core.bspline` module)
- Added a hodograph method to the Bézier class
- Added an experimental NACA 4-series airfoil feature to the API (see the `pymead.core.naca4` module)
- Baseline and optimized airfoil system from each generation are now saved to `.jmea` files during optimization runs
- Added an experimental Wagner function curve class to the API (see the `pymead.core.wagner` module)
- Added option to skip geometric constraint evaluation on a `Chromosome` when post-processing an optimization
- Added multipoint tag option for field/grid/grid statistics files
- Added the keyword argument `"direct_user_request"` to `Param.set_value` that determines whether point parameter values should be set directly or if `Point.request_move` should be called instead
- Added Ferguson's curves to both the API (see the `pymead.core.ferguson` module) and the GUI
- Added "Verify Constraints" feature to the "Dev" toolbar item in the GUI. This allows users to ensure that their system of constraints is working properly. Especially useful for complex airfoil systems
- Added several example airfoil systems to the GUI
- Added a feature where fan pressure ratio can be used as a design variable in optimizations
- Added a "File already exists. Overwrite?" dialog that executes during `GUI.save_as_geo_col`
- Hovering is now ignored for all objects when a point is being dragged
- Added a relative-airfoil point feature. This allows points to move with affine transformations (translation, rotation, etc.) of the airfoil. This option can be toggled from the parameter tree or the context menu of "Modify Geometry" in the airfoil canvas
- Keyboard tracking is now set to false for spin boxes to prevent updates from happening until typing is finished
- Added optimization geometric constraint visualization for maximum thickness, minimum radius, thickness distribution, internal geometry, and minimum area in the "Constraints" tab of the optimization setup dialog
- Added a CPU/RAM usage visualization tab that automatically runs during optimization
- Changed the default function tolerance for termination from `0.0025` (as suggested by `pymoo` for multi-point optimizations) to `1e-6` (as suggested by `pymoo` for single-point optimization). The best value to use depends on the objective function. For example, a smaller value should probably be used if drag coefficient is the objective function since $C_d$ usually takes on a value much less than 1.
Bug fixes
- Fixed bug where deleting a point would not delete its associated `x` and `y` parameters
- Fixed bug where a point could not be removed after creating `x` or `y` parameters/design variables
- Fixed bug where deleting angle constraints in specific sequences would not properly set a new constraint cluster root and would not properly re-orient arrows
- Fixed bug where `ClusterAngle` parameters would sometimes not get automatically removed when deleting some constraints in specific sequences
- An error message now appears in the GUI when a user tries to promote a Point `x` or `y` parameter that has constraints and is not a root of a constraint cluster
- An error message now appears in the GUI when a user tries to add a constraint across points that have promoted `x` or `y`-values
- Fixed bug where progress bar would not reset after MPOLAR failure
- An error message now appears in the GUI when MPOLAR fails to converge
- Fixed broken URL path to `pymead` user guide location in help browser window
- Fixed bug where `ValueSpin` could be negative even if value was non-negative
- Fixed bug where bounds-normalized point values were treated as absolute
- Fixed bug where loading in an optimized airfoil system and running the same MSES settings gave a different result than the optimum outcome
- Added zero curvature handling for proper radius of curvature constraint verification
- Fixed a bug where optimized airfoil design variable vectors were not properly decoded in the GUI
- Fixed bug where symmetry constraints would not update properly from design variable change
- Fixed bug where angle verification would fail incorrectly
- Fixed objective and constraint bugs in optimization
- Fixed bug in `GeometryCollection.assign_design_variable_values`
- Created GUI error message instead of early terminating for plotting Mach contours, etc. with MSES analysis if `MuPDF` or `ps2pdf` were not found on the system path
- A GUI error is now thrown if an airfoil being analyzed in XFOIL has more than 495 coordinates (a hard-coded limit in XFOIL)
- Fixed no GUI error being thrown when trying to visualize downsampling on an empty/non-existent MEA
- Fixed bug in internal geometry visualization
- Fixed bug in `Airfoil.contains_line_string`
- Added a GUI error message for when MPOLAR fails at first point
- Fixed a bug in MPOLAR runs from the GUI
- Fixed a bug in XFOIL multipoint optimization
- Fixed a bug in airfoil statistics
- Fixed bug where an optimization pool would not always properly terminate, especially with heavy CPU and/or RAM usage. See `pymead.utils.pymead_mp.pool_terminate_multi_tiered`
- Fixed bug in `Airfoil.check_contains_points`
- Fixed bug where `n_eval` could return `None` after an optimization
Aesthetics
- Made sampling preview adhere to the global theme
- Updated `PymeadLabeledColorSelector` to reflect the global theme
- Updated suggested width and height values for many dialogs
- Made `PymeadDialog` subclass `FramelessDialog` instead of `QDialog` so that the dialog windows have the same unified style as the GUI title bar
Unit testing
- Added additional GUI unit tests, including testing of the XFOIL analysis, MSES analysis, match airfoil, and help browser features