%% Torque Converter Two-mode Example - Coast Mode Test
% Copyright 2020 The MathWorks, Inc.
% Run this live script to see the plots of torque converter opertaing characteristics in coast mode.
%% 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',3)
sdltc2_in = sdltc2_in.setModelParameter('StopTime',num2str(100));
out_sdl_trqconv2m_coast = sim(sdltc2_in);
clear sdltc2_modelname sdltc2_in

%
%% Plot Simulation Results
% To obtain plots for time series data such as converter speed and torque, check the box below. If unchecked, this script only produces plots as a function of speed ratio.

sdltc2_plot_time_series = false;

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

if sdltc2_plot_time_series
  sdltc2_coast_plot1 = local_function_plot_inputs(out_sdl_trqconv2m_coast, "topleft");
end

%% Torque Converter Output Torques

if sdltc2_plot_time_series
  sdltc2_coast_plot2 = local_function_plot_output_torques(out_sdl_trqconv2m_coast, "topright");
end

%% Torque Converter Output Speeds

if sdltc2_plot_time_series
  sdltc2_coast_plot3 = local_function_plot_output_speeds(out_sdl_trqconv2m_coast, "bottomleft");
end

%% Operating Characteristics

loc = "topleft";
if sdltc2_plot_time_series, loc = "bottomright"; end
sdltc2_coast_plot4 = local_function_plot_performance(out_sdl_trqconv2m_coast, loc);
clear loc sdltc2_plot_time_series

%

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_start_step = 1;
    t = out.tout(t_start_step:end);
    ImpTrqIn = out.logsout.get("Impeller Torque Input").Values.Data(t_start_step:end);
    TurTrqIn = out.logsout.get("Turbine Torque Input").Values.Data(t_start_step:end);
    ImpBrkIn = out.logsout.get("Impeller Brake Input").Values.Data(t_start_step:end);
    TurBrkIn = out.logsout.get("Turbine Brake Input").Values.Data(t_start_step:end);
    LucPres = out.logsout.get("Lock-up clutch pressure").Values.Data(t_start_step:end);
    
    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",3, "LineStyle","--")
    plot(t, TurTrqIn, "DisplayName","Turbine",  "LineWidth",2)
    legend("Location","southeast")
    title("Input Torque on Turbine (no input torque on impeller)")
    ylabel("N*m")
    
    subplot(3,1,2);  hold on;  grid on
    plot(t, ImpBrkIn, "DisplayName","Impeller", "LineWidth",2)
    plot(t, TurBrkIn, "DisplayName","Turbine",  "LineWidth",3, "LineStyle","--")
    legend("Location","northeast")
    title("Brake Pressure on Impeller (no brake on turbine)")
    ylabel("MPa")
    
    subplot(3,1,3);  hold on;  grid on
    plot(t, LucPres, "LineWidth",2)
    title("Lock-up Clutch Pressure")
    ylabel("kPa")
end

%

function fobj = local_function_plot_output_torques(out, winpos)
    t = out.tout;
    t = t(out.tout>0.005);
    ImpTrq = out.logsout.get("<ImpTrq>").Values.Data(out.tout>0.005);
    TurTrq = out.logsout.get("<TurTrq>").Values.Data(out.tout>0.005);
    TrqRatio = out.logsout.get("<TrqRatio>").Values.Data(out.tout>0.005);

    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","west")
    title("Impeller and Turbine Torques")
    ylabel("N*m")
    
    subplot(3,1,3);  hold on;  grid on
    plot(t, TrqRatio, 'LineWidth',2)
    title("Torque Ratio (always 1 in coast mode)")
    ylabel("(-)")
    ylim([0.9 1.1])
end

%

function fobj = local_function_plot_output_speeds(out, winpos)
    t = out.tout;
    t = t(out.tout>0.005);
    ImpSpd = out.logsout.get("<ImpSpd>").Values.Data(out.tout>0.005);
    TurSpd = out.logsout.get("<TurSpd>").Values.Data(out.tout>0.005);
    SpdDiff = out.logsout.get("<SpdDiff>").Values.Data(out.tout>0.005);
    SpdRatio = out.logsout.get("<SpdRatio>").Values.Data(out.tout>0.005);

    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, ImpSpd, "DisplayName","Impeller", "LineWidth",2)
    plot(t, TurSpd, "DisplayName","Turbine",  "LineWidth",2)
    legend("Location","west")
    title("Impeller and Turbine Speeds")
    ylabel("rpm")

    subplot(3,1,2);  hold on;  grid on
    plot(t, SpdDiff, 'LineWidth',2)
    title("Speed Difference")
    ylabel("rpm")

    subplot(3,1,3);  hold on;  grid on
    plot(t, SpdRatio, 'LineWidth',2)
    title("Speed Ratio")
    ylabel("(-)")
end

%

function fobj = local_function_plot_performance(out, winpos)
    SpdRatio = out.logsout.get("<SpdRatio>").Values.Data(out.tout>0.005);
    TrqRatio = out.logsout.get("<TrqRatio>").Values.Data(out.tout>0.005);
    ImpSpd = out.logsout.get("<ImpSpd>").Values.Data(out.tout>0.005);
    TurSpd = out.logsout.get("<TurSpd>").Values.Data(out.tout>0.005);
    
    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

    Efficiency = SpdRatio.*TrqRatio;
    
    subplot(3,1,1);  hold on;  grid on
    plot(SpdRatio, TrqRatio, 'LineWidth',2)
    title("Torque Ratio (always 1 in coast mode)")
    ylabel("(-)")
    xlim([0 1])
    ylim([0.9 1.1])
    
    subplot(3,1,2);  hold on;  grid on
    plot(SpdRatio, ImpSpd, 'LineWidth',2, "DisplayName","Impeller")
    plot(SpdRatio, TurSpd, 'LineWidth',2, "DisplayName","Turbine")
    legend("Location","southeast")
    title("Impeller and Turbine Speeds (partial lock-up near 1)")
    ylabel("rpm")
    xlim([0 1])
    
    subplot(3,1,3);  hold on;  grid on
    plot(SpdRatio, Efficiency, 'LineWidth',2)
    title("Efficiency")
    xlabel("Speed Ratio")
    ylabel("(-)")
    xlim([0 1])
end

%

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