Sic.Framework-Nanjing-Baishi/MECF.Framework.UI.Client/RecipeEditorLib/RecipeModel/RecipeGasFlowCalculatorBase.cs

377 lines
21 KiB
C#
Raw Normal View History

using MECF.Framework.Common.DataCenter;
using MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel.Params;
using System;
using MECF.Framework.Common.Equipment;
namespace MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel
{
/// <summary>
/// 配方步骤气体流量计算器基类。
/// <br/>
/// 同时,该类也作为默认计算器使用;如果构造<see cref="RecipeData"/>时没有指定
/// 计算器对象实例,则默认使用此计算器。
/// </summary>
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
/// <summary>
/// 计算指定工艺步骤的气体流量。
/// </summary>
/// <param name="step">工艺步骤对象。</param>
/// <param name="chamberName">
/// 当前配方步骤所属反应腔的名称,可用的名称请参考<see cref="ModuleName"/>。
/// <remarks>
/// 为什么需要传入反应腔名称?
/// <br/>
/// 计算Vent Flow时需要使用TCS、TMA的气体流量参数而上述两个流量的计算需要使用
/// 系统配置中PM.{chamberName}.Efficiency.TCS-Eff或TMA-Eff的配置值。因此计算
/// 配方气体流量时需要传入反应腔名称以获取这两个配置参数的数值。
/// </remarks>
/// </param>
public void Calculate(RecipeStep step, string chamberName)
{
CalSiSourceFlow(step);
CalCSourceFlow(step);
CalDopeFlow(step);
CalShSupplementFlow(step);
CalVentFlow(step, chamberName);
}
#region Gas Flow Calculation
protected virtual double GetTcsFlow(RecipeStep step, string chamberName)
{
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.{chamberName}.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 chamberName)
{
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.{chamberName}.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 chamberName)
{
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, chamberName);
var tmaFlow = GetTmaFlow(currentStep, chamberName);
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
}
}