Skip to content

Commit

Permalink
Merging changes from the stable version of the horizontal flapping br…
Browse files Browse the repository at this point in the history
…anch into release-3.1.0
  • Loading branch information
camUrban committed Dec 4, 2024
2 parents 0e0a3f3 + 80df7ac commit dae6c5d
Show file tree
Hide file tree
Showing 23 changed files with 1,099 additions and 783 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,9 @@ dmypy.json
# This is the cython debug symbols to ignore.
cython_debug/

# This is a folder full of random tests to ignore.
# These are folders for scripts in development to ignore.
/testing_in_development/
/experimental/

# These are folders created by testing to ignore.
/tests/_trial_temp/
Expand All @@ -135,7 +136,6 @@ cython_debug/
/tests/unit/fixtures/_trial_temp/

# These are folders and files created by releasing.

/build
/dist
/Output
Expand Down
1 change: 1 addition & 0 deletions .idea/dictionaries/camer.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion .idea/statistic.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions pterasoftware/convergence.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ def analyze_steady_convergence(
next_ref_wing_cross_section = ref_wing_cross_sections[
ref_wing_cross_section_id + 1
]
# ToDo: Modify this to allow for new geometry with custom
# planes for the wing cross sections. As of now,
# it fails for vertical wings.
section_length = (
next_ref_wing_cross_section.y_le
- ref_wing_cross_section.y_le
Expand Down Expand Up @@ -749,6 +752,9 @@ def analyze_unsteady_convergence(
ref_wing_cross_section_movement_id + 1
].base_wing_cross_section
)
# ToDo: Modify this to allow for new geometry
# with custom planes for the wing cross
# sections. As of now, it fails for vertical wings.
section_length = (
next_ref_base_wing_cross_section.y_le
- ref_base_wing_cross_section.y_le
Expand Down
109 changes: 107 additions & 2 deletions pterasoftware/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,18 @@
update_ring_vortex_solvers_panel_attributes: This function populates a ring
vortex solver's attributes with the attributes of a given panel.
calculate_steady_freestream_wing_influences: This method finds the vector of
calculate_steady_freestream_wing_influences: This function finds the vector of
freestream-wing influence coefficients associated with this problem.
numba_1d_explicit_cross: This function takes in two arrays, each of which contain
N vectors of 3 components. The function then calculates and returns the cross
product of the two vectors at each position.
reflect_point_across_plane: This function finds the coordinates of the reflection
of a point across a plane in 3D space.
interp_between_points: This function finds the MxN points between M pairs of
points in 3D space given an array of N normalized spacings.
"""

import logging
Expand Down Expand Up @@ -602,7 +608,7 @@ def update_ring_vortex_solvers_panel_attributes(


def calculate_steady_freestream_wing_influences(steady_solver):
"""This method finds the vector of freestream-wing influence coefficients
"""This function finds the vector of freestream-wing influence coefficients
associated with this problem.
:return: None
Expand Down Expand Up @@ -650,3 +656,102 @@ def numba_1d_explicit_cross(vectors_1, vectors_2):
vectors_1[i, 0] * vectors_2[i, 1] - vectors_1[i, 1] * vectors_2[i, 0]
)
return crosses


def reflect_point_across_plane(point, plane_unit_normal, plane_point):
"""This function finds the coordinates of the reflection of a point across a
plane in 3D space.
As the plane doesn't necessarily include the origin, this is an affine
transformation. The transformation matrix and details are discussed in the
following source: https://en.wikipedia.org/wiki/Transformation_matrix#Reflection_2
:param point: (3,) array of floats
This is a (3,) array of the coordinates of the point to reflect. The units
are meters.
:param plane_unit_normal: (3,) array of floats
This is a (3,) array of the components of the plane's unit normal vector. It
must have unit magnitude. The units are meters.
:param plane_point: (3,) array of floats
This is a (3,) array of the coordinates of a point on the plane. The units
are meters.
:return: (3,) array of floats
This is a (3,) array of the components of the reflected point. The units are
meters.
"""
[x, y, z] = point
[a, b, c] = plane_unit_normal

# Find the dot product between the point on the plane and unit normal.
d = np.dot(-plane_point, plane_unit_normal)

# To make the transformation matrix readable, define new variables for the
# products of the vector components and the dot product.
ab = a * b
ac = a * c
ad = a * d
bc = b * c
bd = b * d
cd = c * d
a2 = a**2
b2 = b**2
c2 = c**2

# Define the affine transformation matrix. See the citation in the docstring for
# details.
transformation_matrix = np.array(
[
[1 - 2 * a2, -2 * ab, -2 * ac, -2 * ad],
[-2 * ab, 1 - 2 * b2, -2 * bc, -2 * bd],
[-2 * ac, -2 * bc, 1 - 2 * c2, -2 * cd],
[0, 0, 0, 1],
]
)

expanded_coordinates = np.array([[x], [y], [z], [1]])

transformed_expanded_coordinates = transformation_matrix @ expanded_coordinates

# Extract the reflected coordinates in 3D space.
[x_prime, y_prime, z_prime] = transformed_expanded_coordinates[:-1, 0]

return np.array([x_prime, y_prime, z_prime])


@njit(cache=True, fastmath=False)
def interp_between_points(start_points, end_points, norm_spacings):
"""This function finds the MxN points between M pairs of points in 3D space given
an array of N normalized spacings.
:param start_points: (M, 3) array of floats
This is the (M, 3) array containing the coordinates of the M starting points.
The units are meters.
:param end_points: (M, 3) array of floats
This is the (M, 3) array containing the coordinates of the M ending points.
The units are meters.
:param norm_spacings: (N,) array of floats
This is the (N,) array of the N spacings between the starting points and
ending points. The values are unitless and must be normalized from 0 to 1.
:return points: (M, N, 3) array of floats
This is the (M, N, 3) array of the coordinates of the MxN interpolated
points. The units are meters.
"""
m = start_points.shape[0]
n = norm_spacings.size

points = np.zeros((m, n, 3))

for i in range(m):
start_point = start_points[i, :]
end_point = end_points[i, :]

vector = end_point - start_point

for j in range(n):
norm_spacing = norm_spacings[j]

spacing = norm_spacing * vector

points[i, j, :] = start_point + spacing

return points
Loading

0 comments on commit dae6c5d

Please sign in to comment.