Skip to content

Commit

Permalink
Merge branch 'develop' into enh/air-brakes
Browse files Browse the repository at this point in the history
  • Loading branch information
MateusStano committed Nov 28, 2023
2 parents 2bb2d2b + 1916956 commit 085ad11
Show file tree
Hide file tree
Showing 15 changed files with 535 additions and 376 deletions.
24 changes: 23 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ straightforward as possible.

### Added

- DOC: Added this changelog file [#472](https://github.com/RocketPy-Team/RocketPy/pull/472)
-

### Changed
Expand All @@ -43,6 +42,29 @@ straightforward as possible.

-

## [v1.1.2] - 2023-11-25

You can install this version by running `pip install rocketpy==1.1.2`

### Fixed

- BUG: Function breaks if a header is present in the csv file [#485](https://github.com/RocketPy-Team/RocketPy/pull/485)

## [v1.1.1] - 2023-11-23

You can install this version by running `pip install rocketpy==1.1.1`

### Added

- DOC: Added this changelog file [#472](https://github.com/RocketPy-Team/RocketPy/pull/472)
- ENH: Prevent out of bounds Tanks from Instantiation #484 [#484](https://github.com/RocketPy-Team/RocketPy/pull/484)

### Fixed

- HOTFIX: Negative Static Margin [#476](https://github.com/RocketPy-Team/RocketPy/pull/476)
- HOTFIX: 2D .CSV Function and missing set_get_value_opt call [#478](https://github.com/RocketPy-Team/RocketPy/pull/478)
- HOTFIX: Tanks Overfill not Being Detected [#479](https://github.com/RocketPy-Team/RocketPy/pull/479)

## [v1.1.0] - 2023-11-19

You can install this version by running `pip install rocketpy==1.1.0`
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
author = "RocketPy Team"

# The full version, including alpha/beta/rc tags
release = "1.1.0"
release = "1.1.2"


# -- General configuration ---------------------------------------------------
Expand Down
557 changes: 270 additions & 287 deletions docs/examples/SEB_liquid_motor.ipynb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/user/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ If you want to choose a specific version to guarantee compatibility, you may ins

.. code-block:: shell
pip install rocketpy==1.1.0
pip install rocketpy==1.1.2
Optional Installation Method: ``conda``
Expand Down
4 changes: 2 additions & 2 deletions docs/user/motors/liquidmotor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ Then we must first define the tanks:
fuel_gas = Fluid(name="ethanol_g", density=1.59)

# Define tanks geometry
tanks_shape = CylindricalTank(radius = 0.1, height = 1, spherical_caps = True)
tanks_shape = CylindricalTank(radius = 0.1, height = 1.2, spherical_caps = True)

# Define tanks
oxidizer_tank = MassFlowRateBasedTank(
name="oxidizer tank",
geometry=tanks_shape,
flux_time=5,
initial_liquid_mass=32,
initial_gas_mass=0.1,
initial_gas_mass=0.01,
liquid_mass_flow_rate_in=0,
liquid_mass_flow_rate_out=lambda t: 32 / 3 * exp(-0.25 * t),
gas_mass_flow_rate_in=0,
Expand Down
125 changes: 84 additions & 41 deletions rocketpy/mathutils/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,26 @@ def __init__(
Parameters
----------
source : function, scalar, ndarray, string
The actual function. If type is function, it will be called for
evaluation. If type is int or float, it will be treated as a
constant function. If ndarray, its points will be used for
interpolation. An ndarray should be as [(x0, y0, z0), (x1, y1, z1),
(x2, y2, z2), ...] where x0 and y0 are inputs and z0 is output. If
string, imports file named by the string and treats it as csv.
The file is converted into ndarray and should not have headers.
source : callable, scalar, ndarray, string, or Function
The data source to be used for the function:
- Callable: Called for evaluation with input values. Must have the
desired inputs as arguments and return a single output value.
Input order is important. Example: Python functions, classes, and
methods.
- int or float: Treated as a constant value function.
- ndarray: Used for interpolation. Format as [(x0, y0, z0),
(x1, y1, z1), ..., (xn, yn, zn)], where 'x' and 'y' are inputs,
and 'z' is the output.
- string: Path to a CSV file. The file is read and converted into an
ndarray. The file can optionally contain a single header line.
- Function: Copies the source of the provided Function object,
creating a new Function with adjusted inputs and outputs.
inputs : string, sequence of strings, optional
The name of the inputs of the function. Will be used for
representation and graphing (axis names). 'Scalar' is default.
Expand Down Expand Up @@ -74,6 +86,13 @@ def __init__(
Returns
-------
None
Notes
-----
(I) CSV files can optionally contain a single header line. If present,
the header is ignored during processing.
(II) Fields in CSV files may be enclosed in double quotes. If fields are
not quoted, double quotes should not appear inside them.
"""
# Set input and output
if inputs is None:
Expand Down Expand Up @@ -133,25 +152,42 @@ def set_outputs(self, outputs):
return self

def set_source(self, source):
"""Set the source which defines the output of the function giving a
certain input.
"""Sets the data source for the function, defining how the function
produces output from a given input.
Parameters
----------
source : function, scalar, ndarray, string, Function
The actual function. If type is function, it will be called for
evaluation. If type is int or float, it will be treated as a
constant function. If ndarray, its points will be used for
interpolation. An ndarray should be as [(x0, y0, z0), (x1, y1, z1),
(x2, y2, z2), ...] where x0 and y0 are inputs and z0 is output. If
string, imports file named by the string and treats it as csv.
The file is converted into ndarray and should not have headers.
If the source is a Function, its source will be copied and another
Function will be created following the new inputs and outputs.
source : callable, scalar, ndarray, string, or Function
The data source to be used for the function:
- Callable: Called for evaluation with input values. Must have the
desired inputs as arguments and return a single output value.
Input order is important. Example: Python functions, classes, and
methods.
- int or float: Treated as a constant value function.
- ndarray: Used for interpolation. Format as [(x0, y0, z0),
(x1, y1, z1), ..., (xn, yn, zn)], where 'x' and 'y' are inputs,
and 'z' is the output.
- string: Path to a CSV file. The file is read and converted into an
ndarray. The file can optionally contain a single header line.
- Function: Copies the source of the provided Function object,
creating a new Function with adjusted inputs and outputs.
Notes
-----
(I) CSV files can optionally contain a single header line. If present,
the header is ignored during processing.
(II) Fields in CSV files may be enclosed in double quotes. If fields are
not quoted, double quotes should not appear inside them.
Returns
-------
self : Function
Returns the Function instance.
"""
_ = self._check_user_input(
source,
Expand All @@ -164,21 +200,18 @@ def set_source(self, source):
if isinstance(source, Function):
source = source.get_source()
# Import CSV if source is a string or Path and convert values to ndarray
elif isinstance(source, (str, Path)):
# Read file and check for headers
with open(source, mode="r") as f:
first_line = f.readline()
# If headers are found...
if first_line[0] in ['"', "'"]:
# Headers available
first_line = first_line.replace('"', " ").replace("'", " ")
first_line = first_line.split(" , ")
self.set_inputs(first_line[0])
self.set_outputs(first_line[1:])
source = np.loadtxt(source, delimiter=",", skiprows=1, dtype=float)
# if headers are not found
else:
source = np.loadtxt(source, delimiter=",", dtype=float)
if isinstance(source, (str, Path)):
with open(source, "r") as file:
try:
source = np.loadtxt(file, delimiter=",", dtype=float)
except ValueError:
# If an error occurs, headers are present
source = np.loadtxt(source, delimiter=",", dtype=float, skiprows=1)
except Exception as e:
raise ValueError(
"The source file is not a valid csv or txt file."
) from e

# Convert to ndarray if source is a list
if isinstance(source, (list, tuple)):
source = np.array(source, dtype=np.float64)
Expand Down Expand Up @@ -2715,7 +2748,7 @@ 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.x_initial and func.max > self.x_final:
if func.min < self.x_initial or 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.x_initial, self.x_final}."
Expand Down Expand Up @@ -2785,7 +2818,8 @@ def _check_user_input(
dimensions of inputs and outputs. If the outputs list has more than
one element.
TypeError
If the source is not a list, np.ndarray, or Function object.
If the source is not a list, np.ndarray, Function object, str or
Path.
Warning
If inputs or outputs do not match for a Function source, or if
defaults are used for inputs, interpolation,and extrapolation for a
Expand Down Expand Up @@ -2829,11 +2863,20 @@ def _check_user_input(
# Deal with csv or txt
if isinstance(source, (str, Path)):
# Convert to numpy array
source = np.loadtxt(source, delimiter=",", dtype=float)
try:
source = np.loadtxt(source, delimiter=",", dtype=float)
except ValueError:
# Skip header
source = np.loadtxt(source, delimiter=",", dtype=float, skiprows=1)
except Exception as e:
raise ValueError(
"The source file is not a valid csv or txt file."
) from e

# this will also trigger an error if the source is not a list of
# numbers or if the array is not homogeneous
source = np.array(source, dtype=np.float64)
else:
# this will also trigger an error if the source is not a list of
# numbers or if the array is not homogeneous
source = np.array(source, dtype=np.float64)

# check dimensions
source_dim = source.shape[1]
Expand Down
Loading

0 comments on commit 085ad11

Please sign in to comment.