/// <summary> /// /// </summary> /// <param name="XOp"></param> /// <param name="config"></param> /// <param name="D"></param> /// <param name="LsTrk"></param> public static void AddInterfaceHeatEq_withEvaporation(XSpatialOperatorMk2 XOp, XNSFE_OperatorConfiguration config, int D, LevelSetTracker LsTrk) { // check input if (XOp.IsCommited) { throw new InvalidOperationException("Spatial Operator is already comitted. Adding of new components is not allowed"); } string CodName = EquationNames.HeatEquation; if (!XOp.CodomainVar.Contains(CodName)) { throw new ArgumentException("CoDomain variable \"" + CodName + "\" is not defined in Spatial Operator"); } if (config.getConductMode != ConductivityInSpeciesBulk.ConductivityMode.SIP) { foreach (string cn in EquationNames.AuxHeatFlux(D)) { if (!XOp.CodomainVar.Contains(cn)) { throw new ArgumentException("CoDomain variable \"" + cn + "\" is not defined in Spatial Operator"); } } } PhysicalParameters physParams = config.getPhysParams; ThermalParameters thermParams = config.getThermParams; // set species arguments double rhoA = physParams.rho_A; double rhoB = physParams.rho_B; double sigma = physParams.Sigma; // compute further arguments double hVapA = thermParams.hVap_A; double hVapB = thermParams.hVap_B; double Tsat = thermParams.T_sat; double f = config.thermParams.fc; double R = config.thermParams.Rc; double rho_l = 0.0; double R_int = 0.0; if (config.thermParams.hVap_A > 0 && config.thermParams.hVap_B < 0) { rho_l = rhoA; R_int = ((2.0 - f) / (2 * f)) * Tsat * Math.Sqrt(2 * Math.PI * R * Tsat) / (rhoB * hVapA.Pow2()); //T_intMin = Tsat * (1 + (pc / (rhoA * hVapA.Pow2()))); } else if (config.thermParams.hVap_A < 0 && config.thermParams.hVap_B > 0) { rho_l = rhoB; R_int = ((2.0 - f) / (2 * f)) * Tsat * Math.Sqrt(2 * Math.PI * R * Tsat) / (rhoA * hVapB.Pow2()); //T_intMin = Tsat * (1 + (pc / (rhoB * hVapB.Pow2()))); } // set components var comps = XOp.EquationComponents[CodName]; // mass flux at interface // ====================== //if (!config.isSeparated) { // comps.Add(new HeatFluxAtLevelSet(LsTrk, rho_l, thermParams, R_int, sigma)); //} // convective part // ================ if (thermParams.IncludeConvection) { comps.Add(new HeatConvectionAtLevelSet_Divergence(D, LsTrk, rhoA, rhoB, thermParams, R_int, sigma)); } }
//============== // Heat equation //============== public static void AddSpeciesHeatEq(XSpatialOperatorMk2 XOp, IHeat_Configuration config, int D, string spcName, SpeciesId spcId, ThermalMultiphaseBoundaryCondMap BcMap, LevelSetTracker LsTrk) { // check input if (XOp.IsCommited) { throw new InvalidOperationException("Spatial Operator is already comitted. Adding of new components is not allowed"); } string CodName = EquationNames.HeatEquation; if (!XOp.CodomainVar.Contains(CodName)) { throw new ArgumentException("CoDomain variable \"" + CodName + "\" is not defined in Spatial Operator"); } if (config.getConductMode != ConductivityInSpeciesBulk.ConductivityMode.SIP) { foreach (string cn in EquationNames.AuxHeatFlux(D)) { if (!XOp.CodomainVar.Contains(cn)) { throw new ArgumentException("CoDomain variable \"" + cn + "\" is not defined in Spatial Operator"); } } } ThermalParameters thermParams = config.getThermParams; DoNotTouchParameters dntParams = config.getDntParams; // set species arguments double capSpc, LFFSpc, kSpc; switch (spcName) { case "A": { capSpc = thermParams.rho_A * thermParams.c_A; LFFSpc = dntParams.LFFA; kSpc = thermParams.k_A; break; } case "B": { capSpc = thermParams.rho_B * thermParams.c_B; LFFSpc = dntParams.LFFB; kSpc = thermParams.k_B; break; } default: throw new ArgumentException("Unknown species."); } // set components var comps = XOp.EquationComponents[CodName]; // convective part // ================ if (thermParams.IncludeConvection) { IEquationComponent conv; if (config.useUpwind) { conv = new HeatConvectionInSpeciesBulk_Upwind(D, BcMap, spcName, spcId, capSpc); } else { conv = new HeatConvectionInSpeciesBulk_LLF(D, BcMap, spcName, spcId, capSpc, LFFSpc, LsTrk); } comps.Add(conv); } // viscous operator (laplace) // ========================== if (config.getConductMode == ConductivityInSpeciesBulk.ConductivityMode.SIP) { double penalty = dntParams.PenaltySafety; var Visc = new ConductivityInSpeciesBulk( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, D, spcName, spcId, thermParams.k_A, thermParams.k_B); comps.Add(Visc); if (dntParams.UseGhostPenalties) { var ViscPenalty = new ConductivityInSpeciesBulk(penalty * 1.0, 0.0, BcMap, D, spcName, spcId, thermParams.k_A, thermParams.k_B); XOp.GhostEdgesOperator.EquationComponents[CodName].Add(ViscPenalty); } } else { comps.Add(new HeatFluxDivergenceInSpeciesBulk(D, BcMap, spcName, spcId)); //if (config.getConductMode == ConductivityInSpeciesBulk.ConductivityMode.LDGstabi) // comps.Add(new AuxiliaryStabilizationForm(D, BcMap, spcName, spcId)); for (int d = 0; d < D; d++) { comps = XOp.EquationComponents[EquationNames.AuxHeatFluxComponent(d)]; comps.Add(new AuxiliaryHeatFlux_Identity(d, spcName, spcId)); // cell local comps.Add(new TemperatureGradientInSpeciesBulk(D, d, BcMap, spcName, spcId, kSpc)); //if (config.getConductMode == ConductivityInSpeciesBulk.ConductivityMode.LDGstabi) // comps.Add(new TemperatureStabilizationForm(d, BcMap, spcName, spcId)); } } }
/// <summary> /// ctor for the operator factory, where the equation compnents are set /// </summary> /// <param name="_config"></param> /// <param name="_LsTrk"></param> /// <param name="_HMFdegree"></param> /// <param name="BcMap"></param> /// <param name="thermBcMap"></param> /// <param name="degU"></param> public XNSFE_OperatorFactory(XNSFE_OperatorConfiguration _config, LevelSetTracker _LsTrk, int _HMFdegree, IncompressibleMultiphaseBoundaryCondMap BcMap, ThermalMultiphaseBoundaryCondMap thermBcMap, int degU, IDictionary <SpeciesId, IEnumerable <double> > MassScale) { this.config = _config; this.LsTrk = _LsTrk; this.D = _LsTrk.GridDat.SpatialDimension; this.HMFDegree = _HMFdegree; this.physParams = config.getPhysParams; this.thermParams = config.getThermParams; this.dntParams = config.getDntParams; // test input // ========== { if ((config.getPhysParams.mu_A <= 0) && (config.getPhysParams.mu_B <= 0)) { config.isViscous = false; } else { if ((config.getPhysParams.mu_A <= 0) || (config.getPhysParams.mu_B <= 0)) { throw new ArgumentException(); } } if ((config.getPhysParams.rho_A <= 0) || (config.getPhysParams.rho_B <= 0)) { throw new ArgumentException(); } if (_LsTrk.SpeciesNames.Count != 2) { throw new ArgumentException(); } if (!(_LsTrk.SpeciesNames.Contains("A") && _LsTrk.SpeciesNames.Contains("B"))) { throw new ArgumentException(); } } // full operator: // ============== CodName = ArrayTools.Cat(EquationNames.MomentumEquations(D), EquationNames.ContinuityEquation); Params = ArrayTools.Cat( VariableNames.Velocity0Vector(D), VariableNames.Velocity0MeanVector(D), VariableNames.NormalVector(D), VariableNames.Curvature, VariableNames.SurfaceForceVector(D) ); DomName = ArrayTools.Cat(VariableNames.VelocityVector(D), VariableNames.Pressure); if (config.solveEnergy) { CodName = ArrayTools.Cat(CodName, EquationNames.KineticEnergyEquation); Params = ArrayTools.Cat(Params, VariableNames.VelocityX_GradientVector(), VariableNames.VelocityY_GradientVector(), new string[] { "VelocityXGradX_GradientX", "VelocityXGradX_GradientY" }, new string[] { "VelocityXGradY_GradientX", "VelocityXGradY_GradientY" }, new string[] { "VelocityYGradX_GradientX", "VelocityYGradX_GradientY" }, new string[] { "VelocityYGradY_GradientX", "VelocityYGradY_GradientY" }, VariableNames.Pressure0, VariableNames.PressureGradient(D), VariableNames.GravityVector(D) ); DomName = ArrayTools.Cat(DomName, VariableNames.KineticEnergy); } if (config.solveHeat) { Params = ArrayTools.Cat(Params, VariableNames.Temperature0, VariableNames.HeatFlux0Vector(D), VariableNames.DisjoiningPressure ); if (config.conductMode == ConductivityInSpeciesBulk.ConductivityMode.SIP) { CodName = ArrayTools.Cat(CodName, EquationNames.HeatEquation); DomName = ArrayTools.Cat(DomName, VariableNames.Temperature); } else { CodName = ArrayTools.Cat(CodName, EquationNames.HeatEquation, EquationNames.AuxHeatFlux(D)); DomName = ArrayTools.Cat(DomName, VariableNames.Temperature, VariableNames.HeatFluxVector(D)); } } storedParams = new DGField[Params.Length]; // selected part: if (config.getCodBlocks[0]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(0, D)); } if (config.getCodBlocks[1]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(D, 1)); } if (config.getDomBlocks[0]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(0, D)); } if (config.getDomBlocks[1]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(D, 1)); } int nBlocks = 2; if (config.solveEnergy) { nBlocks = 3; if (config.getCodBlocks[2]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(D + 1, 1)); } if (config.getDomBlocks[2]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(D + 1, 1)); } } if (config.solveHeat) { if (config.getCodBlocks[nBlocks]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(nBlocks + (D - 1) + 1, 1)); } if (config.getDomBlocks[nBlocks]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(nBlocks + (D - 1) + 1, 1)); } if (config.conductMode != ConductivityInSpeciesBulk.ConductivityMode.SIP) { if (config.getCodBlocks[nBlocks + 1]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(nBlocks + (D - 1) + 2, D)); } if (config.getDomBlocks[nBlocks + 1]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(nBlocks + (D - 1) + 2, D)); } } } // create Operator // =============== m_XOp = new XSpatialOperatorMk2(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree, this.LsTrk.SpeciesNames); // add Navier-Stokes components // ============================ // species bulk components for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { // Navier Stokes equations Solution.XNSECommon.XOperatorComponentsFactory.AddSpeciesNSE(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired); // continuity equation if (config.isContinuity) { Solution.XNSECommon.XOperatorComponentsFactory.AddSpeciesContinuityEq(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap); } } // interface components Solution.XNSECommon.XOperatorComponentsFactory.AddInterfaceNSE(m_XOp, config, D, BcMap, LsTrk); // surface stress tensor Solution.XNSECommon.XOperatorComponentsFactory.AddSurfaceTensionForce(m_XOp, config, D, BcMap, LsTrk, degU, out NormalsRequired, out CurvatureRequired); // surface tension force if (config.isContinuity) { Solution.XNSECommon.XOperatorComponentsFactory.AddInterfaceContinuityEq(m_XOp, config, D, LsTrk); // continuity equation } // add kinetic energy equation components // ====================================== if (config.solveEnergy) { // species bulk components for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { Solution.EnergyCommon.XOperatorComponentsFactory.AddSpeciesKineticEnergyEquation(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk); } // interface components Solution.EnergyCommon.XOperatorComponentsFactory.AddInterfaceKineticEnergyEquation(m_XOp, config, D, BcMap, LsTrk, degU); CurvatureRequired = true; } // add Heat equation components // ============================ if (config.solveHeat) { // species bulk components for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { Solution.XheatCommon.XOperatorComponentsFactory.AddSpeciesHeatEq(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], thermBcMap, LsTrk); } // interface components Solution.XheatCommon.XOperatorComponentsFactory.AddInterfaceHeatEq(m_XOp, config, D, thermBcMap, LsTrk); } // add Evaporation interface components // ==================================== if (config.isEvaporation) { XOperatorComponentsFactory.AddInterfaceNSE_withEvaporation(m_XOp, config, D, LsTrk); if (config.isContinuity) { XOperatorComponentsFactory.AddInterfaceContinuityEq_withEvaporation(m_XOp, config, D, LsTrk); } } // create temporal operator // ======================== var TempOp = new ConstantXTemporalOperator(m_XOp, 0.0); m_XOp.TemporalOperator = TempOp; foreach (var kv in MassScale) { TempOp.DiagonalScale[LsTrk.GetSpeciesName(kv.Key)].SetV(kv.Value.ToArray()); } // Finalize // ======== m_XOp.Commit(); }
public static void AddInterfaceHeatEq(XSpatialOperatorMk2 XOp, IXHeat_Configuration config, int D, ThermalMultiphaseBoundaryCondMap BcMap, LevelSetTracker LsTrk) { // check input if (XOp.IsCommited) { throw new InvalidOperationException("Spatial Operator is already comitted. Adding of new components is not allowed"); } string CodName = EquationNames.HeatEquation; if (!XOp.CodomainVar.Contains(CodName)) { throw new ArgumentException("CoDomain variable \"" + CodName + "\" is not defined in Spatial Operator"); } if (config.getConductMode != ConductivityInSpeciesBulk.ConductivityMode.SIP) { foreach (string cn in EquationNames.AuxHeatFlux(D)) { if (!XOp.CodomainVar.Contains(cn)) { throw new ArgumentException("CoDomain variable \"" + cn + "\" is not defined in Spatial Operator"); } } } ThermalParameters thermParams = config.getThermParams; DoNotTouchParameters dntParams = config.getDntParams; // set species arguments double capA = thermParams.rho_A * thermParams.c_A; double LFFA = dntParams.LFFA; double kA = thermParams.k_A; double capB = thermParams.rho_B * thermParams.c_B; double LFFB = dntParams.LFFB; double kB = thermParams.k_B; double Tsat = thermParams.T_sat; // set components var comps = XOp.EquationComponents[CodName]; // convective part // ================ if (thermParams.IncludeConvection) { ILevelSetForm conv; conv = new HeatConvectionAtLevelSet_LLF(D, LsTrk, capA, capB, LFFA, LFFB, BcMap, config.isMovingMesh, Tsat); //conv = new HeatConvectionAtLevelSet_WithEvaporation(D, LsTrk, LFFA, LFFB, thermParams, config.getPhysParams.Sigma); //conv = new HeatConvectionAtLevelSet_Upwind(D, LsTrk, capA, capB, thermParams, config.isMovingMesh, config.isEvaporation, Tsat); comps.Add(conv); } // viscous operator (laplace) // ========================== if (config.getConductMode == ConductivityInSpeciesBulk.ConductivityMode.SIP) { double penalty = dntParams.PenaltySafety; var Visc = new ConductivityAtLevelSet(LsTrk, kA, kB, penalty * 1.0, Tsat); comps.Add(Visc); var qJump = new HeatFluxAtLevelSet(D, LsTrk, thermParams, config.getPhysParams.Sigma); comps.Add(qJump); } else { comps.Add(new HeatFluxDivergencetAtLevelSet(LsTrk)); //if(config.getConductMode == ConductivityInSpeciesBulk.ConductivityMode.LDGstabi) // comps.Add(new AuxiliaryStabilizationFormAtLevelSet(LsTrk, config.isEvaporation)); for (int d = 0; d < D; d++) { comps = XOp.EquationComponents[EquationNames.AuxHeatFluxComponent(d)]; comps.Add(new TemperatureGradientAtLevelSet(d, LsTrk, kA, kB, Tsat)); //if (config.getConductMode == ConductivityInSpeciesBulk.ConductivityMode.LDGstabi) // comps.Add(new TemperatureStabilizationFormAtLevelSet(d, LsTrk, kA, kB, config.isEvaporation, Tsat)); } } }