-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrunGravitySweep.m
More file actions
101 lines (92 loc) · 4.19 KB
/
Copy pathrunGravitySweep.m
File metadata and controls
101 lines (92 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
function grav = runGravitySweep()
%RUNGRAVITYSWEEP Throughput vs ambient gravity across SR-GS-015's range.
% Simulates all three architecture models at gravity points spanning the
% required 0.1 g..12 g operating range (SR-GS-015), with the gravity
% physics built into the inline behaviors (ADR-026): batch vat drain
% rate scales with sqrt(g) (Torricelli), robotic prep derates gently
% above 4 g, and LeanBroth's human-paced prep derates from 2 g.
% Continuous pumped cook lines are gravity-insensitive by design.
%
% Produces gravityResults.mat / gravitySweep.csv and
% docs/figures/gravity_throughput.png, and prints each variant's
% compliant gravity range against the requirement-parsed floor.
G_PTS = [0.1 0.25 0.5 1 2 4 8 12];
T_STOP = 14400; T_SS = 7200;
proj = currentProject;
anaDir = char(fullfile(proj.RootFolder, 'analysis', 'results'));
figDir = char(fullfile(proj.RootFolder, 'docs', 'figures'));
M = load(fullfile(anaDir, 'variantMetrics.mat'));
floorBph = M.caps.Throughput_bph;
models = {'HyperCook','PhysicalHyperCook'; 'LeanBroth','PhysicalLeanBroth'; ...
'EverSimmer','PhysicalEverSimmer'};
nV = size(models,1); nG = numel(G_PTS);
% parsim requires a single model per input array: one batch per variant
thr = zeros(nV, nG);
for v = 1:nV
clear in
in(nG) = Simulink.SimulationInput(models{v,2}); %#ok<AGROW>
for gi = 1:nG
s = Simulink.SimulationInput(models{v,2});
s = s.setModelParameter('StopTime', num2str(T_STOP), ...
'SaveOutput','on', 'SaveFormat','Dataset');
s = s.setVariable('Gravity_g', G_PTS(gi), 'Workspace', models{v,2});
in(gi) = s;
end
out = parsim(in, 'ShowProgress', 'off', 'ShowSimulationManager', 'off');
for gi = 1:nG
assert(isempty(out(gi).ErrorMessage), '%s at %g g: %s', ...
models{v,1}, G_PTS(gi), out(gi).ErrorMessage);
flow = [];
for i = 1:out(gi).yout.numElements
y = out(gi).yout{i}.Values;
if isstruct(y) && isfield(y,'flow_bps'), flow = y.flow_bps; end
end
ss = flow.Time >= T_SS;
thr(v,gi) = trapz(flow.Time(ss), flow.Data(ss)) / (flow.Time(end)-T_SS) * 3600;
end
fprintf('%s swept\n', models{v,1});
end
grav.g = G_PTS;
grav.variants = models(:,1)';
grav.thr_bph = thr;
grav.floor_bph = floorBph;
grav.compliant = thr >= floorBph;
save(fullfile(anaDir, 'gravityResults.mat'), 'grav');
T = array2table(thr', 'VariableNames', models(:,1)');
T = addvars(T, G_PTS', 'Before', 1, 'NewVariableNames', 'Gravity_g');
writetable(T, fullfile(anaDir, 'gravitySweep.csv'));
% ---- figure (house style) ----
th = gsPlotTheme(); % dark house style; colors by variant name
palette = th.palette;
surf_ = th.surface; inkP = th.inkP; inkS = th.inkS; gridC = th.grid;
f = figure('Visible','off','Color',surf_,'Position',[100 100 900 420]);
ax = axes(f); hold(ax,'on');
for v = 1:nV
c = palette(models{v,1});
plot(ax, G_PTS, thr(v,:), '-o', 'Color', c, 'LineWidth', 2, ...
'MarkerFaceColor', c, 'MarkerEdgeColor', surf_, 'MarkerSize', 6);
end
yline(ax, floorBph, '--', 'SR-GS-002 floor (200 bph)', 'Color', th.limit, ...
'LineWidth', 1.2, 'FontSize', 9, 'LabelHorizontalAlignment','left');
set(ax,'XScale','log','XTick',G_PTS, 'XTickLabel',compose('%.2g',G_PTS), ...
'YGrid','on','GridColor',gridC,'GridAlpha',1,'Box','off','Color',surf_, ...
'XColor',inkS,'YColor',inkS,'FontSize',10);
xlabel(ax,'Ambient gravity (g, log scale)','Color',inkP);
ylabel(ax,'Steady-state packaged throughput (bph)','Color',inkP);
legend(ax, models(:,1)', 'Location','southeast','Box','off','TextColor',inkP);
title(ax,'Throughput across the SR-GS-015 gravity range (0.1 g to 12 g)', ...
'Color',inkP,'FontWeight','normal','FontSize',12);
exportgraphics(f, fullfile(figDir,'gravity_throughput.png'), 'Resolution', 200);
close(f);
fprintf('Gravity sweep (floor %.0f bph):\n', floorBph);
for v = 1:nV
ok = grav.compliant(v,:);
if all(ok), rng_ = 'compliant across the full 0.1-12 g range';
else
rng_ = sprintf('compliant at [%s] g, NOT at [%s] g', ...
strjoin(compose('%.2g', G_PTS(ok)), ' '), ...
strjoin(compose('%.2g', G_PTS(~ok)), ' '));
end
fprintf(' %-10s %s\n', models{v,1}, rng_);
end
end