Skip to content

Commit

Permalink
Merge pull request #1037 from ViniciusTxc3/fix-probe_response
Browse files Browse the repository at this point in the history
Fix probe response
  • Loading branch information
raphaeltimbo authored Apr 11, 2024
2 parents d9f7716 + 796b93c commit 0129230
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 40 deletions.
9 changes: 3 additions & 6 deletions ross/defects/abs_defect.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,12 @@ def plot_dfft(self, probe, probe_units="rad", range_freq=None, fig=None, **kwarg

# fmt: off
operator = np.array(
[[np.cos(angle), - np.sin(angle)],
[np.sin(angle), + np.cos(angle)]]
[[np.cos(angle), np.sin(angle)],
[-np.sin(angle), np.cos(angle)]]
)
row, cols = self.response.shape
_probe_resp = operator @ np.vstack((self.response[dofx,int(2*cols/3):], self.response[dofy,int(2*cols/3):]))
probe_resp = (
_probe_resp[0] * np.cos(angle) ** 2 +
_probe_resp[1] * np.sin(angle) ** 2
)
probe_resp = _probe_resp[0,:]
# fmt: on

amp, freq = self._dfft(probe_resp, self.dt)
Expand Down
104 changes: 76 additions & 28 deletions ross/results.py
Original file line number Diff line number Diff line change
Expand Up @@ -4415,6 +4415,75 @@ def __init__(self, rotor, t, yout, xout):
self.xout = xout
self.rotor = rotor

def data_probe_response(
self,
probe,
probe_units="rad",
displacement_units="m",
time_units="s",
):
"""This method create the time response given a tuple of probes with their nodes
and orientations in DataFrame format.
Parameters
----------
probe : list
List with rs.Probe objects.
probe_units : str, option
Units for probe orientation.
Default is "rad".
displacement_units : str, optional
Displacement units.
Default is 'm'.
time_units : str
Time units.
Default is 's'.
Returns
-------
df : pd.DataFrame
DataFrame probe response.
"""
data = {}

nodes = self.rotor.nodes
link_nodes = self.rotor.link_nodes
ndof = self.rotor.number_dof

for i, p in enumerate(probe):

try:
probe_tag = p[2]
except IndexError:
probe_tag = f"Probe {i+1} - Node {p[0]}"

data[f"probe_tag[{i}]"] = probe_tag

fix_dof = (p[0] - nodes[-1] - 1) * ndof // 2 if p[0] in link_nodes else 0
dofx = ndof * p[0] - fix_dof
dofy = ndof * p[0] + 1 - fix_dof

angle = Q_(p[1], probe_units).to("rad").m
data[f"angle[{i}]"] = angle

# fmt: off
operator = np.array(
[[np.cos(angle), np.sin(angle)],
[-np.sin(angle), np.cos(angle)]]
)

_probe_resp = operator @ np.vstack((self.yout[:, dofx], self.yout[:, dofy]))
probe_resp = _probe_resp[0,:]
# fmt: on

probe_resp = Q_(probe_resp, "m").to(displacement_units).m
data[f"probe_resp[{i}]"] = probe_resp

data["time"] = Q_(self.t, "s").to(time_units).m
df = pd.DataFrame(data)

return df

def plot_1d(
self,
probe,
Expand Down Expand Up @@ -4454,43 +4523,22 @@ def plot_1d(
fig : Plotly graph_objects.Figure()
The figure object with the plot.
"""
nodes = self.rotor.nodes
link_nodes = self.rotor.link_nodes
ndof = self.rotor.number_dof

if fig is None:
fig = go.Figure()

df = self.data_probe_response(
probe, probe_units, displacement_units, time_units
)
_time = df["time"].to_numpy()
for i, p in enumerate(probe):
fix_dof = (p[0] - nodes[-1] - 1) * ndof // 2 if p[0] in link_nodes else 0
dofx = ndof * p[0] - fix_dof
dofy = ndof * p[0] + 1 - fix_dof

angle = Q_(p[1], probe_units).to("rad").m

# fmt: off
operator = np.array(
[[np.cos(angle), - np.sin(angle)],
[np.sin(angle), + np.cos(angle)]]
)

_probe_resp = operator @ np.vstack((self.yout[:, dofx], self.yout[:, dofy]))
probe_resp = (
_probe_resp[0] * np.cos(angle) ** 2 +
_probe_resp[1] * np.sin(angle) ** 2
)
# fmt: on

probe_resp = Q_(probe_resp, "m").to(displacement_units).m

try:
probe_tag = p[2]
except IndexError:
probe_tag = f"Probe {i+1} - Node {p[0]}"
probe_tag = df[f"probe_tag[{i}]"][0]
probe_resp = df[f"probe_resp[{i}]"].to_numpy()

fig.add_trace(
go.Scatter(
x=Q_(self.t, "s").to(time_units).m,
x=_time,
y=Q_(probe_resp, "m").to(displacement_units).m,
mode="lines",
name=probe_tag,
Expand Down
9 changes: 3 additions & 6 deletions ross/stochastic/st_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -1142,17 +1142,14 @@ def plot_1d(

# fmt: off
operator = np.array(
[[np.cos(angle), - np.sin(angle)],
[np.sin(angle), + np.cos(angle)]]
[[np.cos(angle), np.sin(angle)],
[-np.sin(angle), np.cos(angle)]]
)

probe_resp = np.zeros_like(self.yout[:, :, 0])
for j, y in enumerate(self.yout):
_probe_resp = operator @ np.vstack((y[:, dofx], y[:, dofy]))
probe_resp[j] = (
_probe_resp[0] * np.cos(angle) ** 2 +
_probe_resp[1] * np.sin(angle) ** 2
)
probe_resp[j] = _probe_resp[0,:]
# fmt: on

fig.add_trace(
Expand Down
6 changes: 6 additions & 0 deletions ross/tests/frf.toml

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions ross/tests/test_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,26 @@ def test_orbit_calculate_amplitude():
)
assert_allclose(orb.calculate_amplitude("minor")[0], 1.4142135623730947)
assert_allclose(orb.calculate_amplitude("major")[0], 2.8284271247461903)


def test_probe_response(rotor1):
speed = 500.0
size = 50
node = 3
t = np.linspace(0, 10, size)
F = np.zeros((size, rotor1.ndof))
F[:, 4 * node] = 10 * np.cos(2 * t)
F[:, 4 * node + 1] = 10 * np.sin(2 * t)
response = rotor1.run_time_response(speed, F, t)

probe1 = (3, 0) # node 3, orientation 0° (X dir.)
probe2 = (3, 90) # node 3, orientation 90°(Y dir.)
resp_prob1 = np.array(
[0.00000000e00, 4.07504756e-06, 1.19778973e-05, 1.68562228e-05, 1.34097882e-05]
)
resp_prob2 = np.array(
[0.00000000e00, 4.13295078e-06, 8.25529257e-06, 1.28932310e-05, 1.59791798e-05]
)
data = response.data_probe_response(probe=[probe1, probe2], probe_units="degree")
assert_allclose(data["probe_resp[0]"].to_numpy()[:5], resp_prob1)
assert_allclose(data["probe_resp[1]"].to_numpy()[:5], resp_prob2)

0 comments on commit 0129230

Please sign in to comment.