/ proof-of-concept / cymbalsim
Sign in
proof-of-concept / cymbalsim
cymbalsim / src / presets.ts
257 lines · 11.4 KBBlameHistoryRaw
1// Predefined design scripts, selectable from the interface. Each is a
2// MATLAB-syntax script that fills in the `design` struct; see design.ts for
3// the fields. A script is self-contained: the shape functions it uses are
4// ordinary MATLAB functions written at the bottom of the script itself.
6export interface Preset {
7 id: string;
8 label: string;
9 source: string;
12const flatRectangle = `% A flat rectangular sheet of stainless steel (turn the stand off in the
13% Stand parameters to let it hang freely).
14% The script is an ordinary MATLAB program that fills in a struct named
15% design. Lengths are meters; the constants at the top are the only units.
16% A field can be a number or a function handle @(x, y, r, theta) of the
17% point, measured from the center of the bounding box; the handles are
18% applied to whole grid matrices, so use elementwise operators (.*, ./, .^)
19% inside them. Anything else a script needs it defines itself, as MATLAB
20% functions at the bottom; the other presets show how. The decay of the
21% sound is not prescribed: it follows from the loss factor of the metal, its
22% thermal constants (thermoelastic damping), the radiation of each mode into
23% the air, and the felt of a stand.
24inch = 0.0254; % m
25mm = 1e-3; % m
27design.name = 'Flat steel rectangle';
28design.material.E = 170e9; % Young's modulus [Pa]
29design.material.nu = 0.29; % Poisson ratio
30design.material.rho = 7900; % density [kg/m^3]
31design.material.lossFactor = 3e-4; % internal friction of the metal (typical published value)
32design.material.alpha = 17e-6; % thermal expansion [1/K] } for the thermoelastic damping
33design.material.cp = 500; % specific heat [J/(kg K)] }
34design.material.k = 16; % conductivity [W/(m K)] }
35design.bounds.width = 12*inch; % bounding box [m]
36design.bounds.height = 18*inch;
37design.thickness = 0.79*mm;
38`;
40const aluminumSquare = `% A flat 12 inch square of 6061-T6 aluminum, 1.02 mm thick, with a center
41% hole for the rod of a stand (the stand itself is set in the Stand
42% parameters beside the script). Aluminum is a third the density of steel and a third as stiff, so
43% the bending frequencies land near those of a steel plate of the same size
44% and thickness. Its high thermal expansion and conductivity give it the
45% strongest thermoelastic damping of the three metals here.
46inch = 0.0254; mm = 1e-3;
47W = 12*inch; hole = 13*mm;
49design.name = 'Aluminum 6061-T6 square';
50design.material.E = 68.9e9; % Young's modulus [Pa]
51design.material.nu = 0.33; % Poisson ratio
52design.material.rho = 2700; % density [kg/m^3]
53design.material.lossFactor = 1e-4; % internal friction of the metal (typical published value)
54design.material.alpha = 23.6e-6; % thermal expansion [1/K] } for the thermoelastic damping
55design.material.cp = 896; % specific heat [J/(kg K)] }
56design.material.k = 167; % conductivity [W/(m K)] }
57design.bounds.width = W;
58design.bounds.height = W;
59design.inside = @(x, y, r, theta) r >= hole/2;
60design.thickness = 1.02*mm;
61`;
63const bowedRectangle = `% The same steel sheet with a 3 mm parabolic bow across its width, the
64% kind of bow that rolling and handling leave in real sheet metal. The bow
65% makes the sheet a shallow shell: the linear modes couple bending to
66% stretching, and the full simulation oil-cans and wobbles when struck.
67inch = 0.0254; mm = 1e-3;
68W = 12*inch; H = 18*inch;
70design.name = 'Bowed steel rectangle';
71design.material.E = 170e9;
72design.material.nu = 0.29;
73design.material.rho = 7900;
74design.material.lossFactor = 3e-4; % internal friction of the metal (typical published value)
75design.material.alpha = 17e-6; % thermal expansion [1/K] } for the thermoelastic damping
76design.material.cp = 500; % specific heat [J/(kg K)] }
77design.material.k = 16; % conductivity [W/(m K)] }
78design.bounds.width = W;
79design.bounds.height = H;
80design.thickness = 0.79*mm;
81design.profile = @(x, y, r, theta) bow(x, W, 3*mm, 0.3); % stress-free height [m]
83function v = bow(s, span, sag, offset)
84% A parabola of the given sag across a span centered on 0; s runs along the
85% span, and the offset in -1..1 moves the crest toward one end.
86t = 2*s/span;
87v = sag * (1 - t.^2) .* (1 + offset*t);
88end
89`;
91const flatDisc = `% A flat 16 inch bronze disc with a center hole for the rod of a stand. The
92% stand itself (the felt pads, the preload, the position of the rod) is set
93% in the Stand parameters beside the script, so that any design can be put
94% on it or taken off it; the pads hold the disc level and let it bounce and
95% rock.
96inch = 0.0254; mm = 1e-3;
97D = 16*inch; hole = 13*mm;
99design.name = 'Flat bronze disc';
100design.material.E = 110e9; % bronze
101design.material.nu = 0.34;
102design.material.rho = 8800;
103design.material.lossFactor = 2e-4; % internal friction of the metal (typical published value)
104design.material.alpha = 18e-6; % thermal expansion [1/K] } for the thermoelastic damping
105design.material.cp = 370; % specific heat [J/(kg K)] }
106design.material.k = 40; % conductivity [W/(m K)] }
107design.bounds.width = D;
108design.bounds.height = D;
109design.inside = @(x, y, r, theta) (r <= D/2) & (r >= hole/2);
110design.thickness = 1.0*mm;
111`;
113const crash16 = `% A 16 inch flat crash: bronze, lathed to a taper from 1.2 mm at the
114% center to 0.7 mm at the edge, with a center hole for the stand. Flat, so
115% the linear modes are pure bending modes; the tapered profile is what
116% makes it a crash rather than a ride.
117inch = 0.0254; mm = 1e-3;
118D = 16*inch; R = D/2; hole = 13*mm;
119tCenter = 1.2*mm; tEdge = 0.7*mm;
121design.name = '16 inch flat crash';
122design.material.E = 110e9;
123design.material.nu = 0.34;
124design.material.rho = 8800;
125design.material.lossFactor = 2e-4; % internal friction of the metal (typical published value)
126design.material.alpha = 18e-6; % thermal expansion [1/K] } for the thermoelastic damping
127design.material.cp = 370; % specific heat [J/(kg K)] }
128design.material.k = 40; % conductivity [W/(m K)] }
129design.bounds.width = D;
130design.bounds.height = D;
131design.inside = @(x, y, r, theta) (r <= R) & (r >= hole/2);
132design.thickness = @(x, y, r, theta) tCenter + (tEdge - tCenter) * ramp(40*mm, R, r);
134function v = ramp(a, b, x)
135% 0 at x = a, 1 at x = b, clamped to that range outside.
136v = min(max((x - a) ./ (b - a), 0), 1);
137end
138`;
140const ride20 = `% A 20 inch flat ride: thicker bronze, 2.2 mm at the center to 1.4 mm at
141% the edge, with a center hole for the stand. The thickness raises every
142% frequency in proportion, and the ride has a clearer ping and a longer
143% decay than the crash; try a small preload in the Stand parameters for a
144% loose wing nut.
145inch = 0.0254; mm = 1e-3;
146D = 20*inch; R = D/2; hole = 13*mm;
148design.name = '20 inch flat ride';
149design.material.E = 110e9;
150design.material.nu = 0.34;
151design.material.rho = 8800;
152design.material.lossFactor = 2e-4; % internal friction of the metal (typical published value)
153design.material.alpha = 18e-6; % thermal expansion [1/K] } for the thermoelastic damping
154design.material.cp = 370; % specific heat [J/(kg K)] }
155design.material.k = 40; % conductivity [W/(m K)] }
156design.bounds.width = D;
157design.bounds.height = D;
158design.inside = @(x, y, r, theta) (r <= R) & (r >= hole/2);
159design.thickness = @(x, y, r, theta) 2.2*mm + (1.4*mm - 2.2*mm) * ramp(50*mm, R, r);
161function v = ramp(a, b, x)
162v = min(max((x - a) ./ (b - a), 0), 1);
163end
164`;
166const crashBell16 = `% A 16 inch crash with a shallow bow and a cosine bell. The
167% profile makes the cymbal a shallow shell: the linear model couples the
168% bending to the stretching (a larger eigenproblem, so the modes take
169% longer), and the full simulation shows the asymmetric nonlinearity of a
170% curved plate. The slopes are kept small; the interface reports the
171% largest one.
172inch = 0.0254; mm = 1e-3;
173D = 16*inch; R = D/2; hole = 13*mm;
174bellR = 55*mm; bellH = 8*mm; bowH = 10*mm;
175tCenter = 1.2*mm; tEdge = 0.7*mm;
177design.name = '16 inch crash with bell';
178design.material.E = 110e9;
179design.material.nu = 0.34;
180design.material.rho = 8800;
181design.material.lossFactor = 2e-4; % internal friction of the metal (typical published value)
182design.material.alpha = 18e-6; % thermal expansion [1/K] } for the thermoelastic damping
183design.material.cp = 370; % specific heat [J/(kg K)] }
184design.material.k = 40; % conductivity [W/(m K)] }
185design.bounds.width = D;
186design.bounds.height = D;
187design.inside = @(x, y, r, theta) (r <= R) & (r >= hole/2);
188design.thickness = @(x, y, r, theta) tCenter + (tEdge - tCenter) * ramp(bellR, R, r);
189design.profile = @(x, y, r, theta) bowH * (1 - (r/R).^2) + dome(r, bellR, bellH);
191function v = ramp(a, b, x)
192v = min(max((x - a) ./ (b - a), 0), 1);
193end
195function v = dome(d, radius, height)
196% A cosine dome of the given height and base radius, with zero slope both at
197% its rim and at its apex; d is the distance from its center.
198v = 0.5 * height * (1 + cos(pi * d / radius)) .* (d < radius);
199end
200`;
202const ellipse = `% An elliptical steel plate. The outline is any test on the point;
203% an ellipse inscribed in the bounding box here. The degenerate mode pairs
204% of a disc split on an ellipse, which the mode browser shows.
205inch = 0.0254; mm = 1e-3;
206A = 14*inch; B = 10*inch;
208design.name = 'Steel ellipse';
209design.material.E = 170e9;
210design.material.nu = 0.29;
211design.material.rho = 7900;
212design.material.lossFactor = 3e-4; % internal friction of the metal (typical published value)
213design.material.alpha = 17e-6; % thermal expansion [1/K] } for the thermoelastic damping
214design.material.cp = 500; % specific heat [J/(kg K)] }
215design.material.k = 16; % conductivity [W/(m K)] }
216design.bounds.width = A;
217design.bounds.height = B;
218design.inside = @(x, y, r, theta) (x/(A/2)).^2 + (y/(B/2)).^2 <= 1;
219design.thickness = 1.0*mm;
220`;
222const thunderSheet = `% A thunder sheet: a large thin steel sheet, hung from a corner in reality
223% (turn the stand off). Its modes
224% are dense and low, and the full simulation turns a hard hit into a roar.
225% Long at the default spacing; a coarser grid keeps it interactive.
226inch = 0.0254; mm = 1e-3;
228design.name = 'Thunder sheet';
229design.material.E = 200e9;
230design.material.nu = 0.3;
231design.material.rho = 7850;
232design.material.lossFactor = 3e-4; % internal friction of the metal (typical published value)
233design.material.alpha = 12e-6; % thermal expansion [1/K] } for the thermoelastic damping
234design.material.cp = 460; % specific heat [J/(kg K)] }
235design.material.k = 50; % conductivity [W/(m K)] }
236design.bounds.width = 24*inch;
237design.bounds.height = 36*inch;
238design.thickness = 0.5*mm;
239`;
241export const PRESETS: Preset[] = [
242 { id: "flat-rectangle", label: "Flat steel rectangle", source: flatRectangle },
243 { id: "aluminum-square", label: "Aluminum 6061-T6 square", source: aluminumSquare },
244 { id: "bowed-rectangle", label: "Bowed steel rectangle", source: bowedRectangle },
245 { id: "flat-disc", label: "Flat bronze disc", source: flatDisc },
246 { id: "crash-16", label: "16 inch flat crash", source: crash16 },
247 { id: "ride-20", label: "20 inch flat ride", source: ride20 },
248 { id: "crash-bell-16", label: "16 inch crash with bell", source: crashBell16 },
249 { id: "ellipse", label: "Steel ellipse", source: ellipse },
250 { id: "thunder-sheet", label: "Thunder sheet", source: thunderSheet },
251];
253export const DEFAULT_PRESET = "crash-16";
255export function presetById(id: string): Preset | undefined {
256 return PRESETS.find((p) => p.id === id);
↑↓ move↵openescclose