Skip to content

Commit cf462a1

Browse files
authored
Merge pull request #1280 from kiracofe8/rotor_Id_summary
Rotor id summary
2 parents 590c9de + 59200c5 commit cf462a1

4 files changed

Lines changed: 180 additions & 9 deletions

File tree

docs/user_guide/tutorial_part_5.ipynb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4592,10 +4592,8 @@
45924592
"metadata": {},
45934593
"outputs": [],
45944594
"source": [
4595-
"A = [[0, 1],\n",
4596-
" [-2, -0.5]]\n",
4597-
"B = [[0],\n",
4598-
" [1]]\n",
4595+
"A = [[0, 1], [-2, -0.5]]\n",
4596+
"B = [[0], [1]]\n",
45994597
"C = [[1, 0]]\n",
46004598
"\n",
46014599
"Q_lqr = np.diag([10, 1])\n",
@@ -4631,7 +4629,7 @@
46314629
"outputs": [],
46324630
"source": [
46334631
"C_lead = lead_lag(tau=0.02, alpha=0.1, k=2.0)\n",
4634-
"C_lag = lead_lag(tau=0.5, alpha=5.0, k=1.0)"
4632+
"C_lag = lead_lag(tau=0.5, alpha=5.0, k=1.0)"
46354633
]
46364634
},
46374635
{
@@ -4723,7 +4721,7 @@
47234721
" pid(2, 1, 0.02, n_f=200),\n",
47244722
" lead_lag(0.03, 0.1),\n",
47254723
" notch_filter(120, 0.02, 0.2),\n",
4726-
" low_pass_filter(400)\n",
4724+
" low_pass_filter(400),\n",
47274725
")"
47284726
]
47294727
},
@@ -4784,12 +4782,14 @@
47844782
],
47854783
"source": [
47864784
"plot_frequency_response(\n",
4787-
" C, N, C * N,\n",
4785+
" C,\n",
4786+
" N,\n",
4787+
" C * N,\n",
47884788
" legends=[\"Controller\", \"Filter\", \"Combined\"],\n",
47894789
" w_min=1e-1,\n",
47904790
" w_max=1e5,\n",
47914791
" n_points=1500,\n",
4792-
" title=\"Bode (Controller / Filter / Combined)\"\n",
4792+
" title=\"Bode (Controller / Filter / Combined)\",\n",
47934793
")"
47944794
]
47954795
},

ross/results.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5290,13 +5290,14 @@ class SummaryResults(Results):
52905290
The figure object with the tables plot.
52915291
"""
52925292

5293-
def __init__(self, df_shaft, df_disks, df_bearings, brg_forces, CG, Ip, tag):
5293+
def __init__(self, df_shaft, df_disks, df_bearings, brg_forces, CG, Ip, It, tag):
52945294
self.df_shaft = df_shaft
52955295
self.df_disks = df_disks
52965296
self.df_bearings = df_bearings
52975297
self.brg_forces = brg_forces
52985298
self.CG = CG
52995299
self.Ip = Ip
5300+
self.It = It
53005301
self.tag = tag
53015302

53025303
def plot(self):
@@ -5334,6 +5335,7 @@ def plot(self):
53345335
"Total lenght": [self.df_shaft["nodes_pos_r"].iloc[-1]],
53355336
"CG": ["{:.3f}".format(self.CG)],
53365337
"Ip": ["{:.3e}".format(self.Ip)],
5338+
"It": ["{:.3e}".format(self.It)],
53375339
"Rotor Mass": [
53385340
"{:.3f}".format(np.sum(self.df_shaft["m"]) + np.sum(self.df_disks["m"]))
53395341
],

ross/rotor_assembly.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,24 @@ def flatten(l):
567567
self.G0 = G0
568568
self.Ksdt0 = Ksdt0
569569

570+
# Calculation of overall rotor transverse (diametral) inertia (includes only DOFs located at the shaft element DOF, excludes point masses that are outside the shaft).
571+
# This is only calculating Iyy. Assuming Ixx is the same.
572+
# First, set up a vector corresponding to rigid body rotation of the entire rotor
573+
v = np.zeros([self.ndof])
574+
for i, elm in enumerate(self.shaft_elements):
575+
dofs = list(elm.dof_global_index.values())
576+
y0 = elm.dof_mapping()["y_0"]
577+
a0 = elm.dof_mapping()["alpha_0"]
578+
y1 = elm.dof_mapping()["y_1"]
579+
a1 = elm.dof_mapping()["alpha_1"]
580+
581+
v[dofs[y0]] = -(nodes_pos_l[i] - self.CG) # y
582+
v[dofs[y1]] = -(nodes_pos_r[i] - self.CG) # y
583+
v[dofs[a0]] = 1 # alpha
584+
v[dofs[a1]] = 1 # alpha
585+
# Then, use the vector to compute diametral aka transverse inertia of the entire rotor.
586+
self.It = v @ (self.M0 @ v.T)
587+
570588
def _set_tag(self, tag):
571589
"""Set the tag for the current rotor."""
572590
self.tag = tag or "Rotor 0"
@@ -4334,6 +4352,7 @@ def summary(self):
43344352
forces,
43354353
self.CG,
43364354
self.Ip,
4355+
self.It,
43374356
self.tag,
43384357
)
43394358
return results

ross/tests/test_rotor_assembly.py

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2907,3 +2907,153 @@ def test_run_amb_sensitivity():
29072907
results.max_abs_sensitivities["Magnetic Bearing 0"]["x"],
29082908
results_custom_freq.max_abs_sensitivities["Magnetic Bearing 0"]["x"],
29092909
)
2910+
2911+
2912+
@pytest.fixture
2913+
def rotor3a():
2914+
# same as rotor 3 but no disks
2915+
i_d = 0
2916+
o_d = 0.05
2917+
n = 6
2918+
L = [0.25 for _ in range(n)]
2919+
2920+
shaft_elem = [
2921+
ShaftElement(
2922+
l,
2923+
i_d,
2924+
o_d,
2925+
material=steel,
2926+
shear_effects=True,
2927+
rotary_inertia=True,
2928+
gyroscopic=True,
2929+
)
2930+
for l in L
2931+
]
2932+
2933+
stfx = 1e6
2934+
stfy = 0.8e6
2935+
bearing0 = BearingElement(0, kxx=stfx, kyy=stfy, cxx=0)
2936+
bearing1 = BearingElement(6, kxx=stfx, kyy=stfy, cxx=0)
2937+
2938+
return Rotor(shaft_elem, [], [bearing0, bearing1])
2939+
2940+
2941+
@pytest.fixture
2942+
def rotor3b():
2943+
# # same as rotor 3, disks at center.
2944+
i_d = 0
2945+
o_d = 0.05
2946+
n = 6
2947+
L = [0.25 for _ in range(n)]
2948+
2949+
shaft_elem = [
2950+
ShaftElement(
2951+
l,
2952+
i_d,
2953+
o_d,
2954+
material=steel,
2955+
shear_effects=True,
2956+
rotary_inertia=True,
2957+
gyroscopic=True,
2958+
)
2959+
for l in L
2960+
]
2961+
2962+
disk0 = DiskElement.from_geometry(3, steel, 0.07, 0.05, 0.28)
2963+
disk1 = DiskElement.from_geometry(3, steel, 0.07, 0.05, 0.35)
2964+
2965+
stfx = 1e6
2966+
stfy = 0.8e6
2967+
bearing0 = BearingElement(0, kxx=stfx, kyy=stfy, cxx=0)
2968+
bearing1 = BearingElement(6, kxx=stfx, kyy=stfy, cxx=0)
2969+
2970+
return Rotor(shaft_elem, [disk0, disk1], [bearing0, bearing1])
2971+
2972+
2973+
@pytest.fixture
2974+
def rotor3c():
2975+
# no density on shaft elements. test ONLY the It of the disks
2976+
i_d = 0
2977+
o_d = 0.05
2978+
n = 6
2979+
L = [0.25 for _ in range(n)]
2980+
2981+
mat0 = Material(name="Steel0", rho=0, E=211e9, Poisson=0.3)
2982+
2983+
shaft_elem = [
2984+
ShaftElement(
2985+
l,
2986+
i_d,
2987+
o_d,
2988+
material=mat0,
2989+
shear_effects=True,
2990+
rotary_inertia=True,
2991+
gyroscopic=True,
2992+
)
2993+
for l in L
2994+
]
2995+
2996+
disk0 = DiskElement.from_geometry(0, steel, 0.07, 0.05, 0.28)
2997+
disk1 = DiskElement.from_geometry(6, steel, 0.07, 0.05, 0.35)
2998+
2999+
stfx = 1e6
3000+
stfy = 0.8e6
3001+
bearing0 = BearingElement(0, kxx=stfx, kyy=stfy, cxx=0)
3002+
bearing1 = BearingElement(6, kxx=stfx, kyy=stfy, cxx=0)
3003+
3004+
return Rotor(shaft_elem, [disk0, disk1], [bearing0, bearing1])
3005+
3006+
3007+
# this test checks if Rotor.m calculates mass the same way as directly summing the mass matrix
3008+
def test_rotor_m(rotor3):
3009+
mm = rotor3.M()[::6, ::6].sum()
3010+
3011+
assert rotor3.m == pytest.approx(mm, rel=1e-8)
3012+
3013+
3014+
# this test checks if Rotor.CG calculates the CG same way as a direct vector calcution from the mass matrix
3015+
def test_rotor_CG(rotor3):
3016+
mm = rotor3.M()[::6, ::6]
3017+
mm2 = np.sum(mm, axis=0)
3018+
CG2 = np.matmul(mm2, rotor3.nodes_pos) / rotor3.m
3019+
3020+
assert rotor3.CG == pytest.approx(CG2, rel=1e-8)
3021+
3022+
3023+
def test_rotor_it(rotor1, rotor3, rotor3a, rotor3b, rotor3c):
3024+
L = 0.5
3025+
r = 0.05 / 2
3026+
It1 = (rotor1.m / 12) * (3 * r**2 + L**2)
3027+
tol = 2e-8
3028+
3029+
assert rotor1.It == pytest.approx(It1, rel=tol) # check with no disks
3030+
3031+
L3 = 0.25 * 6
3032+
It3a = (rotor3a.m / 12) * (3 * r**2 + L3**2)
3033+
assert rotor3a.It == pytest.approx(It3a, rel=tol) # second check with no disks
3034+
3035+
# disk0 It=0.17808928257067666, m=32.58972765304033
3036+
# disk1 It=0.42358058405433824, m=51.5252611115262
3037+
3038+
It3b = It3a + 0.17808928257067666 + 0.42358058405433824
3039+
assert rotor3b.It == pytest.approx(It3b, rel=tol) # check with disks at CG
3040+
3041+
It3c = (
3042+
0.17808928257067666
3043+
+ 32.58972765304033 * (0 - rotor3c.CG) ** 2
3044+
+ 0.42358058405433824
3045+
+ 51.5252611115262 * (1.5 - rotor3c.CG) ** 2
3046+
)
3047+
assert rotor3c.It == pytest.approx(
3048+
It3c, rel=tol
3049+
) # check with ONLY disks off center
3050+
3051+
# check with off center disks and shaft elements
3052+
It3 = (
3053+
(It3a + (rotor3.CG - 0.75) ** 2 * rotor3a.m)
3054+
+ 0.17808928257067666
3055+
+ 32.58972765304033 * (0.5 - rotor3.CG) ** 2
3056+
+ 0.42358058405433824
3057+
+ 51.5252611115262 * (1.0 - rotor3.CG) ** 2
3058+
)
3059+
assert rotor3.It == pytest.approx(It3, rel=tol)

0 commit comments

Comments
 (0)