//============================================================== // additional interface components for NSFE interface components //============================================================== /// <summary> /// /// </summary> /// <param name="XOp"></param> /// <param name="config"></param> /// <param name="d"></param> /// <param name="D"></param> /// <param name="LsTrk"></param> public static void AddInterfaceNSE_withEvaporation_component(XSpatialOperatorMk2 XOp, XNSFE_OperatorConfiguration config, int d, 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.MomentumEquationComponent(d); if (!XOp.CodomainVar.Contains(CodName)) { throw new ArgumentException("CoDomain variable \"" + CodName + "\" is not defined in Spatial Operator"); } PhysicalParameters physParams = config.getPhysParams; ThermalParameters thermParams = config.getThermParams; DoNotTouchParameters dntParams = config.getDntParams; double sigma = physParams.Sigma; // set components var comps = XOp.EquationComponents[CodName]; if (config.isTransport) { comps.Add(new ConvectionAtLevelSet_nonMaterialLLF(d, D, LsTrk, thermParams, sigma)); comps.Add(new ConvectionAtLevelSet_Consistency(d, D, LsTrk, dntParams.ContiSign, dntParams.RescaleConti, thermParams, sigma)); } if (config.isMovingMesh) { comps.Add(new ConvectionAtLevelSet_MovingMesh(d, D, LsTrk, thermParams, sigma)); } if (config.isViscous) { comps.Add(new ViscosityAtLevelSet_FullySymmetric_withEvap(LsTrk, physParams.mu_A, physParams.mu_B, dntParams.PenaltySafety, d, thermParams, sigma)); } comps.Add(new MassFluxAtInterface(d, D, LsTrk, thermParams, sigma)); }
//============================================================== // additional interface components for NSFE interface components //============================================================== /// <summary> /// /// </summary> /// <param name="XOp"></param> /// <param name="config"></param> /// <param name="d"></param> /// <param name="D"></param> /// <param name="LsTrk"></param> public static void AddInterfaceNSE_withEvaporation_component(XSpatialOperatorMk2 XOp, XNSFE_OperatorConfiguration config, int d, 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.MomentumEquationComponent(d); if (!XOp.CodomainVar.Contains(CodName)) { throw new ArgumentException("CoDomain variable \"" + CodName + "\" is not defined in Spatial Operator"); } PhysicalParameters physParams = config.getPhysParams; ThermalParameters thermParams = config.getThermParams; DoNotTouchParameters dntParams = config.getDntParams; // set species arguments double rhoA = physParams.rho_A; double rhoB = physParams.rho_B; double muA = physParams.mu_A; double muB = physParams.mu_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 R_int = 0.0; if (config.thermParams.hVap_A > 0 && config.thermParams.hVap_B < 0) { 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) { 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()))); } //double prescrbM = config.prescribedMassflux; // set components var comps = XOp.EquationComponents[CodName]; if (config.isTransport) { comps.Add(new ConvectionAtLevelSet_nonMaterialLLF(d, D, LsTrk, rhoA, rhoB, thermParams, R_int, sigma)); comps.Add(new ConvectionAtLevelSet_Consistency(d, D, LsTrk, rhoA, rhoB, dntParams.ContiSign, dntParams.RescaleConti, thermParams, R_int, sigma)); } //if (config.isPInterfaceSet) { // comps.Add(new GeneralizedPressureFormAtLevelSet(d, LsTrk, thermParams.p_sat, thermParams.hVap_A)); //} if (config.isViscous) { comps.Add(new ViscosityAtLevelSet_FullySymmetric_withEvap(LsTrk, muA, muB, dntParams.PenaltySafety, d, rhoA, rhoB, thermParams, R_int, sigma)); } comps.Add(new MassFluxAtInterface(d, D, LsTrk, rhoA, rhoB, thermParams, R_int, sigma)); }
/// <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)); } }
//======================= // Navier Stokes equation //======================= #region nse /// <summary> /// /// </summary> /// <param name="XOp"></param> /// <param name="d"></param> /// <param name="D"></param> /// <param name="spcName"></param> /// <param name="spcId"></param> /// <param name="BcMap"></param> /// <param name="config"></param> /// <param name="LsTrk"></param> /// <param name="U0meanrequired"></param> public static void AddSpeciesNSE_component(XSpatialOperatorMk2 XOp, INSE_Configuration config, int d, int D, string spcName, SpeciesId spcId, IncompressibleMultiphaseBoundaryCondMap BcMap, LevelSetTracker LsTrk, out bool U0meanrequired) { // check input if (XOp.IsCommited) { throw new InvalidOperationException("Spatial Operator is already committed. Adding of new components is not allowed"); } string CodName = EquationNames.MomentumEquationComponent(d); if (!XOp.CodomainVar.Contains(CodName)) { throw new ArgumentException("CoDomain variable \"" + CodName + "\" is not defined in Spatial Operator"); } PhysicalParameters physParams = config.getPhysParams; DoNotTouchParameters dntParams = config.getDntParams; // set species arguments double rhoSpc, LFFSpc, muSpc; switch (spcName) { case "A": { rhoSpc = physParams.rho_A; LFFSpc = dntParams.LFFA; muSpc = physParams.mu_A; break; } case "B": { rhoSpc = physParams.rho_B; LFFSpc = dntParams.LFFB; muSpc = physParams.mu_B; break; } default: throw new ArgumentException("Unknown species."); } // set components var comps = XOp.EquationComponents[CodName]; // convective operator // =================== U0meanrequired = false; if (physParams.IncludeConvection && config.isTransport) { var conv = new Operator.Convection.ConvectionInSpeciesBulk_LLF(D, BcMap, spcName, spcId, d, rhoSpc, LFFSpc, LsTrk); comps.Add(conv); U0meanrequired = true; } // pressure gradient // ================= if (config.isPressureGradient) { var pres = new Operator.Pressure.PressureInSpeciesBulk(d, BcMap, spcName, spcId); comps.Add(pres); //problably necessary for LDG Simulation. Only one species parameter reynoldsA!!!!!! //var presStab = new PressureStabilizationInBulk(dntParams.PresPenalty2, physParams.reynolds_A, spcName, spcId); //comps.Add(presStab); } // viscous operator // ================ if (config.isViscous && !(muSpc == 0.0)) { double penalty = dntParams.PenaltySafety; switch (dntParams.ViscosityMode) { case ViscosityMode.Standard: case ViscosityMode.TransposeTermMissing: { // Bulk operator: var Visc1 = new Operator.Viscosity.ViscosityInSpeciesBulk_GradUTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, spcName, spcId, d, D, physParams.mu_A, physParams.mu_B); comps.Add(Visc1); if (dntParams.UseGhostPenalties) { var Visc1Penalty = new Operator.Viscosity.ViscosityInSpeciesBulk_GradUTerm( penalty, 0.0, BcMap, spcName, spcId, d, D, physParams.mu_A, physParams.mu_B); XOp.GhostEdgesOperator.EquationComponents[CodName].Add(Visc1Penalty); } break; } case ViscosityMode.FullySymmetric: { // Bulk operator var Visc1 = new Operator.Viscosity.ViscosityInSpeciesBulk_GradUTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, spcName, spcId, d, D, physParams.mu_A, physParams.mu_B); comps.Add(Visc1); var Visc2 = new Operator.Viscosity.ViscosityInSpeciesBulk_GradUtranspTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, spcName, spcId, d, D, physParams.mu_A, physParams.mu_B); comps.Add(Visc2); if (dntParams.UseGhostPenalties) { var Visc1Penalty = new Operator.Viscosity.ViscosityInSpeciesBulk_GradUTerm( penalty, 0.0, BcMap, spcName, spcId, d, D, physParams.mu_A, physParams.mu_B); var Visc2Penalty = new Operator.Viscosity.ViscosityInSpeciesBulk_GradUtranspTerm( penalty, 0.0, BcMap, spcName, spcId, d, D, physParams.mu_A, physParams.mu_B); XOp.GhostEdgesOperator.EquationComponents[CodName].Add(Visc1Penalty); XOp.GhostEdgesOperator.EquationComponents[CodName].Add(Visc2Penalty); } break; } case ViscosityMode.Viscoelastic: { //set species arguments double ReSpc, betaSpc; switch (spcName) { case "A": { ReSpc = physParams.reynolds_A; betaSpc = physParams.beta_a; break; } case "B": { ReSpc = physParams.reynolds_B; betaSpc = physParams.beta_b; break; } default: throw new ArgumentException("Unknown species."); } // Bulk operator: var Visc1 = new Operator.Viscosity.DimensionlessViscosityInSpeciesBulk_GradUTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, spcName, spcId, d, D, physParams.reynolds_A / physParams.beta_a, physParams.reynolds_B / physParams.beta_b); comps.Add(Visc1); var Visc2 = new Operator.Viscosity.DimensionlessViscosityInSpeciesBulk_GradUtranspTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, spcName, spcId, d, D, physParams.reynolds_A / physParams.beta_a, physParams.reynolds_B / physParams.beta_b); comps.Add(Visc2); var div = new StressDivergenceInBulk(d, BcMap, ReSpc, dntParams.Penalty1, dntParams.Penalty2, spcName, spcId); comps.Add(div); break; } default: throw new NotImplementedException(); } } }
/// <summary> /// /// </summary> /// <param name="XOp"></param> /// <param name="config"></param> /// <param name="d"></param> /// <param name="D"></param> /// <param name="BcMap"></param> /// <param name="LsTrk"></param> /// <param name="degU"></param> /// <param name="NormalsRequired"></param> /// <param name="CurvatureRequired"></param> public static void AddSurfaceTensionForce_component(XSpatialOperatorMk2 XOp, IXNSE_Configuration config, int d, int D, IncompressibleMultiphaseBoundaryCondMap BcMap, LevelSetTracker LsTrk, int degU, out bool NormalsRequired, out bool CurvatureRequired) { // check input if (XOp.IsCommited) { throw new InvalidOperationException("Spatial Operator is already comitted. Adding of new components is not allowed"); } string CodName = EquationNames.MomentumEquationComponent(d); if (!XOp.CodomainVar.Contains(CodName)) { throw new ArgumentException("CoDomain variable \"" + CodName + "\" is not defined in Spatial Operator"); } PhysicalParameters physParams = config.getPhysParams; DoNotTouchParameters dntParams = config.getDntParams; // set arguments double sigma = physParams.Sigma; // set components //var comps = XOp.SurfaceElementOperator.EquationComponents[CodName]; // surface stress tensor // ===================== NormalsRequired = false; CurvatureRequired = false; if (config.isPressureGradient && physParams.Sigma != 0.0) { // isotropic part of the surface stress tensor // =========================================== if (dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Flux || dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Local || dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine) { if (dntParams.SST_isotropicMode != SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine) { IEquationComponent G = new SurfaceTension_LaplaceBeltrami_Surface(d, sigma * 0.5); XOp.SurfaceElementOperator.EquationComponents[CodName].Add(G); IEquationComponent H = new SurfaceTension_LaplaceBeltrami_BndLine(d, sigma * 0.5, dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Flux); XOp.SurfaceElementOperator.EquationComponents[CodName].Add(H); } else { IEquationComponent isoSurfT = new IsotropicSurfaceTension_LaplaceBeltrami(d, D, sigma * 0.5, BcMap.EdgeTag2Type, BcMap, physParams.theta_e, physParams.betaL); XOp.SurfaceElementOperator.EquationComponents[CodName].Add(isoSurfT); } NormalsRequired = true; } else if (dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Projected || dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_ClosestPoint || dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_LaplaceBeltramiMean || dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Fourier) { XOp.EquationComponents[CodName].Add(new CurvatureBasedSurfaceTension(d, D, LsTrk, sigma)); CurvatureRequired = true; } else { throw new NotImplementedException("Not implemented."); } // dynamic part of the surface stress tensor // ========================================= if (dntParams.SurfStressTensor != SurfaceSressTensor.Isotropic) { double muI = physParams.mu_I; double lamI = physParams.lambda_I; double lamI_t = (physParams.lambdaI_tilde < 0) ? (lamI - muI) : physParams.lambdaI_tilde; double penalty_base = (degU + 1) * (degU + D) / D; double penalty = penalty_base * dntParams.PenaltySafety; // surface dilatational viscosity if (dntParams.SurfStressTensor == SurfaceSressTensor.SurfaceDivergence || dntParams.SurfStressTensor == SurfaceSressTensor.FullBoussinesqScriven) { var surfDiv = new BoussinesqScriven_SurfaceVelocityDivergence(d, D, lamI_t * 0.5, penalty, BcMap.EdgeTag2Type, true); XOp.SurfaceElementOperator.EquationComponents[CodName].Add(surfDiv); } // surface shear viscosity if (dntParams.SurfStressTensor == SurfaceSressTensor.SurfaceRateOfDeformation || dntParams.SurfStressTensor == SurfaceSressTensor.SemiImplicit || dntParams.SurfStressTensor == SurfaceSressTensor.FullBoussinesqScriven) { var surfDeformRate = new BoussinesqScriven_SurfaceDeformationRate_GradU(d, D, muI * 0.5, penalty, true, dntParams.SurfStressTensor == SurfaceSressTensor.SemiImplicit); XOp.SurfaceElementOperator.EquationComponents[CodName].Add(surfDeformRate); if (dntParams.SurfStressTensor != SurfaceSressTensor.SemiImplicit) { var surfDeformRateT = new BoussinesqScriven_SurfaceDeformationRate_GradUTranspose(d, D, muI * 0.5, penalty, true); XOp.SurfaceElementOperator.EquationComponents[CodName].Add(surfDeformRateT); } } } // stabilization // ============= if (dntParams.UseLevelSetStabilization) { XOp.EquationComponents[CodName].Add(new LevelSetStabilization(d, D, LsTrk)); } } // artificial surface tension force // ================================ if (config.isPressureGradient && physParams.useArtificialSurfaceForce) { XOp.EquationComponents[CodName].Add(new SurfaceTension_ArfForceSrc(d, D, LsTrk)); } }
/// <summary> /// /// </summary> /// <param name="XOp"></param> /// <param name="config"></param> /// <param name="d"></param> /// <param name="D"></param> /// <param name="BcMap"></param> /// <param name="LsTrk"></param> public static void AddInterfaceNSE_component(XSpatialOperatorMk2 XOp, IXNSE_Configuration config, int d, int D, IncompressibleMultiphaseBoundaryCondMap 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.MomentumEquationComponent(d); if (!XOp.CodomainVar.Contains(CodName)) { throw new ArgumentException("CoDomain variable \"" + CodName + "\" is not defined in Spatial Operator"); } PhysicalParameters physParams = config.getPhysParams; DoNotTouchParameters dntParams = config.getDntParams; // set species arguments double rhoA = physParams.rho_A; double rhoB = physParams.rho_B; double LFFA = dntParams.LFFA; double LFFB = dntParams.LFFB; double muA = physParams.mu_A; double muB = physParams.mu_B; //viscoelastic double reynoldsA = physParams.reynolds_A; double reynoldsB = physParams.reynolds_B; double betaA = physParams.beta_a; double betaB = physParams.beta_b; double[] penalty1 = dntParams.Penalty1; double penalty2 = dntParams.Penalty2; // set components var comps = XOp.EquationComponents[CodName]; // convective operator // =================== if (physParams.IncludeConvection && config.isTransport) { var conv = new Operator.Convection.ConvectionAtLevelSet_LLF(d, D, LsTrk, rhoA, rhoB, LFFA, LFFB, physParams.Material, BcMap, config.isMovingMesh); comps.Add(conv); } // pressure gradient // ================= if (config.isPressureGradient) { var presLs = new Operator.Pressure.PressureFormAtLevelSet(d, D, LsTrk); comps.Add(presLs); } // viscous operator // ================ if (config.isViscous && (!(muA == 0.0) && !(muB == 0.0))) { double penalty = dntParams.PenaltySafety; switch (dntParams.ViscosityMode) { case ViscosityMode.Standard: comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, muA, muB, penalty * 1.0, d, true)); break; case ViscosityMode.TransposeTermMissing: comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, muA, muB, penalty * 1.0, d, false)); break; case ViscosityMode.FullySymmetric: comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_FullySymmetric(LsTrk, muA, muB, penalty, d, dntParams.UseWeightedAverages)); break; case ViscosityMode.Viscoelastic: //comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, 1 / reynoldsA, 1 / reynoldsB, penalty * 1.0, d, false)); comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_FullySymmetric(LsTrk, betaA / reynoldsA, betaB / reynoldsB, penalty, d, dntParams.UseWeightedAverages)); comps.Add(new Operator.Viscosity.StressDivergenceAtLevelSet(LsTrk, reynoldsA, reynoldsB, penalty1, penalty2, d, dntParams.UseWeightedAverages)); break; default: throw new NotImplementedException(); } } }
/// <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="degU"></param> public XNSE_OperatorFactory(IXNSE_Configuration config, LevelSetTracker _LsTrk, int _HMFdegree, IncompressibleMultiphaseBoundaryCondMap BcMap, int degU) { this.LsTrk = _LsTrk; this.D = _LsTrk.GridDat.SpatialDimension; this.HMFDegree = _HMFdegree; this.physParams = config.getPhysParams; this.dntParams = config.getDntParams; // test input // ========== { if (config.getDomBlocks.GetLength(0) != 2 || config.getCodBlocks.GetLength(0) != 2) { throw new ArgumentException(); } 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); // 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)); } // create Operator // =============== m_XOp = new XSpatialOperatorMk2(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree, this.LsTrk.SpeciesIdS.ToArray()); // add components // ============== // species bulk components for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { // Navier Stokes equations XOperatorComponentsFactory.AddSpeciesNSE(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired); // continuity equation if (config.isContinuity) { XOperatorComponentsFactory.AddSpeciesContinuityEq(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap); } } // interface components XOperatorComponentsFactory.AddInterfaceNSE(m_XOp, config, D, BcMap, LsTrk); // surface stress tensor XOperatorComponentsFactory.AddSurfaceTensionForce(m_XOp, config, D, BcMap, LsTrk, degU, out NormalsRequired, out CurvatureRequired); // surface tension force if (config.isContinuity) { XOperatorComponentsFactory.AddInterfaceContinuityEq(m_XOp, config, D, LsTrk); // continuity equation } m_XOp.Commit(); }
/// <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(); }
//============== // 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)); } } }
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)); } } }
/// <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="degU"></param> public XRheology_OperatorFactory(XRheology_OperatorConfiguration config, LevelSetTracker _LsTrk, int _HMFdegree, IncompressibleMultiphaseBoundaryCondMap BcMap, int _stressDegree, int degU) { this.LsTrk = _LsTrk; this.D = _LsTrk.GridDat.SpatialDimension; this.HMFDegree = _HMFdegree; this.physParams = config.getPhysParams; this.dntParams = config.getDntParams; this.useJacobianForOperatorMatrix = config.isUseJacobian; this.useArtificialDiffusion = config.isUseArtificialDiffusion; // test input // ========== { if (config.getDomBlocks.GetLength(0) != 3 || config.getCodBlocks.GetLength(0) != 3) { throw new ArgumentException(); } //if ((config.getPhysParams.Weissenberg_a <= 0) && (config.getPhysParams.Weissenberg_a <= 0)) { // config.isOldroydB = false; //} else { // if ((config.getPhysParams.mu_A <= 0) || (config.getPhysParams.mu_B <= 0)) // throw new ArgumentException(); //} //if ((config.getPhysParams.reynolds_A <= 0) && (config.getPhysParams.reynolds_B <= 0)) { // config.isViscous = false; //} else { // if ((config.getPhysParams.reynolds_A <= 0) || (config.getPhysParams.reynolds_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(this.D), EquationNames.ContinuityEquation, EquationNames.Constitutive(this.D)); Params = ArrayTools.Cat( VariableNames.Velocity0Vector(this.D), VariableNames.Velocity0MeanVector(this.D), VariableNames.VelocityX_GradientVector(), VariableNames.VelocityY_GradientVector(), VariableNames.StressXXP, VariableNames.StressXYP, VariableNames.StressYYP, // "artificialViscosity", VariableNames.NormalVector(this.D), VariableNames.Curvature, VariableNames.SurfaceForceVector(this.D) ); DomName = ArrayTools.Cat(VariableNames.VelocityVector(this.D), VariableNames.Pressure, VariableNames.StressXX, VariableNames.StressXY, VariableNames.StressYY); // selected part: if (config.getCodBlocks[0]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(0, this.D)); } if (config.getCodBlocks[1]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(this.D, 1)); } if (config.getCodBlocks[2]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(this.D + 1, 3)); } if (config.getDomBlocks[0]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(0, this.D)); } if (config.getDomBlocks[1]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(this.D, 1)); } if (config.getDomBlocks[2]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(this.D + 1, 3)); } // create Operator // =============== m_XOp = new XSpatialOperatorMk2(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree, this.LsTrk.SpeciesIdS.ToArray()); // add components // ============================ // species bulk components for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { // Navier Stokes equations XOperatorComponentsFactory.AddSpeciesNSE(m_XOp, config, this.D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired); // continuity equation if (config.isContinuity) { XOperatorComponentsFactory.AddSpeciesContinuityEq(m_XOp, config, this.D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap); } // constitutive equation XConstitutiveOperatorComponentsFactory.AddSpeciesConstitutive(m_XOp, config, this.D, stressDegree, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired); } // interface components XOperatorComponentsFactory.AddInterfaceNSE(m_XOp, config, this.D, BcMap, LsTrk); // surface stress tensor XOperatorComponentsFactory.AddSurfaceTensionForce(m_XOp, config, this.D, BcMap, LsTrk, degU, out NormalsRequired, out CurvatureRequired); // surface tension force XConstitutiveOperatorComponentsFactory.AddInterfaceConstitutive(m_XOp, config, this.D, BcMap, LsTrk); //viscosity of stresses at constitutive if (config.isContinuity) { XOperatorComponentsFactory.AddInterfaceContinuityEq(m_XOp, config, this.D, LsTrk); // continuity equation } m_XOp.Commit(); }