Skip to content
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

MNT: solve warnings #470

Merged
merged 5 commits into from
Nov 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -185,16 +185,18 @@ function-naming-style=snake_case
#function-rgx=

# Good variable names which should always be accepted, separated by a comma.
good-names=i,
j,
k,
ex,
Run,
_
good-names=FlightPhases,
WindroseAxes,


# Good variable names regexes, separated by a comma. If names match any regex,
# they will always be accepted
good-names-rgxs=
good-names-rgxs= ^[a-z][0-9]?$, # Single lowercase characters, possibly followed by a single digit
^[A-Z][0-9]{0,2}$, # Single uppercase characters, possibly followed by one or two digits
^[A-Z]+_\d+(_dot)?$, # Uppercase characters followed by underscore and digits, optionally followed by _dot
^(dry_|propellant_)[A-Z]+_\d+$, # Variables starting with 'dry_' or 'propellant_', followed by uppercase characters, underscore, and digits
^[a-z]+_ISA$, # Lowercase words ending with '_ISA'
^plot(1D|2D)$, # Variables starting with 'plot' followed by '1D' or '2D'

# Include a hint for the correct naming format with invalid-name.
include-naming-hint=no
Expand Down
126 changes: 53 additions & 73 deletions rocketpy/mathutils/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ def source_function(_):
source = source[source[:, 0].argsort()]

self.x_array = source[:, 0]
self.xinitial, self.xfinal = self.x_array[0], self.x_array[-1]
self.x_initial, self.x_final = self.x_array[0], self.x_array[-1]

self.y_array = source[:, 1]
self.y_initial, self.y_final = self.y_array[0], self.y_array[-1]
Expand All @@ -241,7 +241,7 @@ def source_function(_):
# Do things if function is multivariate
else:
self.x_array = source[:, 0]
self.xinitial, self.xfinal = self.x_array[0], self.x_array[-1]
self.x_initial, self.x_final = self.x_array[0], self.x_array[-1]

self.y_array = source[:, 1]
self.y_initial, self.y_final = self.y_array[0], self.y_array[-1]
Expand All @@ -251,30 +251,6 @@ def source_function(_):

# Finally set data source as source
self.source = source

# Update extrapolation method
if (
self.__extrapolation__ is None
or self.__extrapolation__ == "natural"
):
self.set_extrapolation("natural")
else:
raise ValueError(
"Multidimensional datasets only support natural extrapolation."
)

# Set default multidimensional interpolation if it hasn't
if (
self.__interpolation__ is None
or self.__interpolation__ == "shepard"
):
self.set_interpolation("shepard")
else:
raise ValueError(
"Multidimensional datasets only support shepard interpolation."
)

# Return self
return self

@cached_property
Expand Down Expand Up @@ -363,7 +339,7 @@ def set_get_value_opt(self):
# Retrieve general info
x_data = self.x_array
y_data = self.y_array
x_min, x_max = self.xinitial, self.xfinal
x_min, x_max = self.x_initial, self.x_final
if self.__extrapolation__ == "zero":
extrapolation = 0 # Extrapolation is zero
elif self.__extrapolation__ == "natural":
Expand Down Expand Up @@ -557,6 +533,7 @@ def set_discrete(
zs = np.array(self.get_value(mesh))
self.set_source(np.concatenate(([xs], [ys], [zs])).transpose())
self.__interpolation__ = "shepard"
self.__extrapolation__ = "natural"
return self

def set_discrete_based_on_model(
Expand Down Expand Up @@ -888,7 +865,7 @@ def get_value(self, *args):
x = np.array(args[0])
x_data = self.x_array
y_data = self.y_array
x_min, x_max = self.xinitial, self.xfinal
x_min, x_max = self.x_initial, self.x_final
coeffs = self.__polynomial_coefficients__
matrix = np.zeros((len(args[0]), coeffs.shape[0]))
for i in range(coeffs.shape[0]):
Expand All @@ -909,7 +886,7 @@ def get_value(self, *args):
x_data = self.x_array
y_data = self.y_array
x_intervals = np.searchsorted(x_data, x)
x_min, x_max = self.xinitial, self.xfinal
x_min, x_max = self.x_initial, self.x_final
if self.__interpolation__ == "spline":
coeffs = self.__spline_coefficients__
for i, _ in enumerate(x):
Expand Down Expand Up @@ -1229,7 +1206,7 @@ def plot_1d(
else:
# Determine boundaries
x_data = self.x_array
x_min, x_max = self.xinitial, self.xfinal
x_min, x_max = self.x_initial, self.x_final
lower = x_min if lower is None else lower
upper = x_max if upper is None else upper
# Plot data points if force_data = True
Expand Down Expand Up @@ -1356,7 +1333,7 @@ def plot_2d(
mesh_x.shape
)
z_min, z_max = z.min(), z.max()
color_map = plt.cm.get_cmap(cmap)
color_map = plt.colormaps[cmap]
norm = plt.Normalize(z_min, z_max)

# Plot function
Expand Down Expand Up @@ -1530,7 +1507,7 @@ def __interpolate_polynomial__(self):
y = self.y_array
# Check if interpolation requires large numbers
if np.amax(x) ** degree > 1e308:
print(
warnings.warn(
"Polynomial interpolation of too many points can't be done."
" Once the degree is too high, numbers get too large."
" The process becomes inefficient. Using spline instead."
Expand Down Expand Up @@ -2738,10 +2715,10 @@ def compose(self, func, extrapolate=False):
if isinstance(self.source, np.ndarray) and isinstance(func.source, np.ndarray):
# Perform bounds check for composition
if not extrapolate:
if func.min < self.xinitial and func.max > self.xfinal:
if func.min < self.x_initial and func.max > self.x_final:
raise ValueError(
f"Input Function image {func.min, func.max} must be within "
f"the domain of the Function {self.xinitial, self.xfinal}."
f"the domain of the Function {self.x_initial, self.x_final}."
)

return Function(
Expand All @@ -2763,10 +2740,10 @@ def compose(self, func, extrapolate=False):
@staticmethod
def _check_user_input(
source,
inputs,
outputs,
interpolation,
extrapolation,
inputs=None,
outputs=None,
interpolation=None,
extrapolation=None,
):
"""
Validates and processes the user input parameters for creating or
Expand Down Expand Up @@ -2857,30 +2834,55 @@ def _check_user_input(
source_dim = source.shape[1]

# check interpolation and extrapolation
if source_dim > 2:

## single dimension
if source_dim == 2:
# possible interpolation values: llinear, polynomial, akima and spline
if interpolation is None:
interpolation = "spline"
elif interpolation.lower() not in [
"spline",
"linear",
"polynomial",
"akima",
]:
warnings.warn(
"Interpolation method for single dimensional functions was "
+ f"set to 'spline', the {interpolation} method is not supported."
)
interpolation = "spline"

# possible extrapolation values: constant, natural, zero
if extrapolation is None:
extrapolation = "constant"
elif extrapolation.lower() not in ["constant", "natural", "zero"]:
warnings.warn(
"Extrapolation method for single dimensional functions was "
+ f"set to 'constant', the {extrapolation} method is not supported."
)
extrapolation = "constant"

## multiple dimensions
elif source_dim > 2:
# check for inputs and outputs
if inputs == ["Scalar"]:
inputs = [f"Input {i+1}" for i in range(source_dim - 1)]
warnings.warn(
f"Inputs not set, defaulting to {inputs} for "
+ "multidimensional functions.",
)

if interpolation not in [None, "shepard"]:
interpolation = "shepard"
warnings.warn(
(
"Interpolation method for multidimensional functions is set"
"to 'shepard', currently other methods are not supported."
"Interpolation method for multidimensional functions was"
"set to 'shepard', other methods are not supported yet."
),
)
interpolation = "shepard"

if extrapolation is None:
extrapolation = "natural"
if extrapolation not in [None, "natural"]:
warnings.warn(
"Extrapolation not set, defaulting to 'natural' "
+ "for multidimensional functions.",
"Extrapolation method for multidimensional functions was set"
"to 'natural', other methods are not supported yet."
)
extrapolation = "natural"

# check input dimensions
in_out_dim = len(inputs) + len(outputs)
Expand All @@ -2889,21 +2891,6 @@ def _check_user_input(
"Source dimension ({source_dim}) does not match input "
+ f"and output dimension ({in_out_dim})."
)

# if function, check for inputs and outputs
if isinstance(source, Function):
# check inputs
if inputs is not None and inputs != source.get_inputs():
warnings.warn(
f"Inputs do not match source inputs, setting inputs to {inputs}.",
)

# check outputs
if outputs is not None and outputs != source.get_outputs():
warnings.warn(
f"Outputs do not match source outputs, setting outputs to {outputs}.",
)

return inputs, outputs, interpolation, extrapolation


Expand Down Expand Up @@ -2937,7 +2924,7 @@ def __new__(
outputs: list of strings
A list of strings that represent the outputs of the function.
interpolation: str
The type of interpolation to use. The default value is 'akima'.
The type of interpolation to use. The default value is 'spline'.
extrapolation: str
The type of extrapolation to use. The default value is None.
datapoints: int
Expand Down Expand Up @@ -3123,13 +3110,6 @@ def source_function(*_):

source = source_function
val = Function(source, *args, **kwargs)
except Exception as exc:
# TODO: Raising too general exception Pylint W0719
raise Exception(
"Could not create Function object from method "
f"{self.func.__name__}."
) from exc

# pylint: disable=W0201
val.__doc__ = self.__doc__
val.__cached__ = True
Expand Down
24 changes: 22 additions & 2 deletions rocketpy/motors/liquid_motor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
from ..mathutils.function import funcify_method, reset_funcified_methods
import warnings

import numpy as np

from rocketpy.mathutils.function import (
Function,
funcify_method,
reset_funcified_methods,
)

from ..plots.liquid_motor_plots import _LiquidMotorPlots
from ..prints.liquid_motor_prints import _LiquidMotorPrints
from .motor import Motor
Expand Down Expand Up @@ -264,7 +273,18 @@ def exhaust_velocity(self):
mass flow rate. Therefore, this will vary with time if the mass flow
rate varies with time.
"""
return self.thrust / (-1 * self.mass_flow_rate)
times, thrusts = self.thrust.source[:, 0], self.thrust.source[:, 1]
mass_flow_rates = self.mass_flow_rate(times)

# Compute exhaust velocity only for non-zero mass flow rates
valid_indices = mass_flow_rates != 0
valid_times = times[valid_indices]
valid_thrusts = thrusts[valid_indices]
valid_mass_flow_rates = mass_flow_rates[valid_indices]

ext_vel = -valid_thrusts / valid_mass_flow_rates

return np.column_stack([valid_times, ext_vel])

@funcify_method("Time (s)", "Propellant Mass (kg)")
def propellant_mass(self):
Expand Down
2 changes: 1 addition & 1 deletion rocketpy/plots/rocket_plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def stability_margin(self):
None
"""

self.rocket.stability_margin.plot2D(
self.rocket.stability_margin.plot_2d(
lower=0,
upper=[2, self.rocket.motor.burn_out_time], # Mach 2 and burnout
samples=[20, 20],
Expand Down