/// <summary> /// /// </summary> /// <param name="XOp"></param> /// <param name="CodName"></param> /// <param name="_D"></param> /// <param name="BcMap"></param> /// <param name="config"></param> /// <param name="LsTrk"></param> public static void AddInterfaceContinuityEq(XSpatialOperatorMk2 XOp, IXNSE_Configuration 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.ContinuityEquation; 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; // set components var comps = XOp.EquationComponents[CodName]; var divPen = new Operator.Continuity.DivergenceAtLevelSet(D, LsTrk, rhoA, rhoB, config.isMatInt, dntParams.ContiSign, dntParams.RescaleConti); comps.Add(divPen); //var stabint = new PressureStabilizationAtLevelSet(LsTrk, dntParams.PresPenalty2, physParams.reynolds_A, physParams.reynolds_B); //comps.Add(stabint); }
/// <summary> /// /// </summary> /// <param name="XOp"></param> /// <param name="config"></param> /// <param name="BcMap"></param> /// <param name="LsTrk"></param> public static void AddInterfaceNSE(XSpatialOperatorMk2 XOp, IXNSE_Configuration config, int D, IncompressibleMultiphaseBoundaryCondMap BcMap, LevelSetTracker LsTrk) { for (int d = 0; d < D; d++) { AddInterfaceNSE_component(XOp, config, d, D, BcMap, LsTrk); } }
/// <summary> /// /// </summary> /// <param name="XOp"></param> /// <param name="config"></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(XSpatialOperatorMk2 XOp, IXNSE_Configuration config, int D, IncompressibleMultiphaseBoundaryCondMap BcMap, LevelSetTracker LsTrk, int degU, out bool NormalsRequired, out bool CurvatureRequired) { NormalsRequired = false; CurvatureRequired = false; for (int d = 0; d < D; d++) { AddSurfaceTensionForce_component(XOp, config, d, D, BcMap, LsTrk, degU, out NormalsRequired, out CurvatureRequired); } }
/// <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> /// /// </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 AddInterfaceConstitutive_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; if (d == 0) { CodName = EquationNames.ConstitutiveXX; } else if (d == 1) { CodName = EquationNames.ConstitutiveXY; } else if (d == 2) { CodName = EquationNames.ConstitutiveYY; } else { throw new NotSupportedException("Invalid index (3D not supported), d is: " + 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; // set components var comps = XOp.EquationComponents[CodName]; // identity part // =================== var identity = new IdentityAtLevelSet(LsTrk, d); comps.Add(identity); // viscous operator // ================== var viscosity = new ViscosityAtLevelSet(LsTrk, d, physParams.beta_a, physParams.beta_b, dntParams.Penalty1); comps.Add(viscosity); }