-
-
Notifications
You must be signed in to change notification settings - Fork 51
Feature/properties #94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Refactored the Airfoil class to store numpy arrays as private attributes and expose them via read-only properties. All numpy arrays are now made immutable to prevent external mutation, and deep copies are enforced during validation and copying. This improves encapsulation and data safety for Airfoil geometry data.
Refactored WingCrossSection to make key attributes immutable via private fields and read-only properties, with numpy arrays set as read-only. Added set-once enforcement for validated and symmetry_type attributes. Updated fixtures and tests to verify immutability and deep copy behavior, ensuring attributes cannot be modified after initialization except for control_surface_symmetry_type.
Refactored the Wing class to store key attributes as private and enforce immutability via read-only properties and set-once setters. Numpy arrays for geometry are now made read-only, and mesh metadata is set-once. Updated deepcopy logic to respect immutability and set-once semantics. Added caching for derived properties. Updated unit tests to use fresh fixtures for each test and added tests for immutability, set-once enforcement, and tuple immutability.
Introduces a temporary comprehensive benchmarking script to measure UnsteadyProblem object creation time under various configurations, including static and variable geometry, different panel counts, and cycle numbers. Results are saved as JSON for later comparison, and the script supports listing and comparing benchmark runs.
… vortex planning doc Added a section explaining how numpy arrays are made immutable using `arr.flags.writeable = False` to prevent in-place mutation via read-only properties. Also updated code examples to use `cast(np.ndarray, ...)` for clarity and type safety.
Refactors the Panel class to make key geometric attributes immutable and read-only, and introduces set-once properties for mesh and global geometry metadata. Removes setters for corner points, enforces single-assignment for mesh metadata and global positions, and updates all internal logic to use the new attribute structure. This improves data integrity, prevents accidental mutation, and clarifies the distinction between immutable, set-once, and cached properties.
Moved Panel-related test fixtures from geometry_fixtures.py to a new panel_fixtures.py module and updated imports accordingly. Expanded panel_fixtures.py with additional fixture functions for various panel configurations. Updated test_panel.py to use the new fixtures and added comprehensive tests for Panel immutability, set-once properties, and deep copy behavior.
The LineVortex class was moved from _aerodynamics_functions.py to a new module _vortices/_line_vortex.py. All references and imports throughout the codebase, including in horseshoe_vortex.py, ring_vortex.py, movement.py, fixtures, and tests, were updated to use the new location and class name. Documentation was updated to reflect the new class name and location.
Added `flags.writeable = False` to all derived cached numpy arrays in the Panel class to enforce immutability. Updated documentation to reflect this change and clarified the immutability strategy for all vortex-related classes.
Refactors the LineVortex class to make the start and end points immutable after initialization, removing their property setters and related cache invalidation logic. Updates tests to remove cases that relied on mutating these attributes.
Refactors HorseshoeVortex to make geometric attributes (front points, leg vector, leg length) immutable after construction, removing their setters and related cache invalidation logic. Updates property access and internal caching accordingly. Removes tests that relied on mutability of these attributes, retaining only strength mutability and its propagation to legs.
Refactored RingVortex to make corner positions immutable after construction, removing setters and related cache invalidation logic. Updated unsteady_ring_vortex_lattice_method to create new RingVortex objects with updated corners instead of mutating existing ones. Removed unit tests that relied on mutating corner positions and cache invalidation.
Introduces new test classes to verify attribute immutability and lazy caching behavior for LineVortex objects. Updates __init__.py files to include new test and fixture modules for LineVortex.
Add new test classes for immutability and lazy caching behavior of HorseshoeVortex attributes. Remove redundant or superseded tests and improve clarity of test names and docstrings.
Introduces new test classes to verify attribute immutability and lazy caching behavior in RingVortex. Removes redundant tests for initial age and area property.
Expanded and clarified the GEOMETRY_PLAN.md to detail immutable, set-once, and mutable attribute patterns for Airplane, Wing, WingCrossSection, and Airfoil classes. Added guidance on numpy array immutability, manual lazy caching for derived properties, and correct deepcopy handling for caches. Updated PANEL_VORTEX_PLAN.md to reflect implementation status. Added new unsteady problem benchmark results.
…_PLAN.md Standardized and clarified the __deepcopy__ implementation for Airfoil, improving docstrings and attribute handling. Updated section comments for consistency and readability.
…ate with GEOMETRY_PLAN.md Refactored WingCrossSection to lazily evaluate and cache the derived transformation matrices T_pas_Wcsp_Lpp_to_Wcs_Lp and T_pas_Wcs_Lp_to_Wcsp_Lpp. Updated __deepcopy__ to preserve cached matrices, improved docstrings, and removed redundant property implementations. This change improves performance by avoiding repeated computation of transformation matrices.
…GEOMETRY_PLAN.md changes Reorganized the Wing class to use manual lazy caching for derived properties, separating caches for immutable and set-once attributes. Moved property definitions and docstrings for set-once attributes and their derived properties, and updated the deepcopy method to preserve or reset caches appropriately. Improved code clarity and maintainability by grouping related logic and updating comments.
Refactored the Airplane class to make core attributes (wings, name, Cg_GP1_CgP1, weight, s_ref, c_ref, b_ref) immutable and read-only, storing them as private variables with property accessors. Updated derived properties (num_panels, T_pas_G_Cg_to_GP1_CgP1) to use lazy evaluation and caching. Removed unit tests that relied on mutability and direct assignment of these attributes.
Introduces Airplane.deep_copy_with_Cg_GP1_CgP1 to create deep copies with a specified Cg_GP1_CgP1 position, supporting immutable airplane instances with different positions. Updates AirplaneMovement to use this method instead of deepcopy and manual attribute assignment, improving clarity and correctness.
…data Added comprehensive unit tests for the Wing.average_panel_aspect_ratio property and the Wing.get_plottable_data method, including input validation, caching, and output structure. Also added tests for transformation matrix caching and immutability. Removed obsolete test comments and updated docstrings for clarity.
Corrects the sign of the translation vector in the T_pas_G_Cg_to_GP1_CgP1 property to ensure the transformation matrix is computed correctly. Also removes outdated test comments.
Introduces comprehensive unit tests for Airplane attribute immutability, deep copy with Cg_GP1_CgP1, transformation matrix property, plottable data, and draw methods. Adds a follower airplane fixture for transformation tests. Updates documentation to indicate geometry class plan is implemented.
…es from PANEL_VORTEX_PLAN.md and GEOMETRY_PLAN.md
Added docs/OPERATING_POINT_MOVEMENT_PROBLEM_PLAN.md detailing the planned refactor for immutability and lazy caching patterns in OperatingPoint, movement, and problem classes.
Refactored OperatingPoint to use private immutable attributes with read-only properties. Added manual lazy caching for derived properties and ensured cached numpy arrays are read-only. Expanded test coverage with new fixtures for edge cases and added tests for immutability, caching, and numerical stability.
Refactored SteadyProblem to store airplanes and operating_point as private, immutable attributes and expose them as read-only properties. Changed reynolds_numbers to return a cached tuple instead of a list, ensuring immutability. Updated documentation and tests to reflect these changes, and added new tests for immutability and caching behavior.
Refactored OperatingPointMovement to store initialization parameters as private attributes and expose them via read-only properties, ensuring immutability. Updated tests to verify immutability and type conversion of parameters. Removed redundant tests and improved test coverage for attribute access.
Implements a custom __deepcopy__ method for WingCrossSectionMovement to ensure numpy arrays remain read only and caches are reset after copying. Refactors attributes to use private variables with read only properties, updates documentation to reflect deepcopy requirements, and adds comprehensive unit tests for immutability, caching, and deepcopy behavior.
Refactors WingMovement to store all attributes as private, immutable fields, exposes them via read-only properties, and ensures all numpy arrays are read-only. Adds a __deepcopy__ method for safe deep copying, including resetting internal caches. Updates and expands unit tests to verify immutability, caching, and deep copy behavior.
Refactored AirplaneMovement to store all attributes as private, immutable fields and expose them via read-only properties. Added __deepcopy__ method to support deep copying of AirplaneMovement instances, ensuring independence of internal state. Implemented manual caching for derived properties (all_periods, max_period). Updated tests to verify immutability, caching, and deepcopy behavior, and added new test classes for validation and immutability.
Refactored the Movement class to store key attributes as private and expose them via read-only properties, ensuring immutability. Airplane and operating point sequences are now tuples to prevent external mutation. Added new unit tests for immutability and caching behavior, and updated existing tests to reflect the new attribute types and access patterns.
Refactored UnsteadyProblem to store key attributes as private and expose them via read-only properties, ensuring immutability. Updated steady_problems to be a tuple instead of a list to prevent external mutation. Added comprehensive unit tests to verify immutability of these attributes and tuple behavior, as well as tests for multiple Airplanes and numpy bool handling.
…int attributes All three phases of the properties refactoring plan (see *_PLAN.md files in docs) are now complete.
…ne from this branch The final results show massive performance gains across almost all test cases, in particular ones with many WingCrossSections.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #94 +/- ##
==========================================
+ Coverage 89.29% 91.32% +2.02%
==========================================
Files 28 32 +4
Lines 5259 5818 +559
==========================================
+ Hits 4696 5313 +617
+ Misses 563 505 -58 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…nes and PR template
…ucture and attribute immutability
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements a comprehensive refactoring to enforce attribute immutability across all core classes in Ptera Software. The changes introduce read-only properties, set-once semantics, and lazy caching patterns to improve performance (25-40x for complex simulations) and data integrity.
Changes:
- Refactored core classes (Panel, Vortex, Geometry, Movement, OperatingPoint, Problem) to use immutable attributes with read-only properties backed by private variables
- Implemented manual lazy caching for derived properties with cache reset in
__deepcopy__methods - Changed mutable collections (lists) to immutable collections (tuples) throughout the API
- Moved vortex classes to new
_vortices/package structure - Updated trim functions to create new OperatingPoint instances instead of mutating existing ones
- Added comprehensive unit tests for immutability, caching, and deepcopy behavior
Reviewed changes
Copilot reviewed 56 out of 57 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| test_wing_movement.py | Added immutability, caching, and deepcopy tests for WingMovement |
| test_wing_cross_section_movement.py | Added immutability, caching, and deepcopy tests for WingCrossSectionMovement |
| test_problems.py | Added immutability tests and updated for tuple returns |
| test_operating_point_movement.py | Added immutability tests for OperatingPointMovement |
| test_operating_point.py | Added comprehensive immutability and caching tests |
| test_movement.py | Added immutability, caching tests and LCM method tests |
| test_line_vortex.py | Added immutability and caching tests, removed mutation tests |
| ring_vortex_fixtures.py | Updated imports to new _vortices package |
| problem_fixtures.py | Added multi-airplane unsteady problem fixture |
| panel_fixtures.py | New fixture file for Panel testing |
| operating_point_fixtures.py | Added 8 new fixtures for edge cases |
| line_vortex_fixtures.py | Updated imports to new _vortices package |
| horseshoe_vortex_fixtures.py | Updated imports to new _vortices package |
| geometry_fixtures.py | Added new fixtures and refactored existing ones |
| fixtures/init.py | Updated module documentation |
| unit/init.py | Updated module documentation |
| operating_point.py | Refactored to immutable with lazy caching |
| problems.py | Refactored SteadyProblem and UnsteadyProblem to immutable |
| movements/*.py | Refactored all movement classes to immutable with deepcopy support |
| _vortices/*.py | New package with immutable vortex classes |
| trim.py | Updated to create new OperatingPoints instead of mutating |
| solver files | Updated for new vortex package and tuple types |
| docs/*.md | Updated documentation for conventions and structure |
Files not reviewed (1)
- .idea/dictionaries/project.xml: Language not supported
Description
This PR implements a comprehensive refactoring of the Ptera Software codebase to enforce attribute immutability across all core classes. The refactoring introduces read-only properties, set-once semantics, and lazy caching patterns throughout the Panel, Vortex, Geometry, Movement, OperatingPoint, and Problem class hierarchies. The class structure and attribute immutability decisions are documented in
docs/CLASSES_AND_IMMUTABILITY.md.Motivation
The original codebase allowed mutable attributes, which led to:
This refactoring addresses these issues by:
__deepcopy__methods to support safe copying with cache preservation/resetThe result is a 25-40x performance improvement for complex variable geometry simulations, with simpler and more maintainable code.
Relevant Issues
Continues work from #93, which referenced #92.
Changes
Phase 1: Panel and Vortex Classes
_aerodynamics.pyto_aerodynamics_functions.py_vortices/package and moved vortex classes:LineVortexto_vortices/_line_vortex.pyHorseshoeVortexto_vortices/horseshoe_vortex.pyRingVortexto_vortices/ring_vortex.pyLineVortexendpoints immutable (removed setters)HorseshoeVortexgeometry immutable (front points, leg vector, leg length)RingVortexcorners immutable; updated UVLM solver to create new objects instead of mutatingPanelclass with immutable and set-once attributesPhase 2: Geometry Classes
Airfoilnumpy arrays immutable with private attributes and read-only propertiesWingCrossSectionattributes immutable with set-once enforcement forvalidatedandsymmetry_typeWingCrossSection(T_pas_Wcsp_Lpp_to_Wcs_Lp,T_pas_Wcs_Lp_to_Wcsp_Lpp)Wingattributes immutable with read-only and set-once enforcementAirplaneattributes immutable (wings,name,Cg_GP1_CgP1,weight,s_ref,c_ref,b_ref)Airplane.deep_copy_with_Cg_GP1_CgP1()method for creating copies with a custom global CG positionwingscollections to tuples instead of listsnum_panels,T_pas_G_Cg_to_GP1_CgP1)__deepcopy__methods to preserve or reset caches appropriatelyPhase 3: Movement and Problem Classes
OperatingPointattributes immutable with read-only properties and lazy cachingOperatingPointMovementattributes immutableWingCrossSectionMovementimmutable with custom__deepcopy__WingMovementimmutable with deep copy supportAirplaneMovementimmutable with manual caching for derived properties (all_periods,max_period)Movementattributes immutable; changed sequences to tuplesSteadyProblemattributes and outputs immutable;reynolds_numbersreturns cached tupleUnsteadyProblemattributes immutable;steady_problemsstored as tupleOperatingPointattributesAirplaneobjectsNew Dependencies
None.
Change Magnitude
Major: Large change that adds significant new functionality, changes existing behavior, or may affect many parts of the codebase.
This refactoring touches nearly every core class in the codebase and changes the fundamental mutability contract of the API. While the public interface remains largely the same (properties are accessed the same way), code that previously mutated attributes directly will now raise
AttributeError.Checklist
mainand is up to date with the upstreammainbranch.--in-place --black). See the style guide for type hints and docstrings for more details.pterasoftwarepackage use type hints. See the style guide for type hints and docstrings for more details.testspackage.testspackage.codespell,black,mypy, andtests).