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

377 lines
21 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 => "Mfc8.Ramp";
public virtual string NameTmaFlowMode => "TMA.SetValve";
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
}
}