InertiaFreeQSMPowerModel¶
The InertiaFreeQSMPowerModel wraps the
inertiafree-qsm
package. The underlying model is an Inertia-Free Quasi-Steady Model (QSM)
that simulates the full pumping cycle with four flight phases
(traction, retraction, transitionRIO, transitionRORI). It numerically optimises the cycle
parameters per wind speed to maximise output power using SLSQP.
Wrapper¶
- class awespa.power.inertiafree_qsm_power.InertiaFreeQSMPowerModel[source]¶
Bases:
PowerEstimationModelWrapper for the Inertia-Free Quasi-Steady Model power curve constructor.
This wrapper adapts the vendored InertiaFree-QSM to the AWESPA modular architecture. Power curves are generated from optimized cycle parameters per wind speed. Single-wind-speed simulations can still be run either directly or with optimization.
The model requires three configuration files in awesIO format: - System configuration (kite, tether, ground station properties) - Wind resource (altitude profiles, profiles, probability matrix) - Simulation settings (cycle parameters, optimizer bounds, phase settings)
- load_configuration(system_path: Path, simulation_settings_path: Path, wind_resource_path: Path | None = None, validate: bool = True) None[source]¶
Load power model configuration from YAML files.
Creates a
PowerCurveConstructorinstance from the vendored InertiaFree-QSM package using the provided configuration files.- Parameters:
system_path (Path) – Path to the system configuration YAML file (awesIO format with wing, tether, ground_station components).
simulation_settings_path (Path) – Path to simulation settings YAML file containing cycle, phase, optimizer, and solver parameters.
wind_resource_path (Path) – Path to wind resource YAML file containing altitude profiles, profiles, and probability matrix.
validate (bool) – If True, validate configuration files using the awesIO validator. Defaults to True.
- Raises:
ImportError – If the vendored PowerCurveConstructor cannot be imported.
FileNotFoundError – If any required file does not exist.
- compute_power_curves(wind_speeds: ndarray | None = None, profile_ids: List[int] | None = None, output_path: Path | None = None, verbose: bool = True, showplot: bool = False, saveplot: bool = False, validate: bool = True) Dict[str, Any][source]¶
Compute power curves.
- Parameters:
output_path (Path) – Path where power curve YAML will be written. If None, no export is performed. Defaults to None.
wind_speeds (np.ndarray) – Custom wind speeds to evaluate [m/s]. If None, uses wind speeds from simulation settings. Defaults to None.
profile_ids (list) – profile IDs (1-indexed) to calculate. If None, calculates all profiles. Defaults to None.
verbose (bool) – Whether to print progress output. Defaults to True.
showplot (bool) – Whether to display plots after generation. Defaults to False.
saveplot (bool) – Whether to save plots to file. Requires
output_path. Defaults to False.validate (bool) – If True, validate the output YAML file using the awesIO validator. Defaults to True.
- Returns:
Power curve data in awesIO format.
- Return type:
- Raises:
ValueError – If model is not initialized.
- calculate_power_at_wind_speed(wind_speed: float, method: str = 'direct', profile_id: int = 1, output_path: Path | None = None, verbose: bool = True, showplot: bool = False, saveplot: bool = False, validate: bool = True) float[source]¶
Calculate power output at a single wind speed.
Simulates a single pumping cycle at the given wind speed and returns the average cycle power.
- Parameters:
wind_speed (float) – Wind speed at reference height [m/s].
method (str) – Simulation method, either
'direct'or'optimization'. Defaults to'direct'.profile_id (int) – profile ID (1-indexed) for wind profile selection. Defaults to 1.
output_path (Path) – Path where results YAML will be written. If None, no export is performed. Defaults to None.
verbose (bool) – Whether to print verbose output. Defaults to True.
showplot (bool) – Whether to display cycle detail plot. Defaults to False.
saveplot (bool) – Whether to save cycle detail plot. Requires
output_path. Defaults to False.validate (bool) – If True, validate the output YAML file using the awesIO validator. Defaults to True.
- Returns:
Average cycle power output [W].
- Return type:
- Raises:
ValueError – If model is not initialized.
Configuration files¶
load_configuration expects three YAML files:
system_pathSystem configuration in awesIO format.
simulation_settings_pathQSM-specific settings — aerodynamics, cycle parameters, phase settings, optimizer bounds, and solver tolerances.
wind_resource_pathOutput of the wind module.
Simulation settings¶
An annotated example is shown below
(see config/example/inertiafree-qsm_settings.yml):
# ===== AERODYNAMIC SETTINGS =====
aerodynamics:
kite_lift_coefficient_reel_out: 0.63
kite_drag_coefficient_reel_out: 0.14
kite_lift_coefficient_reel_in: 0.4
kite_drag_coefficient_reel_in: 0.12
tether_drag_coefficient: 1.1
# ===== OPTIMIZATION =====
optimization:
wind_speeds:
cut_in: 3.0
cut_out: 25.0
n_points: 23
optimizer:
optimize_variables:
reeling_speed_traction: true
reeling_speed_retraction: true
fraction_tether_length_traction_end: true
fraction_tether_length_retraction_end: true
elevation_angle_traction: true
elevation_angle_end_trans_rori: true
opt_phase_timestep:
retraction: 1.5
transition_riro: 0.05
traction: 2.5
transition_rori: 0.05
max_iterations: 40
ftol: 0.005
eps: 1.0e-2
finite_difference_steps:
reeling_speed: 0.03
tether_fraction: 0.005
elevation_angle: 0.25
x0: [2, -2, 0.65, 0.9, 30.0, 50.0]
scaling: [1, 1, 1, 1, 30, 30]
bounds:
reeling_speed_traction_min: 0.01
reeling_speed_traction_max: 15.0
reeling_speed_retraction_min: -15.0
reeling_speed_retraction_max: -0.01
fraction_tether_length_traction_end_min: 0.8
fraction_tether_length_traction_end_max: 0.95
fraction_tether_length_retraction_end_min: 0.2
fraction_tether_length_retraction_end_max: 0.8
elevation_angle_traction_min: 30.0
elevation_angle_traction_max: 60.0
elevation_angle_end_trans_rori_min: 30.0
elevation_angle_end_trans_rori_max: 80.0
constraints:
min_tether_length_fraction_difference: 0.1
max_difference_elevation_angle_steps: 10.0
# ===== CYCLE CONFIGURATION =====
cycle:
minimum_tether_force: 750.0
minimum_height: 100.0
elevation_angle_traction: [30.0, 30.0, 30.0, 30.0, 30.0]
tether_length_end_traction: 0.95
tether_length_end_retraction: 0.6
include_transition_energy: true
elevation_angle_end_trans_rori: 50.0
# ===== PHASE SETTINGS =====
retraction:
control: ['reeling_speed', -2.0]
time_step: 0.25
azimuth_angle: 0.0
course_angle: 180.0
transition_riro:
control: ['reeling_speed', 0]
time_step: 0.05
azimuth_angle: 0.0
course_angle: 0.0
transition_rori:
control: ['reeling_speed', 0]
time_step: 0.05
azimuth_angle: 0.0
course_angle: 180.0
traction:
control: ['reeling_speed', 2.0]
time_step: 0.25
azimuth_angle: 11.5
course_angle: 93.0
# ===== STEADY STATE SOLVER =====
steady_state:
max_iterations: 250
convergence_tolerance: 1.0e-3
# ===== PHASE SOLVER =====
phase_solver:
max_time_points: 5000
Usage example¶
from pathlib import Path
from awespa.power.inertiafree_qsm_power import InertiaFreeQSMPowerModel
model = InertiaFreeQSMPowerModel()
model.load_configuration(
system_path=Path("config/example/tudelft V3_25.yml"),
simulation_settings_path=Path("config/example/inertiafree-qsm_settings.yml"),
wind_resource_path=Path("config/example/wind_resource.yml"),
)
# Compute power curves
model.compute_power_curves(
output_path=Path("results/example/power_curves_qsm.yml"),
verbose=True,
showplot=True,
saveplot=True,
)
# Single operating point with a direct simulation, meaning that the parameters are not optimized but taken directly from the settings file. This is much faster than the default method, which runs an optimization loop to find the optimal parameters at each wind speed.
# Useful for testing
power_w = model.calculate_power_at_wind_speed(
wind_speed=10.0,
method="direct",
profile_id=1,
verbose=True,
)
print(f"Power at 10 m/s: {power_w / 1000:.1f} kW - DIRECT")
# Single operating point with an optimization-based simulation, meaning that the parameters are optimized to find the optimal settings for each wind speed.
power_w = model.calculate_power_at_wind_speed(
wind_speed=10.0,
method="optimization",
profile_id=1,
verbose=True,
)
print(f"Power at 10 m/s: {power_w / 1000:.1f} kW - OPTIMIZATION")
Or use the ready-made script:
python scripts/run_inertiafree_qsm.py