From 04de2ba5fbe6e3042eea0c7a90030de1f49c7102 Mon Sep 17 00:00:00 2001 From: ven-k <32921645+ven-k@users.noreply.github.com> Date: Mon, 10 Aug 2026 06:31:19 +0000 Subject: [PATCH] feat(RaceCar): single-cylinder crankshaft model with four-stroke torque ripple MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds RaceCar/, a Dyad model of a single-cylinder four-stroke crankshaft: crank and flywheel inertias joined by a torsional spring-damper, driven by a 55 N·m mean torque plus a 35 N·m ripple evaluated at half crank angle so the firing event lands once per two revolutions. The transient analysis runs 0.05 s from 550 rad/s and exposes crank angle, both shaft speeds, and transmitted torque; viz_submission/index.html renders those traces. Model source is unchanged from JuliaConVerify/, which this replaces. --- dyad/crankshaft.dyad | 47 +++++++ dyad/hello.dyad | 30 ---- viz_submission/index.html | 281 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 328 insertions(+), 30 deletions(-) create mode 100644 dyad/crankshaft.dyad delete mode 100644 dyad/hello.dyad create mode 100644 viz_submission/index.html diff --git a/dyad/crankshaft.dyad b/dyad/crankshaft.dyad new file mode 100644 index 0000000..b7052ce --- /dev/null +++ b/dyad/crankshaft.dyad @@ -0,0 +1,47 @@ +"Single-cylinder race-engine crankshaft test model" +test component SingleCylinderRaceEngine + "Crank throw and crank-web inertia" + crank = RotationalComponents.Components.Inertia(J = 0.012) + "Flywheel and output-end inertia" + flywheel = RotationalComponents.Components.Inertia(J = 0.018) + "Crankshaft torsional stiffness and internal damping" + shaft = RotationalComponents.Components.SpringDamper(c = 4000.0, d = 2.0) + transmitted_torque = RotationalComponents.Sensors.TorqueSensor() + "Crank-angle-synchronous four-stroke torque ripple" + crank_angle = RotationalComponents.Sensors.AngleSensor() + four_stroke_angle = BlockComponents.Math.Gain(k = 0.5) + combustion_shape = BlockComponents.Math.Sin() + ripple_torque = BlockComponents.Math.Gain(k = 35.0) + "Mean plus ripple indicated engine torque" + mean_torque = BlockComponents.Sources.Constant(k = 55.0) + total_torque = BlockComponents.Math.Add() + cylinder_torque = RotationalComponents.Sources.TorqueSource() + "Viscous bearing and accessory loss" + bearing_loss = RotationalComponents.Components.Damper(d = 0.1) + fixed = RotationalComponents.Components.Fixed() + crank_speed = RotationalComponents.Sensors.VelocitySensor() + output_speed = RotationalComponents.Sensors.VelocitySensor() +relations + initial crank.phi = 0.01375 + initial crank.w = 550.0 + initial flywheel.phi = 0.0 + initial flywheel.w = 550.0 + connect(crank_angle.phi, four_stroke_angle.u) + connect(four_stroke_angle.y, combustion_shape.u) + connect(combustion_shape.y, ripple_torque.u) + connect(mean_torque.y, total_torque.u1) + connect(ripple_torque.y, total_torque.u2) + connect(total_torque.y, cylinder_torque.tau) + connect(cylinder_torque.support, fixed.spline) + connect(cylinder_torque.spline, crank.spline_a) + connect(crank.spline_b, shaft.spline_a, crank_speed.spline, crank_angle.spline) + connect(shaft.spline_b, transmitted_torque.spline_a) + connect(transmitted_torque.spline_b, flywheel.spline_a) + connect(flywheel.spline_b, bearing_loss.spline_a, output_speed.spline) + connect(bearing_loss.spline_b, fixed.spline) +end + +analysis RaceEngineTransient + extends TransientAnalysis(stop = 0.05) + model = SingleCylinderRaceEngine() +end diff --git a/dyad/hello.dyad b/dyad/hello.dyad deleted file mode 100644 index cb61d64..0000000 --- a/dyad/hello.dyad +++ /dev/null @@ -1,30 +0,0 @@ -"A simple lumped thermal model" -component Hello - "Ambient temperature" - parameter T_inf::Temperature = 300 - "Initial temperature" - parameter T0::Temperature = 320 - "Convective heat transfer coefficient" - parameter h::CoefficientOfHeatTransfer = 0.7 - "Surface area" - parameter A::Area = 1.0 - "Mass of thermal capacitance" - parameter m::Mass = 0.1 - "Specific Heat" - parameter c_p::SpecificHeatCapacity = 1.2 - variable T::Temperature -relations - "Specify initial conditions" - initial T = T0 - "Newton's law of cooling/heating" - m * c_p * der(T) = h * A * (T_inf - T) -metadata {"Dyad": {"tests": {"case1": {"stop": 10, "expect": {"initial": {"T": 320}}}}}} -end - -analysis World - extends TransientAnalysis(stop = 10) - model = Hello(T_inf = T_inf, h = h) - parameter T_inf::Temperature = 300 - parameter h::CoefficientOfHeatTransfer = 0.7 -relations -end \ No newline at end of file diff --git a/viz_submission/index.html b/viz_submission/index.html new file mode 100644 index 0000000..dd6a756 --- /dev/null +++ b/viz_submission/index.html @@ -0,0 +1,281 @@ + + + + + + Single-cylinder crankshaft dynamics + + + + +
+
+
+

01 · Dynamics

+

Single-cylinder crankshaft dynamics

+

A two-inertia race-engine model showing how a four-stroke torque pulse travels through a compliant crankshaft into the flywheel.

+
+
Model output · 50 ms
+
+ +
+
+
Output speed
+
5272rpm
+
50.0 ms simulated
+
+
+
Cylinder torque
+
88.5N·m
+
Four-stroke input 20—90 N·m
+
+
+
Shaft transfer
+
78.1N·m
+
+
+
+
Torsional split
+
0.73rad/s
+
Peak observed 1.87 rad/s
+
+
+ +
+
+
+
Power transmission

Crank throw to flywheel

+ Power stroke +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CRANK · J 0.012 + FLYWHEEL · J 0.018 + +
+
Crank
552.9 rad/s
+
Flywheel
552.1 rad/s
+
Shaft twist
−19.2 mrad
+
+
+
The cylinder pulse accelerates the crank first; shaft compliance filters the pulse before it reaches the flywheel.
+
+ +
+
+
Angular velocity

Speed response

+
CrankFlywheel
+
+
+ + + + 560556552548 + 02550 ms + + + + + +
+
+ +
+
+
Torque transfer

Pulse through the shaft

+ 4-stroke · 720° +
+
+ + + + 905520 + + + + +
+
+
+ +
+ + +
50.0 / 50.0 ms
+
+ + +
+ + + +