%% Torque Converter Two-Mode Example - Basic Lock-up
% Copyright 2020 The MathWorks, Inc.
% Run this live script to see how the torque converter two-mode block works including lock-up clutch.
%% Setup and Run Simulation

sdltc2_modelname = 'sdl_torque_converter_two_mode';
if not(bdIsLoaded(sdltc2_modelname)), open_system(sdltc2_modelname); end
sdltc2_in = local_function_setup_simulation(sdltc2_modelname);
signalbuilder([sdltc2_modelname '/Input Signals'], 'activegroup',1)
sdltc2_in = sdltc2_in.setModelParameter('StopTime',num2str(100));
out_sdl_trqconv2m_lockup = sim(sdltc2_in);
clear sdltc2_modelname sdltc2_in

%
%% Plot Simulation Results
%% Input Torques, Brake Pressures, and Lock-up Clutch Pressure

sdltc2_lockup_plot1 = local_function_plot_inputs(out_sdl_trqconv2m_lockup, "topleft");

%% Torque Converter Output Torques

sdltc2_lockup_plot2 = local_function_plot_output_torques(out_sdl_trqconv2m_lockup, "topright");

%% Torque Converter Output Speeds

sdltc2_lockup_plot3 = local_function_plot_output_speeds(out_sdl_trqconv2m_lockup, "bottomleft");

%

function in = local_function_setup_simulation(model_name)
    in = Simulink.SimulationInput(model_name);
    
    in = in.setModelParameter('SimscapeLogOpenViewer', 'off');
    in = in.setModelParameter('EnablePacing', 'off');
    in = in.setModelParameter('SolverType', 'Variable-step');
    in = in.setModelParameter('Solver', 'VariableStepAuto');
    
    in = in.setModelParameter('SaveTime', 'on');
    in = in.setModelParameter('TimeSaveName', 'tout');
    
    in = in.setModelParameter('SignalLogging', 'on');
    in = in.setModelParameter('SignalLoggingName', 'logsout');
    
    in = in.setModelParameter('SimscapeLogType', 'local');
    in = in.setModelParameter('SimscapeLogSimulationStatistics', 'off');
    in = in.setModelParameter('SimscapeLogToSDI', 'on');
    in = in.setModelParameter('SimscapeLogName', 'logsoutssc');
    in = in.setModelParameter('SimscapeLogDecimation', 1);
    in = in.setModelParameter('SimscapeLogLimitData', 'off');
    
    in = in.setModelParameter('ReturnWorkspaceOutputs', 'on');
    in = in.setModelParameter('ReturnWorkspaceOutputsName', 'out');
end

%

function fobj = local_function_plot_inputs(out, winpos)
    t = out.tout;
    ImpTrqIn = out.logsout.get("Impeller Torque Input").Values.Data;
    TurTrqIn = out.logsout.get("Turbine Torque Input").Values.Data;
    ImpBrkIn = out.logsout.get("Impeller Brake Input").Values.Data;
    TurBrkIn = out.logsout.get("Turbine Brake Input").Values.Data;
    LucPres = out.logsout.get("Lock-up clutch pressure").Values.Data;
    
    if nargin==1
      fobj = figure;
    else
      p = local_function_winpos(winpos);
      fobj = figure('OuterPosition', [p.left, p.bottom, p.width, p.height]);
      fobj.MenuBar='none';  fobj.ToolBar='none';
    end
    
    subplot(3,1,1);  hold on;  grid on
    plot(t, ImpTrqIn, "DisplayName","Impeller", "LineWidth",2)
    plot(t, TurTrqIn, "DisplayName","Turbine", "LineWidth",2)
    legend("Location","northeast")
    title("Input Torques")
    ylabel("N*m")
    
    subplot(3,1,2);  hold on;  grid on
    plot(t, ImpBrkIn, "LineWidth",3)
    plot(t, TurBrkIn, "LineWidth",2, "LineStyle","--")
    legend("Impeller", "Turbine", "Location","northeast")
    title("Brake Pressures")
    ylabel("MPa")
    
    subplot(3,1,3);  hold on;  grid on
    plot(t, LucPres, "LineWidth",2)
    title("Lock-up Clutch Pressure")
    ylabel("kPa")
end  % function

%

function fobj = local_function_plot_output_torques(out, winpos)
    t = out.tout;
    ImpTrq = out.logsout.get("<ImpTrq>").Values.Data;
    TurTrq = out.logsout.get("<TurTrq>").Values.Data;
    TrqRatio = out.logsout.get("<TrqRatio>").Values.Data;
    
    if nargin==1
      fobj = figure;
    else
      p = local_function_winpos(winpos);
      fobj = figure('OuterPosition', [p.left, p.bottom, p.width, p.height]);
      fobj.MenuBar='none';  fobj.ToolBar='none';
    end
    
    subplot(3,1,[1 2]);  hold on;  grid on
    plot(t, ImpTrq, "DisplayName","Impeller", "LineWidth",2)
    plot(t, TurTrq, "DisplayName","Turbine", "LineWidth",2)
    legend("Location","northeast")
    title("Impeller and Turbine Torques")
    ylabel("N*m")
    
    subplot(3,1,3);  hold on;  grid on
    plot(t, TrqRatio, 'LineWidth',2)
    title("Torque Ratio")
    ylabel("(-)")
    ylim([0 2])
end  % function

%

function fobj = local_function_plot_output_speeds(out, winpos)
    t = out.tout;
    ImpSpd = out.logsout.get("<ImpSpd>").Values.Data;
    TurSpd = out.logsout.get("<TurSpd>").Values.Data;
    SpdDiff = out.logsout.get("<SpdDiff>").Values.Data;
    SpdRatio = out.logsout.get("<SpdRatio>").Values.Data;
    
    if nargin==1
      fobj = figure;
    else
      p = local_function_winpos(winpos);
      fobj = figure('OuterPosition', [p.left, p.bottom, p.width, p.height]);
      fobj.MenuBar='none';  fobj.ToolBar='none';
    end

    function hilightLockupDuration(x1, x2, y_lo, y_hi)
      patch("Vertices",[x1 y_lo; x2 y_lo; x2 y_hi; x1 y_hi], "Faces",[1:4],...
        "EdgeColor","green", "FaceColor","green", "FaceAlpha",.5);
    end

    subplot(3,1,1);  hold on;  grid on
    plot(t, ImpSpd, "DisplayName","Impeller", "LineWidth",2)
    plot(t, TurSpd, "DisplayName","Turbine", "LineWidth",2)
    legend("Location","northeast")
    title("Impeller and Turbine Speeds (Drive to Coast switch at 60s)")
    ylabel("rpm")
    
    subplot(3,1,2);  hold on;  grid on
    hilightLockupDuration(40,50, -500,500)
    hilightLockupDuration(70,80, -500,500)
    plot(t, SpdDiff, 'LineWidth',2)
    title("Speed Difference (lock-up 40-50s, 70-80s)")
    ylabel("rpm")
    
    subplot(3,1,3);  hold on;  grid on
    hilightLockupDuration(40,50, 0,1)
    hilightLockupDuration(70,80, 0,1)
    plot(t, SpdRatio, 'LineWidth',2)
    title("Speed Ratio (lock-up 40-50s, 70-80s)")
    ylabel("(-)")
end  % function

%

function pos = local_function_winpos(location)
    % Positions of 2x2 Figure windows. Only used when this script is run
    % programatically (rather than by clicking Run button in Live Editor).
    set(0, 'units','pixels')
    scr = get(0, 'screensize');
    screen_height = scr(4);
    
    fig_width = 480;
    fig_height = 340;
    gap = 5;
    
    p.topL.left = gap;
    p.topL.bottom = screen_height - gap - fig_height;

    p.topR.left = p.topL.left + fig_width + gap;
    p.topR.bottom = p.topL.bottom;

    p.botL.left = gap;
    p.botL.bottom = screen_height - gap - fig_height - gap - fig_height;

    p.botR.left = p.topL.left + fig_width + gap;
    p.botR.bottom = p.botL.bottom;
    
    if location == "topleft"
      pos.left   = p.topL.left;
      pos.bottom = p.topL.bottom;
    elseif location == "topright"
      pos.left   = p.topR.left;
      pos.bottom = p.topR.bottom;
    elseif location == "bottomleft"
      pos.left   = p.botL.left;
      pos.bottom = p.botL.bottom;
    elseif location == "bottomright"
      pos.left   = p.botR.left;
      pos.bottom = p.botR.bottom;
    end
    pos.width = fig_width;
    pos.height = fig_height;
end  % function