Skip to content

Conversation

@ArthurIasbeck
Copy link
Contributor

@ArthurIasbeck ArthurIasbeck commented Feb 22, 2025

The API STANDARD 617 document (produced by the American Petroleum Institute) requires that rotors supported by active magnetic bearings (AMBs) have their stability assessed based on a series of criteria. One of these criteria involves analyzing the sensitivity of the closed-loop control system that enables the AMB operation.

ISO 14839-3 defines how the sensitivity of active magnetic bearings should be measured. This ISO standard assumes that the control system associated with the AMB can be represented as follows:

image

where $G_p$ is the rotor's transfer function, $E$ is a disturbance associated with the sensor signal (which can represent white noise or a harmonic signal), and $F_d$ is a force that represents a disturbance applied directly to the rotor.

The system above can be simplified so that:

Based on these representations, the ISO standard proposes that the open-loop, closed-loop, and sensitivity transfer functions, represented by $G_o$, $G_c$, and $G_s$, respectively, be computed as follows:

To compute the sensitivities associated with the rotor's AMBs, the run_amb_sensitivity() method was implemented. The run_amb_sensitivity() method invokes run_time_response() and specifies that the Newmark integrator should be used. During the execution of run_time_response(), the magnetic_bearing_controller() method (responsible for computing the forces applied by the AMB based on the shaft position) is invoked. This method was modified to include an impulse-type disturbance signal in the shaft position (which in this case is obtained numerically but would be acquired from a sensor in a practical application).

The run_time_response() method is invoked $2 N_{AMB}$ times, where $N_{AMB}$ is the number of AMBs present in the rotor under analysis. With each execution, the disturbance signal is applied to a different degree of freedom ($x$ or $y$) of a different AMB.

Finally, the frequency-domain equivalents of the displacement vectors produced in each execution and the disturbance signals associated with them are obtained (using the Fourier Transform). By relating both signals in the frequency domain, the frequency response representing the sensitivity is obtained.

Below is an example of using the run_amb_sensitivity() method.

# 1. Create a rotor model using a built-in example
rotor_amb = rs.rotor_amb_example()

# 2. Run the sensitivity analysis on this rotor
sensitivity_results = rotor_amb.run_amb_sensitivity(
    speed=0,
    t_max=5,
    dt=1e-4,
    disturbance_amplitude=10e-6,
    disturbance_min_frequency=0.01,
    disturbance_max_frequency=150,
    amb_tags=["Magnetic Bearing 0", "Magnetic Bearing 1"],
    sensors_theta=45,
    verbose=0,
)

The expected parameters for this method are described below:

Argument Type Description
speed float The rotational speed of the rotor in rad/s.
t_max float The total time duration for the simulation in seconds.
dt float The time step for the simulation in seconds.
disturbance_amplitude float, optional The amplitude of the chirp disturbance signal. Defaults to 10e-6.
disturbance_min_frequency float, optional The minimum frequency (in Hz) of the logarithmic chirp signal. The chirp sweeps from this frequency to disturbance_max_frequency. Defaults to 0.001 Hz.
disturbance_max_frequency float, optional The maximum frequency (in Hz) of the logarithmic chirp signal. Defaults to 150 Hz.
amb_tags list[str], optional A list of AMB tags to be included in the analysis. If None, all magnetic bearings in the rotor model are analyzed. Defaults to None.
sensors_theta float, optional The angular position of the AMB sensors in radians, defining the orientation of the sensor coordinate system (v, w) relative to the global system (x, y). Defaults to 45 degrees.

The SensitivityResults object, resulting from the execution of the run_amb_sensitivity() method, contains the following attributes:

Attribute Type Description
sensitivities_frequencies np.ndarray A NumPy array of frequencies (in Hz) at which the sensitivity FRF was computed.
sensitivities_abs dict A dictionary containing the absolute magnitude (linear scale) of the sensitivity FRF for each AMB and axis. The structure is {amb_tag: {'x': array, 'y': array}}.
sensitivities_phase dict A dictionary containing the phase (in radians) of the sensitivity FRF for each AMB and axis. The structure is {amb_tag: {'x': array, 'y': array}}.
sensitivities dict A dictionary containing the complex sensitivity FRF for each AMB and axis. The structure is {amb_tag: {'x': array, 'y': array}}.
max_abs_sensitivities dict A dictionary holding the maximum absolute sensitivity value for each AMB and axis. This is useful for quickly identifying the peak sensitivity.
sensitivity_run_time_results dict A dictionary with the raw time-domain results from the simulation. It includes the time vector t, and for each AMB and axis, the excitation_signal, disturbed_signal and the original sensor_signal (displacement from FEM model).
sensitivity_compute_dofs dict A mapping of AMB tags to their corresponding degrees of freedom (DOFs) indices.
number_dof int The number of degrees of freedom of the rotor system.

To check, for example, the maximum sensitivity associated with the bearing controller Bearing 0 that regulates the shaft position in the x direction, simply access the max_abs_sensitivities attribute as shown below.

sensitivites_results.max_abs_sensitivities["Magnetic Bearing 0"]["x"]

The attributes of the SensitivityResults object are dictionaries that organize the data produced during the execution of the run_amb_sensitivity() method based on the tags of each AMB and their degrees of freedom. For example, considering that the rotor under analysis has two AMBs assigned the tags Bearing 0 and Bearing 1, the max_abs_sensitivities attribute would be defined as follows. The other attributes are defined similarly.

max_abs_sensitivities = {
    'Bearing 0': {
        'x': ...,
	'y': ...
    },
    'Bearing 1': {
        'x': ...,
        'y': ...
    }
}

The use of the SensitivityResults.plot() method allows for a graphical representation of the magnitude and phase of the sensitivities associated with each AMB present in the rotor under analysis.

fig_sens = sensitivity_results.plot(
    frequency_units="Hz",
    phase_unit="degree",
    magnitude_scale="decibel",
    xaxis_type="log",
)
newplot

The use of the SensitivityResults.plot_run_time_results() method allows for a graphical representation of the time-domain data that served as the basis for computing the sensitivities. Note that if the time response diverges, inconsistent sensitivity values may be determined.

fig_time = sensitivity_results.plot_run_time_results()
newplot

Finally, it is worth noting that the file tutorial_part_2_2.ipynb has been updated to include detailed instructions regarding the sensitivity calculation.

image

ArthurIasbeck and others added 4 commits February 17, 2025 05:00
…e_results() methods. Updated tutorial_part_2_2.ipynb file to include detailed instructions regarding the sensitivity calculation.
@ross-bott
Copy link
Collaborator

Hi there!
I have marked this issue as stale because it has not had activity for 45 days.
Consider the following options:

  • If the issue refers to a large task, break it in smaller issues that can be solved in
    less than 45 days;
  • Label the issue as wontfix or wontfix for now and close it.

@ross-bott ross-bott added the stale Issues with no activity for a long period label Apr 10, 2025
…vity

# Conflicts:
#	docs/user_guide/tutorial_part_2_2.ipynb
#	ross/bearing/cylindrical.py
#	ross/rotor_assembly.py
#	ross/utils.py
…ação do tipo chirp e da rotação do eixo de referência dos sensores.
…nctions to the SensitivityResults class, adjustment of the method names in the SensitivityResults class that contained the word run, adaptation of the load and save methods to the new format of the SensitivityResults class, optimization of the imports in the rotor_assembly.py module, removal of the ignore parameter from the K() and C() methods, update of the integrate_system method to include the definition of the rotor object (identical to self, but without the magnetic bearings), and reallocation of the code responsible for computing the control current (compute_pid_amb) to the MagneticBearingElement class.
@ArthurIasbeck
Copy link
Contributor Author

The requested changes have been implemented and are briefly described below.

1. AMB PID Control Logic Encapsulation

The PID (Proportional-Integral-Derivative) control logic for Active Magnetic Bearings has been refactored.

  • The function compute_pid_amb, previously located in ross/utils.py, has been moved and is now a method of the MagneticBearingElement class in ross/bearing_seal_element.py.
  • Impact: This change improves code organization and encapsulation by associating the control logic directly with the magnetic bearing element it controls. The rotor_assembly.py module has been updated to call this new method (elm.compute_pid_amb(...)) during time-domain simulations.

2. Sensitivity Analysis Calculation

The responsibility for calculating frequency-domain sensitivity functions has been shifted from the Rotor class to the SensitivityResults class.

  • Previously, the Rotor.run_amb_sensitivity() method performed both the time-domain simulation and the subsequent frequency-domain calculations (FFT, magnitude, phase).
  • Now, Rotor.run_amb_sensitivity() only performs the time-domain simulation to generate raw signal data. This data is then passed to the SensitivityResults constructor (__init__), which is now responsible for all frequency-domain processing.
  • Impact: This refactoring provides better separation of concerns. The SensitivityResults class is now self-contained, handling both the storage and the processing of the analysis data, which simplifies the Rotor class.

3. Robust Serialization for Sensitivity Analysis Results

The save() and load() methods within the SensitivityResults class have been completely rewritten to be more robust and reliable.

  • Enhanced Serialization: The new save() method correctly serializes all relevant data, including complex NumPy arrays for Frequency Response Functions (FRFs), into a standard TOML file format. This is achieved by converting NumPy arrays into nested Python lists.
  • Reliable Deserialization: The load() class method now correctly reconstructs the SensitivityResults object from a TOML file. It properly converts the list data back into NumPy arrays with the correct data types (e.g., np.complex128), eliminating the fragile string parsing used in the previous implementation.
  • Impact: Saving and loading sensitivity analysis results is now significantly more reliable, ensuring data integrity and preventing errors during file I/O operations.

4. Adjustment of the K() and C() methods

The Rotor.run_time_response() method has been optimized for simulations involving Active Magnetic Bearings (AMBs).

  • When calculating the time response for a rotor with AMBs, the method now creates a deep copy of the rotor and removes the magnetic bearing elements from that copy.
  • The base stiffness (K0) and damping (C0) matrices are then directly accessed from this pre-calculated copy, rather than being recalculated at each time step with an ignore list.
  • Impact: The methods K() and C() no longer take the ignore argument, in accordance with the current version of ROSS.

5. Method Rename in SensitivityResults

For clarity and consistency, a plotting method in the SensitivityResults class has been renamed:

  • plot_run_time_results() is now plot_time_results().

Example usage has been updated accordingly in the documentation.

…-sensitivity

# Conflicts:
#	ross/results.py
#	ross/rotor_assembly.py
#	ross/tests/test_labyrinth.py
…ization of the AMBs associated with the rotor, aiming to reduce the cognitive complexity of the integrate_system method.
…-sensitivity

# Conflicts:
#	ross/rotor_assembly.py
@ArthurIasbeck
Copy link
Contributor Author

Creation of the init_ambs_for_integrate method to isolate the initialization of the AMBs associated with the rotor, aiming to reduce the cognitive complexity of the integrate_system method.

@codecov-commenter
Copy link

codecov-commenter commented Oct 9, 2025

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 98.28080% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.27%. Comparing base (ab269a9) to head (2b64986).
⚠️ Report is 15 commits behind head on main.

Files with missing lines Patch % Lines
ross/results.py 97.38% 4 Missing ⚠️
ross/bearings/plain_journal.py 0.00% 1 Missing ⚠️
ross/probe.py 0.00% 1 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1149      +/-   ##
==========================================
+ Coverage   82.82%   83.27%   +0.45%     
==========================================
  Files          42       42              
  Lines       11561    11894     +333     
==========================================
+ Hits         9575     9905     +330     
- Misses       1986     1989       +3     
Files with missing lines Coverage Δ
ross/bearing_seal_element.py 94.80% <100.00%> (+0.23%) ⬆️
ross/gear_element.py 92.00% <ø> (ø)
ross/materials.py 90.00% <ø> (ø)
ross/rotor_assembly.py 93.17% <100.00%> (+0.55%) ⬆️
ross/shaft_element.py 95.69% <ø> (ø)
ross/stochastic/st_results.py 82.82% <100.00%> (ø)
ross/utils.py 92.04% <100.00%> (+1.11%) ⬆️
ross/bearings/plain_journal.py 65.20% <0.00%> (ø)
ross/probe.py 76.47% <0.00%> (ø)
ross/results.py 76.14% <97.38%> (+2.04%) ⬆️

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 388dfb8...2b64986. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@raphaeltimbo raphaeltimbo merged commit fa3ab3e into petrobras:main Oct 10, 2025
9 checks passed
raphaeltimbo added a commit to raphaeltimbo/ross-1 that referenced this pull request Oct 10, 2025
Document the new run_amb_sensitivity() method added in PR petrobras#1149,
which enables compliance with ISO 14839-3 and API STANDARD 617
requirements for Active Magnetic Bearing stability assessment.

Includes usage example showing how to compute sensitivities and
access results for AMB control system analysis.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale Issues with no activity for a long period

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants