using MECF.Framework.Common.DataCenter; using MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel.Params; using System; namespace MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel { public class RecipeGasFlowCalculatorBase : IRecipeGasFlowCalculator { #region Properties public virtual string NameTcsBubbleLowFlow => "Mfc11.Ramp"; public virtual string NameTcsBubbleHighFlow => "Mfc10.Ramp"; public virtual string NameTcsPushFlow => "Mfc12.Ramp"; public virtual string NameTcsFlowMode => "TCS.SetValve"; public virtual string NameTmaBubbleFlow => "Mfc7.Ramp"; public virtual string NameTmaPushFlow => "Mfc7.Ramp"; public virtual string NameTmaFlowMode => "Mfc7.Ramp"; public virtual string NameSiSourceSplitRatio => "SiSourSplitRatio"; public virtual string NameSiSourceTotalFlow => "SiSourTotalFlow"; public virtual string NameSiSourceInnerFlow => "Mfc23.Ramp"; public virtual string NameSiSourceMiddleFlow => "Mfc22.Ramp"; public virtual string NameSiSourceOuterFlow => "Mfc9.Ramp"; public virtual string NameCxHxFlow => "Mfc16.Ramp"; public virtual string NameCxHxFlowMode => "C2H4.SetValve"; public virtual string NameCSourceSplitRatio => "CSourSplitRatio"; public virtual string NameCSourceTotalFlow => "CSourTotalFlow"; public virtual string NameCSourcePushFlow => "Mfc15.Ramp"; public virtual string NameCSourceInnerFlow => "Mfc26.Ramp"; public virtual string NameCSourceMiddleFlow => "Mfc25.Ramp"; public virtual string NameCSourceOuterFlow => "Mfc15.Ramp"; public virtual string NameDopeTotalFlow => "DopeTotalFlow"; public virtual string NameDopeSplitRatio => "DopeSplitRatio"; public virtual string NameDopeInnerFlow => "Mfc20.Ramp"; public virtual string NameDopeMiddleFlow => "Mfc19.Ramp"; public virtual string NameDopeOuterFlow => "Mfc2.Ramp"; public virtual string NameN2ActualFlow => "N2ActualFlow"; public virtual string NameN2LowFlow => "Mfc4.Ramp"; public virtual string NameDilutionFlowForN2 => "Mfc3.Ramp"; public virtual string NameDilutedN2Flow => "Mfc6.Ramp"; public virtual string NameShTotalFlow => "SHTotalFlow"; public virtual string NameShTotalFlowSplitRatio => "SHTotalFlowSplitRatio"; public virtual string NameShPushTotalFlow => "SHSuppTotalFlow"; public virtual string NameShInnerFlow => "SHInnerFlow"; public virtual string NameShMiddleFlow => "SHMidFlow"; public virtual string NameShOuterFlow => "SHOutterFlow"; public virtual string NameInnerPushFlow => "Mfc29.Ramp"; public virtual string NameMiddlePushFlow => "Mfc31.Ramp"; public virtual string NameOuterPushFlow => "Mfc28.Ramp"; public virtual string NameCarryGasFlow => "Mfc40.Ramp"; public virtual string NameSiH4Flow => "Mfc14.Ramp"; public virtual string NameSiH4FlowMode => "SiH4.SetValve"; public virtual string NameVentPushFlow => "Mfc1.Ramp"; public virtual string NameTotalVentFlow => "TotalVentFlow"; public virtual string NameHclFlow => "Mfc13.Ramp"; public virtual string NameHclFlowMode => "HCl.SetValve"; public virtual string NameN2HighFlow => "Mfc5.Ramp"; public virtual string NameN2FlowMode => "N2Dilution.SetValve"; public virtual string NameN2HighFlowMode => "N2HighDoping.SetValve"; #endregion public void Calculate(RecipeStep step) { CalSiSourceFlow(step); CalCSourceFlow(step); CalDopeFlow(step); CalShSupplementFlow(step); CalVentFlow(step, step.Parent.Module); } #region Gas Flow Calculation protected virtual double GetTcsFlow(RecipeStep step, string selectedChamber) { var currentTcsBubbleLowFlow = ((DoubleParam)step.FindParamByControlName(NameTcsBubbleLowFlow)).Value; var currentTcsBubbleHighFlow = ((DoubleParam)step.FindParamByControlName(NameTcsBubbleHighFlow)).Value; var currentTcsPushFlow = ((DoubleParam)step.FindParamByControlName(NameTcsPushFlow)).Value; var currentTcsFlowMode = ((ComboxParam)step.FindParamByControlName(NameTcsFlowMode)).Value; var tcsFlow = 0d; var tcsEff = (double)QueryDataClient.Instance.Service.GetConfig($"PM.{selectedChamber}.Efficiency.TCS-Eff"); if (string.Equals(currentTcsFlowMode, FlowModeParam.FlowModeEnum.Run.ToString(), StringComparison.OrdinalIgnoreCase) || string.Equals(currentTcsFlowMode, FlowModeParam.FlowModeEnum.Vent.ToString(), StringComparison.OrdinalIgnoreCase)) { tcsFlow = (currentTcsBubbleHighFlow + currentTcsBubbleLowFlow) * tcsEff + currentTcsPushFlow; } else if (string.Equals(currentTcsFlowMode, FlowModeParam.FlowModeEnum.Purge.ToString(), StringComparison.OrdinalIgnoreCase)) { tcsFlow = currentTcsBubbleHighFlow + currentTcsBubbleLowFlow + currentTcsPushFlow; } return tcsFlow; } protected virtual double GetTmaFlow(RecipeStep step, string selectedChamber) { var currentTmaBubbleFlow = ((DoubleParam)step.FindParamByControlName(NameTmaBubbleFlow)).Value; var currentTmaPushFlow = ((DoubleParam)step.FindParamByControlName(NameTmaPushFlow)).Value; var currentTmaFlowMode = ((ComboxParam)step.FindParamByControlName(NameTmaFlowMode)).Value; var tmaFlow = 0d; var tmaEff = (double)QueryDataClient.Instance.Service.GetConfig($"PM.{selectedChamber}.Efficiency.TMA-Eff"); if (string.Equals(currentTmaFlowMode, FlowModeParam.FlowModeEnum.Run.ToString(), StringComparison.OrdinalIgnoreCase) || string.Equals(currentTmaFlowMode, FlowModeParam.FlowModeEnum.Vent.ToString(), StringComparison.OrdinalIgnoreCase)) tmaFlow = currentTmaBubbleFlow * tmaEff + currentTmaPushFlow; else if (string.Equals(currentTmaFlowMode, FlowModeParam.FlowModeEnum.Purge.ToString(), StringComparison.OrdinalIgnoreCase)) tmaFlow = currentTmaBubbleFlow + currentTmaPushFlow; return tmaFlow; } protected virtual void CalSiSourceFlow(RecipeStep step) { var currentSiSourSplitRatio = new double[3]; if (step.FindParamByControlName(NameSiSourceSplitRatio) is Sets3RatioParam siSourceRatio) currentSiSourSplitRatio = siSourceRatio.Ratio; var currentSiSourTotalFlow = ((DoubleParam)step.FindParamByControlName(NameSiSourceTotalFlow)).Value; //double currentSiSourPushFlow = currentSiSourTotalFlow - (currentSiH4FlowMode == FlowMode.Run.ToString() ? currentSiH4Flow : 0) // - (currentTCSFlowMode == FlowMode.Run.ToString() ? TCSFlow : 0) - (currentHClFlowMode == FlowMode.Run.ToString() ? currentHClFlow : 0); //(currentStep[(int)RecipColNo.SiSourceOuterFlow] as DoubleParam).Value = currentSiSourPushFlow.ToString("F1"); double currentSiSourInnerFlow = 0; double currentSiSourMidFlow = 0; double currentSiSourOutFlow = 0; if (currentSiSourSplitRatio.Length == 3) { var rationSum = currentSiSourSplitRatio[0] + currentSiSourSplitRatio[1] + currentSiSourSplitRatio[2]; currentSiSourInnerFlow = currentSiSourTotalFlow / rationSum * currentSiSourSplitRatio[0]; currentSiSourMidFlow = currentSiSourTotalFlow / rationSum * currentSiSourSplitRatio[1]; currentSiSourOutFlow = currentSiSourTotalFlow / rationSum * currentSiSourSplitRatio[2]; } ((DoubleParam)step.FindParamByControlName(NameSiSourceInnerFlow)).Value = Math.Round(currentSiSourInnerFlow, 1); ((DoubleParam)step.FindParamByControlName(NameSiSourceMiddleFlow)).Value = Math.Round(currentSiSourMidFlow, 1); ((DoubleParam)step.FindParamByControlName(NameSiSourceOuterFlow)).Value = Math.Round(currentSiSourOutFlow, 1); } protected virtual void CalCSourceFlow(RecipeStep currentStep) { var currentC2H4Flow = ((DoubleParam)currentStep.FindParamByControlName(NameCxHxFlow)).Value; var currentCSourSplitRatio = new double[3]; if (currentStep.FindParamByControlName(NameCSourceSplitRatio) is Sets3RatioParam cSourceRatio) currentCSourSplitRatio = cSourceRatio.Ratio; var currentCSourTotalFlow = ((DoubleParam)currentStep.FindParamByControlName(NameCSourceTotalFlow)).Value; var currentC2H4FlowMode = (currentStep.FindParamByControlName(NameCxHxFlowMode) as ComboxParam)?.Value; var currentCSourPushFlow = currentCSourTotalFlow - (string.Equals(currentC2H4FlowMode, FlowModeParam.FlowModeEnum.Run.ToString(), StringComparison.OrdinalIgnoreCase) ? currentC2H4Flow : 0d); ((DoubleParam)currentStep.FindParamByControlName(NameCSourcePushFlow)).Value = Math.Round(currentCSourPushFlow, 1); double currentCSourInnerFlow = 0; double currentCSourMidFlow = 0; double currentCSourOuterFlow = 0; if (currentCSourSplitRatio.Length == 3) { var ratioSum = currentCSourSplitRatio[0] + currentCSourSplitRatio[1] + currentCSourSplitRatio[2]; currentCSourInnerFlow = currentCSourTotalFlow / ratioSum * currentCSourSplitRatio[0]; currentCSourMidFlow = currentCSourTotalFlow / ratioSum * currentCSourSplitRatio[1]; currentCSourOuterFlow = currentCSourTotalFlow / ratioSum * currentCSourSplitRatio[2]; } ((DoubleParam)currentStep.FindParamByControlName(NameCSourceInnerFlow)).Value = Math.Round(currentCSourInnerFlow, 1); ((DoubleParam)currentStep.FindParamByControlName(NameCSourceMiddleFlow)).Value = Math.Round(currentCSourMidFlow, 1); ((DoubleParam)currentStep.FindParamByControlName(NameCSourceOuterFlow)).Value = Math.Round(currentCSourOuterFlow, 1); } protected virtual void CalDopeFlow(RecipeStep currentStep) { var currentDopeTotalFlow = ((DoubleParam)currentStep.FindParamByControlName(NameDopeTotalFlow)).Value; var currentN2ActualFlow = ((DoubleParam)currentStep.FindParamByControlName(NameN2ActualFlow)).Value; var currentN2LowFlow = ((DoubleParam)currentStep.FindParamByControlName(NameN2LowFlow)).Value; var currentDiluFlowForN2 = ((DoubleParam)currentStep.FindParamByControlName(NameDilutionFlowForN2)).Value; var currentDilutedN2Flow = (currentN2LowFlow + currentDiluFlowForN2) * currentN2ActualFlow / currentN2LowFlow; ((DoubleParam)currentStep.FindParamByControlName(NameDilutedN2Flow)).Value = Math.Round(currentDilutedN2Flow, 1); var currentDopeSplitRatio = new double[3]; if (currentStep.FindParamByControlName(NameDopeSplitRatio) is Sets3RatioParam dopRatio) currentDopeSplitRatio = dopRatio.Ratio; //double currentDopePushFlow = currentDopeTotalFlow // - (currentN2FlowMode == FlowMode.Run.ToString() ? currentDilutedN2Flow : 0) // - (currentN2HighFlowMode == FlowMode.Run.ToString() ? currentN2HighFlow : 0) // - (currentTMAFlowMode == FlowMode.Run.ToString() ? TMAFlow : 0); //(currentStep[(int)RecipColNo.DopeOuterFlow] as DoubleParam).Value = currentDopePushFlow.ToString("F1"); double currentDopeInnerFlow = 0; double currentDopeMidFlow = 0; double currentDopeOuterFlow = 0; if (currentDopeSplitRatio.Length == 3) { var ratioSum = currentDopeSplitRatio[0] + currentDopeSplitRatio[1] + currentDopeSplitRatio[2]; currentDopeInnerFlow = currentDopeTotalFlow / ratioSum * currentDopeSplitRatio[0]; currentDopeMidFlow = currentDopeTotalFlow / ratioSum * currentDopeSplitRatio[1]; currentDopeOuterFlow = currentDopeTotalFlow / ratioSum * currentDopeSplitRatio[2]; } ((DoubleParam)currentStep.FindParamByControlName(NameDopeInnerFlow)).Value = Math.Round(currentDopeInnerFlow, 1); ((DoubleParam)currentStep.FindParamByControlName(NameDopeMiddleFlow)).Value = Math.Round(currentDopeMidFlow, 1); ((DoubleParam)currentStep.FindParamByControlName(NameDopeOuterFlow)).Value = Math.Round(currentDopeOuterFlow, 1); } protected virtual void CalShSupplementFlow(RecipeStep currentStep) { var currentSiSourTotalFlow = ((DoubleParam)currentStep.FindParamByControlName(NameSiSourceTotalFlow)).Value; var currentCSourTotalFlow = ((DoubleParam)currentStep.FindParamByControlName(NameCSourceTotalFlow)).Value; var currentDopeTotalFlow = ((DoubleParam)currentStep.FindParamByControlName(NameDopeTotalFlow)).Value; var currentShTotalFlow = ((DoubleParam)currentStep.FindParamByControlName(NameShTotalFlow)).Value; var currentSurroundingFlow = ((DoubleParam)currentStep.FindParamByControlName(NameCarryGasFlow)).Value; var currentSiSourInnerFlow = ((DoubleParam)currentStep.FindParamByControlName(NameSiSourceInnerFlow)).Value; var currentSiSourMidFlow = ((DoubleParam)currentStep.FindParamByControlName(NameSiSourceMiddleFlow)).Value; var currentCSourInnerFlow = ((DoubleParam)currentStep.FindParamByControlName(NameCSourceInnerFlow)).Value; var currentCSourMidFlow = ((DoubleParam)currentStep.FindParamByControlName(NameCSourceMiddleFlow)).Value; var currentDopeInnerFlow = ((DoubleParam)currentStep.FindParamByControlName(NameDopeInnerFlow)).Value; var currentDopeMidFlow = ((DoubleParam)currentStep.FindParamByControlName(NameDopeMiddleFlow)).Value; var currentShTotalFlowSplitRatio = new double[3]; if (currentStep.FindParamByControlName(NameShTotalFlowSplitRatio) is Sets3RatioParam shTotalRatio) currentShTotalFlowSplitRatio = shTotalRatio.Ratio; var currentShSuppTotalFlow = currentShTotalFlow - currentSurroundingFlow - currentSiSourTotalFlow - currentCSourTotalFlow - currentDopeTotalFlow; var sumShTotalFlowSplitRatio = currentShTotalFlowSplitRatio[0] + currentShTotalFlowSplitRatio[1] + currentShTotalFlowSplitRatio[2]; var currentShInnerFlow = (currentShTotalFlow - currentSurroundingFlow) / sumShTotalFlowSplitRatio * currentShTotalFlowSplitRatio[0]; var currentShMidFlow = (currentShTotalFlow - currentSurroundingFlow) / sumShTotalFlowSplitRatio * currentShTotalFlowSplitRatio[1]; var currentShOutterFlow = (currentShTotalFlow - currentSurroundingFlow) / sumShTotalFlowSplitRatio * currentShTotalFlowSplitRatio[2]; var currentInnerSuppFlow = currentShInnerFlow - currentSiSourInnerFlow - currentCSourInnerFlow - currentDopeInnerFlow; var currentMidSuppFlow = currentShMidFlow - currentSiSourMidFlow - currentCSourMidFlow - currentDopeMidFlow; var currentOutterSuppFlow = currentShSuppTotalFlow - currentInnerSuppFlow - currentMidSuppFlow; ((DoubleParam)currentStep.FindParamByControlName(NameShPushTotalFlow)).Value = Math.Round(currentShSuppTotalFlow, 1); ((DoubleParam)currentStep.FindParamByControlName(NameShInnerFlow)).Value = Math.Round(currentShInnerFlow, 1); ((DoubleParam)currentStep.FindParamByControlName(NameShMiddleFlow)).Value = Math.Round(currentShMidFlow, 1); ((DoubleParam)currentStep.FindParamByControlName(NameShOuterFlow)).Value = Math.Round(currentShOutterFlow, 1); ((DoubleParam)currentStep.FindParamByControlName(NameInnerPushFlow)).Value = Math.Round(currentInnerSuppFlow, 1); ((DoubleParam)currentStep.FindParamByControlName(NameMiddlePushFlow)).Value = Math.Round(currentMidSuppFlow, 1); ((DoubleParam)currentStep.FindParamByControlName(NameOuterPushFlow)).Value = Math.Round(currentOutterSuppFlow, 1); } protected virtual void CalVentFlow(RecipeStep currentStep, string selectedChamber) { var currentSiH4Flow = ((DoubleParam)currentStep.FindParamByControlName(NameSiH4Flow)).Value; var currentTotalVentFlow = ((DoubleParam)currentStep.FindParamByControlName(NameTotalVentFlow)).Value; var currentHClFlow = ((DoubleParam)currentStep.FindParamByControlName(NameHclFlow)).Value; var currentN2HighFlow = ((DoubleParam)currentStep.FindParamByControlName(NameN2HighFlow)).Value; var currentC2H4Flow = ((DoubleParam)currentStep.FindParamByControlName(NameCxHxFlow)).Value; var currentDilutedN2Flow = ((DoubleParam)currentStep.FindParamByControlName(NameDilutedN2Flow)).Value; var currentN2FlowMode = ((ComboxParam)currentStep.FindParamByControlName(NameN2FlowMode)).Value; var currentN2HighFlowMode = ((ComboxParam)currentStep.FindParamByControlName(NameN2HighFlowMode)).Value; var currentSiH4FlowMode = (currentStep.FindParamByControlName(NameSiH4FlowMode) as ComboxParam)?.Value; var currentTcsFlowMode = (currentStep.FindParamByControlName(NameTcsFlowMode) as ComboxParam)?.Value; var currentHClFlowMode = (currentStep.FindParamByControlName(NameHclFlowMode) as ComboxParam)?.Value; var currentC2H4FlowMode = (currentStep.FindParamByControlName(NameCxHxFlowMode) as ComboxParam)?.Value; var currentTmaFlowMode = ((ComboxParam)currentStep.FindParamByControlName(NameTmaFlowMode)).Value; var tcsFlow = GetTcsFlow(currentStep, selectedChamber); var tmaFlow = GetTmaFlow(currentStep, selectedChamber); var currentSiSourTotalFlowForPurge = (string.Equals(currentSiH4FlowMode, FlowModeParam.FlowModeEnum.Run.ToString(), StringComparison.OrdinalIgnoreCase) == false ? currentSiH4Flow : 0d) + (string.Equals(currentTcsFlowMode, FlowModeParam.FlowModeEnum.Run.ToString(), StringComparison.OrdinalIgnoreCase) == false ? tcsFlow : 0d) + (string.Equals(currentHClFlowMode, FlowModeParam.FlowModeEnum.Run.ToString(), StringComparison.OrdinalIgnoreCase) == false ? currentHClFlow : 0d); var currentCSourTotalFlowForPurge = string.Equals(currentC2H4FlowMode, FlowModeParam.FlowModeEnum.Run.ToString(), StringComparison.OrdinalIgnoreCase) == false ? currentC2H4Flow : 0d; var n2Flow = (string.Equals(currentN2FlowMode, FlowModeParam.FlowModeEnum.Run.ToString(), StringComparison.OrdinalIgnoreCase) == false ? currentDilutedN2Flow : 0d) + (string.Equals(currentN2HighFlowMode, FlowModeParam.FlowModeEnum.Run.ToString(), StringComparison.OrdinalIgnoreCase) == false ? currentN2HighFlow : 0d); var currentDopeTotalFlowForPurge = n2Flow + (string.Equals(currentTmaFlowMode, FlowModeParam.FlowModeEnum.Run.ToString(), StringComparison.OrdinalIgnoreCase) == false ? tmaFlow : 0d); var currentVentPushFlow = currentTotalVentFlow - currentSiSourTotalFlowForPurge - currentCSourTotalFlowForPurge - currentDopeTotalFlowForPurge; ((DoubleParam)currentStep.FindParamByControlName(NameVentPushFlow)).Value = Math.Round(currentVentPushFlow, 1); } #endregion } }