//XdgBDFTimestepping AltTimeIntegration; protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { int quadorder = this.u.Basis.Degree * 2 + 1; Op = new XSpatialOperatorMk2(1, 0, 1, (A, B, C) => quadorder, LsTrk.SpeciesNames, "u", "c1"); var blkFlux = new DxFlux(this.LsTrk, alpha_A, alpha_B); Op.EquationComponents["c1"].Add(blkFlux); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new LevSetFlx(this.LsTrk, alpha_A, alpha_B)); // flux am lev-set 0 Op.LinearizationHint = LinearizationHint.AdHoc; Op.TemporalOperator = new ConstantXTemporalOperator(Op, 1.0); Op.Commit(); if (L == null) { /* * AltTimeIntegration = new XdgBDFTimestepping( * new DGField[] { u }, new DGField[0], new DGField[] { uResidual }, base.LsTrk, * true, * DelComputeOperatorMatrix, Op.TemporalOperator, DelUpdateLevelset, * 3, // BDF3 * //-1, // Crank-Nicolson * //0, // Explicit Euler * LevelSetHandling.LieSplitting, * MassMatrixShapeandDependence.IsTimeDependent, * SpatialOperatorType.LinearTimeDependent, * MultigridOperatorConfig, * this.MultigridSequence, * this.LsTrk.SpeciesIdS.ToArray(), * quadorder, * this.THRESHOLD, * true, * this.Control.NonLinearSolver, * this.Control.LinearSolver); */ TimeIntegration = new XdgTimestepping( Op, new DGField[] { u }, new DGField[] { uResidual }, TimeSteppingScheme.BDF3, this.DelUpdateLevelset, LevelSetHandling.LieSplitting, MultigridOperatorConfig, MultigridSequence, _AgglomerationThreshold: this.THRESHOLD, LinearSolver: this.Control.LinearSolver, NonLinearSolver: this.Control.NonLinearSolver); } else { Debug.Assert(object.ReferenceEquals(this.MultigridSequence[0].ParentGrid, this.GridData)); TimeIntegration.DataRestoreAfterBalancing(L, new DGField[] { u }, new DGField[] { uResidual }, base.LsTrk, this.MultigridSequence); //AltTimeIntegration.DataRestoreAfterBalancing(L, new DGField[] { u }, new DGField[] { uResidual }, base.LsTrk, this.MultigridSequence); } }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { Op = new XSpatialOperatorMk2(1, 0, 1, QuadOrderFunc.SumOfMaxDegrees(RoundUp: true), new SpeciesId[] { LsTrk.GetSpeciesId("B") }, "u", "c1"); Op.EquationComponents["c1"].Add(new DxFlux()); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new LevSetFlx_phi0(this.LsTrk)); // flux am lev-set 0 Op.EquationComponents["c1"].Add(new LevSetFlx_phi1(this.LsTrk)); // flux am lev-set 1 Op.Commit(); }
/// <summary> /// creates the spatial operator that consists only of component <paramref name="c"/> /// </summary> public static XSpatialOperatorMk2 XOperator(this IEquationComponent c, Func <int[], int[], int[], int> quadOrderFunc) { string[] Codomain = new string[] { "v1" }; string[] Domain = c.ArgumentOrdering.ToArray(); string[] Param = (c.ParameterOrdering != null) ? c.ParameterOrdering.ToArray() : new string[0]; XSpatialOperatorMk2 ret = new XSpatialOperatorMk2(Domain, Param, Codomain, quadOrderFunc, null); ret.EquationComponents[Codomain[0]].Add(c); ret.Commit(); return(ret); }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { m_quadOrder = u1.Basis.Degree * 2; Op = new XSpatialOperatorMk2(2, 0, 2, (A, B, c) => m_quadOrder, LsTrk.SpeciesIdS.ToArray(), "u1", "u2", "c1", "c2"); Op.EquationComponents["c1"].Add(new DxFlux("u1", -3.0)); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new LevSetFlx(this.LsTrk, "u1", -3.0)); Op.EquationComponents["c2"].Add(new DxFlux("u1", +3.0)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new LevSetFlx(this.LsTrk, "u1", +3.0)); Op.EquationComponents["c2"].Add(new DxFlux("u2", 77.7)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new LevSetFlx(this.LsTrk, "u2", 77.7)); Op.Commit(); }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { int quadorder = this.u.Basis.Degree * 2 + 1; Op = new XSpatialOperatorMk2(1, 0, 1, (A, B, C) => quadorder, LsTrk.SpeciesIdS.ToArray(), "u", "c1"); var blkFlux = new DxFlux(this.LsTrk, alpha_A, alpha_B); Op.EquationComponents["c1"].Add(blkFlux); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new LevSetFlx(this.LsTrk, alpha_A, alpha_B)); // flux am lev-set 0 Op.Commit(); if (L == null) { TimeIntegration = new XdgBDFTimestepping( new DGField[] { u }, new DGField[] { uResidual }, base.LsTrk, true, DelComputeOperatorMatrix, null, DelUpdateLevelset, 3, // BDF3 //-1, // Crank-Nicolson //0, // Explicit Euler LevelSetHandling.LieSplitting, MassMatrixShapeandDependence.IsTimeDependent, SpatialOperatorType.LinearTimeDependent, MassScale, MultigridOperatorConfig, this.MultigridSequence, this.LsTrk.SpeciesIdS.ToArray(), quadorder, this.THRESHOLD, true, this.Control.NonLinearSolver, this.Control.LinearSolver); } else { Debug.Assert(object.ReferenceEquals(this.MultigridSequence[0].ParentGrid, this.GridData)); TimeIntegration.DataRestoreAfterBalancing(L, new DGField[] { u }, new DGField[] { uResidual }, base.LsTrk, this.MultigridSequence); } }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { Op = new XSpatialOperatorMk2(1, 0, 1, QuadOrderFunc: (int[] DomDegs, int[] ParamDegs, int[] CoDomDegs) => QuadOrder, __Species: new [] { "B" }, __varnames: new[] { "u", "c1" }); Op.EquationComponents["c1"].Add(new DxFlux()); // Flux in Bulk Phase; if (usePhi0) { Op.EquationComponents["c1"].Add(new LevSetFlx_phi0(this.LsTrk)); // flux am lev-set 0 } if (usePhi1) { Op.EquationComponents["c1"].Add(new LevSetFlx_phi1(this.LsTrk)); // flux am lev-set 1 } //Op.EquationComponents["c1"].Add(new DxBroken()); Op.Commit(); }
/// <summary> /// locks the configuration of the operator /// </summary> public void Commit() { InternalRepresentation.OperatorCoefficientsProvider = owner.OperatorCoefficientsProvider; InternalRepresentation.LinearizationHint = LinearizationHint.AdHoc; InternalRepresentation.ParameterFactories.Clear(); InternalRepresentation.ParameterFactories.AddRange(owner.ParameterFactories); InternalRepresentation.ParameterUpdates.Clear(); InternalRepresentation.ParameterUpdates.AddRange(owner.ParameterUpdates); InternalRepresentation.EdgeQuadraturSchemeProvider = owner.EdgeQuadraturSchemeProvider; InternalRepresentation.VolumeQuadraturSchemeProvider = owner.VolumeQuadraturSchemeProvider; InternalRepresentation.SurfaceElement_EdgeQuadraturSchemeProvider = owner.SurfaceElement_EdgeQuadraturSchemeProvider; InternalRepresentation.SurfaceElement_VolumeQuadraturSchemeProvider = owner.SurfaceElement_VolumeQuadraturSchemeProvider; InternalRepresentation.GhostEdgeQuadraturSchemeProvider = owner.GhostEdgeQuadraturSchemeProvider; InternalRepresentation.m_UserDefinedValues = owner.m_UserDefinedValues; InternalRepresentation.OperatorCoefficientsProvider = owner.OperatorCoefficientsProvider; InternalRepresentation.Commit(); }
public OperatorFactoryMk2( OperatorConfigurationMk2 config, LevelSetTracker _LsTrk, int _HMFdegree, int degU, IncompressibleMultiphaseBoundaryCondMap BcMap, bool _movingmesh, bool _evaporation) { // variable names // ============== D = _LsTrk.GridDat.SpatialDimension; this.LsTrk = _LsTrk; this.HMFDegree = _HMFdegree; this.dntParams = config.dntParams.CloneAs(); this.physParams = config.physParams.CloneAs(); this.UseExtendedVelocity = config.UseXDG4Velocity; this.movingmesh = _movingmesh; this.evaporation = _evaporation; // test input // ========== { if (config.DomBlocks.GetLength(0) != 2 || config.CodBlocks.GetLength(0) != 2) { throw new ArgumentException(); } if (config.physParams.mu_A == 0.0 && config.physParams.mu_B == 0.0) { muIs0 = true; } else { if (config.physParams.mu_A <= 0) { throw new ArgumentException(); } if (config.physParams.mu_B <= 0) { throw new ArgumentException(); } } if (config.physParams.rho_A <= 0) { throw new ArgumentException(); } if (config.physParams.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 = ((new string[] { "momX", "momY", "momZ" }).GetSubVector(0, D)).Cat("div"); Params = ArrayTools.Cat( VariableNames.Velocity0Vector(D), VariableNames.Velocity0MeanVector(D), "Curvature", (new string[] { "surfForceX", "surfForceY", "surfForceZ" }).GetSubVector(0, D), (new string[] { "NX", "NY", "NZ" }).GetSubVector(0, D), (new string[] { "GradTempX", "GradTempY", "GradTempZ" }.GetSubVector(0, D)), VariableNames.Temperature, "DisjoiningPressure"); DomName = ArrayTools.Cat(VariableNames.VelocityVector(D), VariableNames.Pressure); // selected part: if (config.CodBlocks[0]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(0, D)); } if (config.CodBlocks[1]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(D, 1)); } if (config.DomBlocks[0]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(0, D)); } if (config.DomBlocks[1]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(D, 1)); } muA = config.physParams.mu_A; muB = config.physParams.mu_B; rhoA = config.physParams.rho_A; rhoB = config.physParams.rho_B; sigma = config.physParams.Sigma; MatInt = !evaporation; double kA = config.thermParams.k_A; double kB = config.thermParams.k_B; double hVapA = config.thermParams.hVap_A; double hVapB = config.thermParams.hVap_B; double Tsat = config.thermParams.T_sat; double R_int = 0.0; //double T_intMin = 0.0; if (evaporation) { double f = config.thermParams.fc; double R = config.thermParams.Rc; //double pc = config.thermParams.pc; 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()))); } this.CurvatureRequired = true; } double p_c = config.thermParams.pc; // create Operator // =============== m_OP = new XSpatialOperatorMk2(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree, this.LsTrk.SpeciesIdS.ToArray()); // build the operator // ================== { // Momentum equation // ================= if (config.physParams.IncludeConvection && config.Transport) { for (int d = 0; d < D; d++) { var comps = m_OP.EquationComponents[CodName[d]]; double LFFA = config.dntParams.LFFA; double LFFB = config.dntParams.LFFB; //var conv = new Operator.Convection.ConvectionInBulk_LLF(D, BcMap, d, rhoA, rhoB, LFFA, LFFB, LsTrk); //comps.Add(conv); // Bulk component for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { double rhoSpc = 0.0; double LFFSpc = 0.0; switch (LsTrk.SpeciesNames[spc]) { case "A": rhoSpc = rhoA; LFFSpc = LFFA; break; case "B": rhoSpc = rhoB; LFFSpc = LFFB; break; default: throw new ArgumentException("Unknown species."); } var conv = new Operator.Convection.ConvectionInSpeciesBulk_LLF(D, BcMap, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], d, rhoSpc, LFFSpc, LsTrk); comps.Add(conv); // Bulk component } comps.Add(new Operator.Convection.ConvectionAtLevelSet_LLF(d, D, LsTrk, rhoA, rhoB, LFFA, LFFB, config.physParams.Material, BcMap, movingmesh)); // LevelSet component if (evaporation) { comps.Add(new Operator.Convection.GeneralizedConvectionAtLevelSet_DissipativePart(d, D, LsTrk, rhoA, rhoB, LFFA, LFFB, BcMap, kA, kB, hVapA, hVapB, R_int, Tsat, sigma, p_c)); } } this.U0meanrequired = true; } // pressure gradient // ================= if (config.PressureGradient) { for (int d = 0; d < D; d++) { var comps = m_OP.EquationComponents[CodName[d]]; //var pres = new Operator.Pressure.PressureInBulk(d, BcMap); //comps.Add(pres); for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { var pres = new Operator.Pressure.PressureInSpeciesBulk(d, BcMap, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc]); comps.Add(pres); } var presLs = new Operator.Pressure.PressureFormAtLevelSet(d, D, LsTrk); //, dntParams.UseWeightedAverages, muA, muB); comps.Add(presLs); } } // viscous operator // ================ if (config.Viscous && !muIs0) { for (int d = 0; d < D; d++) { var comps = m_OP.EquationComponents[CodName[d]]; double penalty = dntParams.PenaltySafety; switch (dntParams.ViscosityMode) { case ViscosityMode.Standard: { // Bulk operator: var Visc = new Operator.Viscosity.ViscosityInBulk_GradUTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB); // , _betaA: this.physParams.betaS_A, _betaB: this.physParams.betaS_B); comps.Add(Visc); if (dntParams.UseGhostPenalties) { var ViscPenalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(penalty * 1.0, 0.0, BcMap, d, D, muA, muB); m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(ViscPenalty); } // Level-Set operator: comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, muA, muB, penalty * 1.0, d, true)); break; } case ViscosityMode.TransposeTermMissing: { // Bulk operator: var Visc = new Operator.Viscosity.ViscosityInBulk_GradUTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB); comps.Add(Visc); if (dntParams.UseGhostPenalties) { var ViscPenalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(penalty * 1.0, 0.0, BcMap, d, D, muA, muB); m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(ViscPenalty); } // Level-Set operator: comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, muA, muB, penalty * 1.0, d, false)); break; } case ViscosityMode.FullySymmetric: { // Bulk operator for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { var Visc1 = new Operator.Viscosity.ViscosityInSpeciesBulk_GradUTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], d, D, muA, muB); comps.Add(Visc1); var Visc2 = new Operator.Viscosity.ViscosityInSpeciesBulk_GradUtranspTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], d, D, muA, muB); comps.Add(Visc2); } if (dntParams.UseGhostPenalties) { var Visc1Penalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm( penalty, 0.0, BcMap, d, D, muA, muB); var Visc2Penalty = new Operator.Viscosity.ViscosityInBulk_GradUtranspTerm( penalty, 0.0, BcMap, d, D, muA, muB); m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(Visc1Penalty); m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(Visc2Penalty); } // Level-Set operator comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_FullySymmetric(LsTrk, muA, muB, penalty, d, dntParams.UseWeightedAverages)); if (this.evaporation) { comps.Add(new Operator.Viscosity.GeneralizedViscosityAtLevelSet_FullySymmetric(LsTrk, muA, muB, penalty, d, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c)); } break; } default: throw new NotImplementedException(); } } } // Continuum equation // ================== if (config.continuity) { for (int d = 0; d < D; d++) { //var src = new Operator.Continuity.DivergenceInBulk_Volume(d, D, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti); //var flx = new Operator.Continuity.DivergenceInBulk_Edge(d, BcMap, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti); //m_OP.EquationComponents["div"].Add(flx); //m_OP.EquationComponents["div"].Add(src); for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { double rhoSpc = 0.0; switch (LsTrk.SpeciesNames[spc]) { case "A": rhoSpc = rhoA; break; case "B": rhoSpc = rhoB; break; default: throw new ArgumentException("Unknown species."); } var src = new Operator.Continuity.DivergenceInSpeciesBulk_Volume(d, D, LsTrk.SpeciesIdS[spc], rhoSpc, config.dntParams.ContiSign, config.dntParams.RescaleConti); var flx = new Operator.Continuity.DivergenceInSpeciesBulk_Edge(d, BcMap, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], rhoSpc, config.dntParams.ContiSign, config.dntParams.RescaleConti); m_OP.EquationComponents["div"].Add(flx); m_OP.EquationComponents["div"].Add(src); } } var divPen = new Operator.Continuity.DivergenceAtLevelSet(D, LsTrk, rhoA, rhoB, MatInt, config.dntParams.ContiSign, config.dntParams.RescaleConti); //, dntParams.UseWeightedAverages, muA, muB); m_OP.EquationComponents["div"].Add(divPen); if (evaporation) { var divPenGen = new Operator.Continuity.GeneralizedDivergenceAtLevelSet(D, LsTrk, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti, kA, kB, hVapA, R_int, Tsat, sigma, p_c); m_OP.EquationComponents["div"].Add(divPenGen); } } // surface tension // =============== if (config.PressureGradient && config.physParams.Sigma != 0.0) { // isotropic part of the surface stress tensor if (config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Flux || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Local || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine) { for (int d = 0; d < D; d++) { if (config.dntParams.SST_isotropicMode != SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine) { IEquationComponent G = new SurfaceTension_LaplaceBeltrami_Surface(d, config.physParams.Sigma * 0.5); IEquationComponent H = new SurfaceTension_LaplaceBeltrami_BndLine(d, config.physParams.Sigma * 0.5, config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Flux); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(G); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(H); } else { IEquationComponent isoSurfT = new IsotropicSurfaceTension_LaplaceBeltrami(d, D, config.physParams.Sigma * 0.5, BcMap.EdgeTag2Type, config.physParams.theta_e, config.physParams.betaL); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(isoSurfT); } } this.NormalsRequired = true; } else if (config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Projected || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_ClosestPoint || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_LaplaceBeltramiMean || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Fourier) { for (int d = 0; d < D; d++) { m_OP.EquationComponents[CodName[d]].Add(new CurvatureBasedSurfaceTension(d, D, LsTrk, config.physParams.Sigma)); } this.CurvatureRequired = true; } else { throw new NotImplementedException("Not implemented."); } // dynamic part if (config.dntParams.SurfStressTensor != SurfaceSressTensor.Isotropic) { double muI = config.physParams.mu_I; double lamI = config.physParams.lambda_I; double penalty_base = (degU + 1) * (degU + D) / D; double penalty = penalty_base * dntParams.PenaltySafety; // surface shear viscosity if (config.dntParams.SurfStressTensor == SurfaceSressTensor.SurfaceRateOfDeformation || config.dntParams.SurfStressTensor == SurfaceSressTensor.SemiImplicit || config.dntParams.SurfStressTensor == SurfaceSressTensor.FullBoussinesqScriven) { for (int d = 0; d < D; d++) { var surfDeformRate = new BoussinesqScriven_SurfaceDeformationRate_GradU(d, muI * 0.5, penalty); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfDeformRate); if (config.dntParams.SurfStressTensor != SurfaceSressTensor.SemiImplicit) { var surfDeformRateT = new BoussinesqScriven_SurfaceDeformationRate_GradUTranspose(d, muI * 0.5, penalty); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfDeformRateT); } } } // surface dilatational viscosity if (config.dntParams.SurfStressTensor == SurfaceSressTensor.SurfaceVelocityDivergence || config.dntParams.SurfStressTensor == SurfaceSressTensor.FullBoussinesqScriven) { for (int d = 0; d < D; d++) { var surfVelocDiv = new BoussinesqScriven_SurfaceVelocityDivergence(d, muI * 0.5, lamI * 0.5, penalty, BcMap.EdgeTag2Type); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfVelocDiv); } } } // stabilization if (config.dntParams.UseLevelSetStabilization) { for (int d = 0; d < D; d++) { m_OP.EquationComponents[CodName[d]].Add(new LevelSetStabilization(d, D, LsTrk)); } } } // surface force term // ================== if (config.PressureGradient && config.physParams.useArtificialSurfaceForce) { for (int d = 0; d < D; d++) { m_OP.EquationComponents[CodName[d]].Add(new SurfaceTension_ArfForceSrc(d, D, LsTrk)); } } // evaporation (mass flux) // ======================= if (evaporation) { for (int d = 0; d < D; d++) { m_OP.EquationComponents[CodName[d]].Add(new Operator.DynamicInterfaceConditions.MassFluxAtInterface(d, D, LsTrk, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c)); } } } // Finalize // ======== m_OP.Commit(); }
private void AssembleMatrix(double MU_A, double MU_B, out BlockMsrMatrix M, out double[] b, out MultiphaseCellAgglomerator agg, out MassMatrixFactory massFact) { using (var tr = new FuncTrace()) { // create operator // =============== if (this.Control.SetDefaultDiriBndCnd) { this.Control.xLaplaceBCs.g_Diri = ((CommonParamsBnd inp) => 0.0); this.Control.xLaplaceBCs.IsDirichlet = (inp => true); } double D = this.GridData.SpatialDimension; int p = u.Basis.Degree; double penalty_base = (p + 1) * (p + D) / D; double penalty_multiplyer = base.Control.penalty_multiplyer; XQuadFactoryHelper.MomentFittingVariants momentFittingVariant; if (D == 3) { momentFittingVariant = XQuadFactoryHelper.MomentFittingVariants.Classic; } momentFittingVariant = this.Control.CutCellQuadratureType; int order = this.u.Basis.Degree * 2; Op = new XSpatialOperatorMk2(1, 1, (A, B, C) => order, this.LsTrk.SpeciesNames, "u", "c1"); var lengthScales = ((BoSSS.Foundation.Grid.Classic.GridData)GridData).Cells.PenaltyLengthScales; var lap = new XLaplace_Bulk(this.LsTrk, penalty_multiplyer * penalty_base, "u", this.Control.xLaplaceBCs, 1.0, MU_A, MU_B, lengthScales, this.Control.ViscosityMode); Op.EquationComponents["c1"].Add(lap); // Bulk form Op.EquationComponents["c1"].Add(new XLaplace_Interface(this.LsTrk, MU_A, MU_B, penalty_base * 2, this.Control.ViscosityMode)); // coupling form Op.Commit(); // create agglomeration // ==================== var map = new UnsetteledCoordinateMapping(u.Basis); //agg = new MultiphaseCellAgglomerator( // new CutCellMetrics(momentFittingVariant, // QuadOrderFunc.SumOfMaxDegrees(RoundUp: true)(map.BasisS.Select(bs => bs.Degree).ToArray(), new int[0], map.BasisS.Select(bs => bs.Degree).ToArray()), // //this.HMFDegree, // LsTrk, this.LsTrk.SpeciesIdS.ToArray()), // this.Control.AgglomerationThreshold, false); agg = LsTrk.GetAgglomerator(this.LsTrk.SpeciesIdS.ToArray(), order, this.Control.AgglomerationThreshold); // compute matrix // ============= using (new BlockTrace("XdgMatrixAssembly", tr)) { M = new BlockMsrMatrix(map, map); b = new double[M.RowPartitioning.LocalLength]; //Op.ComputeMatrixEx(LsTrk, // map, null, map, // M, b, false, 0.0, true, // agg.CellLengthScales, null, null, //out massFact, // this.LsTrk.SpeciesIdS.ToArray()); XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(this.LsTrk, map, null, map); mtxBuilder.CellLengthScales.AddRange(agg.CellLengthScales); mtxBuilder.time = 0.0; mtxBuilder.MPITtransceive = true; mtxBuilder.ComputeMatrix(M, b); } // compare with linear evaluation // ============================== DGField[] testDomainFieldS = map.BasisS.Select(bb => new XDGField(bb as XDGBasis)).ToArray(); CoordinateVector test = new CoordinateVector(testDomainFieldS); DGField[] errFieldS = map.BasisS.Select(bb => new XDGField(bb as XDGBasis)).ToArray(); CoordinateVector Err = new CoordinateVector(errFieldS); var eval = Op.GetEvaluatorEx(LsTrk, testDomainFieldS, null, map); eval.CellLengthScales.AddRange(agg.CellLengthScales); eval.time = 0.0; int L = test.Count; Random r = new Random(); for (int i = 0; i < L; i++) { test[i] = r.NextDouble(); } double[] R1 = new double[L]; double[] R2 = new double[L]; eval.Evaluate(1.0, 1.0, R1); R2.AccV(1.0, b); M.SpMV(1.0, test, 1.0, R2); Err.AccV(+1.0, R1); Err.AccV(-1.0, R2); double ErrDist = GenericBlas.L2DistPow2(R1, R2).MPISum().Sqrt(); double Ref = test.L2NormPow2().MPISum().Sqrt(); Assert.LessOrEqual(ErrDist, Ref * 1.0e-5, "Mismatch between explicit evaluation of XDG operator and matrix."); // agglomeration wahnsinn // ====================== agg.ManipulateMatrixAndRHS(M, b, map, map); foreach (var S in this.LsTrk.SpeciesNames) { Console.WriteLine(" Species {0}: no of agglomerated cells: {1}", S, agg.GetAgglomerator(this.LsTrk.GetSpeciesId(S)).AggInfo.SourceCells.NoOfItemsLocally); } // mass matrix factory // =================== Basis maxB = map.BasisS.ElementAtMax(bss => bss.Degree); //massFact = new MassMatrixFactory(maxB, agg); massFact = LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), order).MassMatrixFactory; } }
public XDGTestSetup( int p, double AggregationThreshold, int TrackerWidth, MultigridOperator.Mode mumo, XQuadFactoryHelper.MomentFittingVariants momentFittingVariant, ScalarFunction LevSetFunc = null) { // Level set, tracker and XDG basis // ================================ if (LevSetFunc == null) { LevSetFunc = ((_2D)((x, y) => 0.8 * 0.8 - x * x - y * y)).Vectorize(); } LevSet = new LevelSet(new Basis(grid, 2), "LevelSet"); LevSet.Clear(); LevSet.ProjectField(LevSetFunc); LsTrk = new LevelSetTracker(grid, XQuadFactoryHelper.MomentFittingVariants.Classic, TrackerWidth, new string[] { "A", "B" }, LevSet); LsTrk.UpdateTracker(0.0); XB = new XDGBasis(LsTrk, p); XSpatialOperatorMk2 Dummy = new XSpatialOperatorMk2(1, 0, 1, QuadOrderFunc.SumOfMaxDegrees(RoundUp: true), this.LsTrk.SpeciesNames, "C1", "u"); //Dummy.EquationComponents["c1"].Add(new Dummy.Commit(); //Tecplot.PlotFields(new DGField[] { LevSet }, "agglo", 0.0, 3); // operator // ======== Debug.Assert(p <= 4); XDGBasis opXB = new XDGBasis(LsTrk, 4); // we want to have a very precise quad rule var map = new UnsetteledCoordinateMapping(opXB); int quadOrder = Dummy.QuadOrderFunction(map.BasisS.Select(bs => bs.Degree).ToArray(), new int[0], map.BasisS.Select(bs => bs.Degree).ToArray()); //agg = new MultiphaseCellAgglomerator(new CutCellMetrics(momentFittingVariant, quadOrder, LsTrk, LsTrk.SpeciesIdS.ToArray()), AggregationThreshold, false); agg = LsTrk.GetAgglomerator(LsTrk.SpeciesIdS.ToArray(), quadOrder, __AgglomerationTreshold: AggregationThreshold); foreach (var S in LsTrk.SpeciesIdS) { Console.WriteLine("Species {0}, no. of agglomerated cells {1} ", LsTrk.GetSpeciesName(S), agg.GetAgglomerator(S).AggInfo.SourceCells.Count()); } // mass matrix factory // =================== // Basis maxB = map.BasisS.ElementAtMax(b => b.Degree); //MassFact = new MassMatrixFactory(maxB, agg); MassFact = LsTrk.GetXDGSpaceMetrics(LsTrk.SpeciesIdS.ToArray(), quadOrder, 1).MassMatrixFactory; // Test field // ========== // set the test field: this is a polynomial function, // but different for each species; On this field, restriction followed by prolongation should be the identity this.Xdg_uTest = new XDGField(this.XB, "uTest"); Dictionary <SpeciesId, double> dumia = new Dictionary <SpeciesId, double>(); int i = 2; foreach (var Spc in LsTrk.SpeciesIdS) { dumia.Add(Spc, i); i -= 1; } SetTestValue(Xdg_uTest, dumia); // dummy operator matrix which fits polynomial degree p // ==================================================== Xdg_opMtx = new BlockMsrMatrix(Xdg_uTest.Mapping, Xdg_uTest.Mapping); Xdg_opMtx.AccEyeSp(120.0); // XDG Aggregation BasiseS // ======================= //XAggB = MgSeq.Select(agGrd => new XdgAggregationBasis[] { new XdgAggregationBasis(uTest.Basis, agGrd) }).ToArray(); XAggB = new XdgAggregationBasis[MgSeq.Length][]; var _XAggB = AggregationGridBasis.CreateSequence(MgSeq, Xdg_uTest.Mapping.BasisS); for (int iLevel = 0; iLevel < XAggB.Length; iLevel++) { XAggB[iLevel] = new[] { (XdgAggregationBasis)(_XAggB[iLevel][0]) }; XAggB[iLevel][0].Update(agg); } // Multigrid Operator // ================== Xdg_opMtx = new BlockMsrMatrix(Xdg_uTest.Mapping, Xdg_uTest.Mapping); Xdg_opMtx.AccEyeSp(120.0); XdgMultigridOp = new MultigridOperator(XAggB, Xdg_uTest.Mapping, Xdg_opMtx, MassFact.GetMassMatrix(Xdg_uTest.Mapping, false), new MultigridOperator.ChangeOfBasisConfig[][] { new MultigridOperator.ChangeOfBasisConfig[] { new MultigridOperator.ChangeOfBasisConfig() { VarIndex = new int[] { 0 }, mode = mumo, DegreeS = new int[] { p } } } }, null); }
/// <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(); }
/// <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(); }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { m_quadOrder = u1.Basis.Degree * 2; Setup(); //XLaplaceBCs xLaplaceBCs = new XLaplaceBCs(); //xLaplaceBCs.g_Diri = ((CommonParamsBnd inp) => 0.0); //xLaplaceBCs.IsDirichlet = (inp => true); //double penalty_base = (m_DGorder + 1) * (m_DGorder + 2) / 2; //var lengthScales = ((BoSSS.Foundation.Grid.Classic.GridData)GridData).Cells.PenaltyLengthScales; //var lap = new XLaplace_Bulk(this.LsTrk, 2.0 * penalty_base, "u1", xLaplaceBCs, 1.0, 1, 1000, lengthScales, XLaplace_Interface.Mode.SIP); Op = new XSpatialOperatorMk2(2, 0, 2, (A, B, c) => m_quadOrder, LsTrk.SpeciesNames, "u1", "u2", "c1", "c2"); //Op = new XSpatialOperatorMk2(1, 0, 1, (A, B, c) => m_quadOrder, LsTrk.SpeciesIdS.ToArray(), "u1","c1"); switch (m_Mshape) { case MatrixShape.laplace: var lengthScales = ((BoSSS.Foundation.Grid.Classic.GridData)GridData).Cells.PenaltyLengthScales; int p = u1.Basis.Degree; int D = this.GridData.SpatialDimension; double penalty_base = (p + 1) * (p + D) / D; double MU_A = 1; double MU_B = 10; Op.EquationComponents["c1"].Add(new XLaplace_Bulk(this.LsTrk, MU_A, MU_B, penalty_base * 2, "u1", lengthScales)); // Bulk form Op.EquationComponents["c1"].Add(new XLaplace_Interface(this.LsTrk, MU_A, MU_B, penalty_base * 2, "u1", lengthScales)); // coupling form Op.EquationComponents["c1"].Add(new XLaplace_Bulk(this.LsTrk, MU_A, MU_B, penalty_base * 2, "u2", lengthScales)); // Bulk form Op.EquationComponents["c1"].Add(new XLaplace_Interface(this.LsTrk, MU_A, MU_B, penalty_base * 2, "u2", lengthScales)); // coupling form Op.EquationComponents["c2"].Add(new XLaplace_Bulk(this.LsTrk, MU_A, MU_B, penalty_base * 2, "u1", lengthScales)); // Bulk form Op.EquationComponents["c2"].Add(new XLaplace_Interface(this.LsTrk, MU_A, MU_B, penalty_base * 2, "u1", lengthScales)); // coupling form Op.EquationComponents["c2"].Add(new XLaplace_Bulk(this.LsTrk, MU_A, MU_B, penalty_base * 2, "u2", lengthScales)); // Bulk form Op.EquationComponents["c2"].Add(new XLaplace_Interface(this.LsTrk, MU_A, MU_B, penalty_base * 2, "u2", lengthScales)); // coupling form Op.EquationComponents["c1"].Add(new SourceTest("u1", 11)); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new SourceTest("u2", 11)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new SourceTest("u1", 11)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new SourceTest("u2", 11)); // Flux in Bulk Phase; break; case MatrixShape.full: //tested: shape valid for testing Op.EquationComponents["c1"].Add(new DxFlux("u1", 3)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new DxFlux("u2", 4)); // Flux in Bulk Phase; break; case MatrixShape.full_var: //tested: shape valid for testing Op.EquationComponents["c1"].Add(new SourceTest("u1", 1)); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new SourceTest("u2", 2)); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new DxFlux("u1", 3)); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new DxFlux("u2", 4)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new SourceTest("u1", -5)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new SourceTest("u2", -6)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new DxFlux("u1", -7)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new DxFlux("u2", -8)); // Flux in Bulk Phase; break; case MatrixShape.full_spec: //tested: no spec coupling in the secondary diagonals (obviously) Op.EquationComponents["c1"].Add(new LevSetFlx(this.LsTrk, "u1", -1)); Op.EquationComponents["c1"].Add(new SourceTest("u1", 1)); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new DxFlux("u1", 10)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new LevSetFlx(this.LsTrk, "u2", -4)); Op.EquationComponents["c2"].Add(new SourceTest("u2", -2)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new DxFlux("u2", -11)); // Flux in Bulk Phase; break; case MatrixShape.full_var_spec: //tested: no spec coupling in the secondary diagonals (obviously) Op.EquationComponents["c1"].Add(new LevSetFlx(this.LsTrk, "u1", -1)); Op.EquationComponents["c1"].Add(new LevSetFlx(this.LsTrk, "u2", -1)); Op.EquationComponents["c1"].Add(new DxFlux("u1", 3)); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new DxFlux("u2", 4)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new LevSetFlx(this.LsTrk, "u1", -1)); Op.EquationComponents["c2"].Add(new LevSetFlx(this.LsTrk, "u2", -1)); Op.EquationComponents["c2"].Add(new DxFlux("u1", 3)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new DxFlux("u2", 4)); // Flux in Bulk Phase; break; case MatrixShape.diagonal_var_spec: // block diagonal matrix (ignore cell coupling) Op.EquationComponents["c1"].Add(new SourceTest("u1", 1)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new SourceTest("u1", -2)); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new SourceTest("u2", 3)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new SourceTest("u2", -4)); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new LevSetFlx(this.LsTrk, "u1", -2)); Op.EquationComponents["c2"].Add(new LevSetFlx(this.LsTrk, "u2", -4)); break; case MatrixShape.diagonal_spec: // block diagonal matrix (ignore cell and variable coupling) Op.EquationComponents["c1"].Add(new LevSetFlx(this.LsTrk, "u1", -2)); Op.EquationComponents["c2"].Add(new LevSetFlx(this.LsTrk, "u2", -4)); Op.EquationComponents["c1"].Add(new SourceTest("u1", 1)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new SourceTest("u2", -4)); // Flux in Bulk Phase; break; case MatrixShape.diagonal: // sparse matrix (ignore cell and variable coupling) Op.EquationComponents["c1"].Add(new SourceTest("u1", 1)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new SourceTest("u2", -4)); // Flux in Bulk Phase; break; case MatrixShape.diagonal_var: // sparse matrix (ignore cell and variable coupling) Op.EquationComponents["c1"].Add(new SourceTest("u1", 1)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new SourceTest("u1", -2)); // Flux in Bulk Phase; Op.EquationComponents["c1"].Add(new SourceTest("u2", 3)); // Flux in Bulk Phase; Op.EquationComponents["c2"].Add(new SourceTest("u2", -4)); // Flux in Bulk Phase; break; } //Op.EquationComponents["c1"].Add(new LevSetFlx(this.LsTrk, "u1", -1)); //Op.EquationComponents["c1"].Add(new DxFlux("u2", -1)); // Flux in Bulk Phase; //Op.EquationComponents["c2"].Add(new DxFlux("u1", 2)); // Flux in Bulk Phase; //Op.EquationComponents["c2"].Add(new DxFlux("u2", -2)); // Flux in Bulk Phase; //Op.EquationComponents["c1"].Add(new DxFlux("u1", -3.0)); // Flux in Bulk Phase; //Op.EquationComponents["c1"].Add(new LevSetFlx(this.LsTrk, "u1", -3.0)); //Op.EquationComponents["c2"].Add(new DxFlux("u1", +3.0)); // Flux in Bulk Phase; //Op.EquationComponents["c2"].Add(new LevSetFlx(this.LsTrk, "u1", +3.0)); //Op.EquationComponents["c2"].Add(new DxFlux("u2", 77.7)); // Flux in Bulk Phase; //Op.EquationComponents["c2"].Add(new LevSetFlx(this.LsTrk, "u2", 77.7)); Op.Commit(); Basis maxB = map.BasisS.ElementAtMax(bss => bss.Degree); //massFact = new MassMatrixFactory(maxB, agg); massFact = LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), m_quadOrder).MassMatrixFactory; }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { if (Operator != null) { return; } // create operator // --------------- Func <double[], double, double> S; switch (this.Control.InterfaceMode) { case InterfaceMode.MovingInterface: S = this.Control.S; break; case InterfaceMode.Splitting: S = (X, t) => 0.0; break; default: throw new NotImplementedException(); } int quadOrder; if (this.Control.Eq == Equation.ScalarTransport) { quadOrder = this.LinearQuadratureDegree; Func <double[], double, double>[] uBnd = new Func <double[], double, double> [this.Grid.EdgeTagNames.Keys.Max() + 1]; for (int iEdgeTag = 1; iEdgeTag < uBnd.Length; iEdgeTag++) { string nameEdgeTag; if (this.Grid.EdgeTagNames.TryGetValue((byte)iEdgeTag, out nameEdgeTag)) { if (!this.Control.BoundaryValues[nameEdgeTag].Evaluators.TryGetValue("u", out uBnd[iEdgeTag])) { uBnd[iEdgeTag] = (X, t) => 0.0; } } } Operator = new XSpatialOperatorMk2(1, 2, 1, (A, B, C) => quadOrder, LsTrk.SpeciesIdS.ToArray(), "u", "Vx", "Vy", "Cod1"); Operator.EquationComponents["Cod1"].Add(new TranportFlux_Bulk() { Inflow = uBnd }); Operator.EquationComponents["Cod1"].Add(new TransportFlux_Interface(this.LsTrk, S)); Operator.Commit(); } else if (this.Control.Eq == Equation.HeatEq) { quadOrder = this.LinearQuadratureDegree; Operator = new XSpatialOperatorMk2(1, 0, 1, (A, B, C) => quadOrder, LsTrk.SpeciesIdS.ToArray(), "u", "Cod1"); var bulkFlx = new HeatFlux_Bulk() { m_muA = this.Control.muA, m_muB = this.Control.muB, m_rhsA = this.Control.rhsA, m_rhsB = this.Control.rhsB }; var intfFlx = new HeatFlux_Interface(this.LsTrk, S) { m_muA = this.Control.muA, m_muB = this.Control.muB }; Operator.EquationComponents["Cod1"].Add(bulkFlx); Operator.EquationComponents["Cod1"].Add(intfFlx); Operator.Commit(); } else if (this.Control.Eq == Equation.Burgers) { quadOrder = this.NonlinearQuadratureDegree; Operator = new XSpatialOperatorMk2(1, 1, 1, (A, B, C) => quadOrder, LsTrk.SpeciesIdS.ToArray(), "u", "u0", "Cod1"); Operator.EquationComponents["Cod1"].Add(new BurgersFlux_Bulk() { Direction = this.Control.BurgersDirection, Inflow = this.Control.u_Ex }); Operator.EquationComponents["Cod1"].Add(new BurgersFlux_Interface(this.LsTrk, S, this.Control.BurgersDirection)); Operator.Commit(); } else { throw new NotImplementedException(); } // create timestepper // ------------------ LevelSetHandling lsh; switch (this.Control.InterfaceMode) { case InterfaceMode.MovingInterface: lsh = LevelSetHandling.Coupled_Once; break; case InterfaceMode.Splitting: lsh = LevelSetHandling.LieSplitting; break; default: throw new NotImplementedException(); } RungeKuttaScheme rksch = null; int bdfOrder = -1000; if (this.Control.TimeSteppingScheme == TimeSteppingScheme.CrankNicolson) { bdfOrder = -1; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.ExplicitEuler) { bdfOrder = 0; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.ImplicitEuler) { bdfOrder = 1; } else if (this.Control.TimeSteppingScheme.ToString().StartsWith("BDF")) { bdfOrder = Convert.ToInt32(this.Control.TimeSteppingScheme.ToString().Substring(3)); } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK1) { rksch = RungeKuttaScheme.ExplicitEuler; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK1u1) { rksch = RungeKuttaScheme.ExplicitEuler2; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK2) { rksch = RungeKuttaScheme.Heun2; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK3) { rksch = RungeKuttaScheme.TVD3; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK4) { rksch = RungeKuttaScheme.RungeKutta1901; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK_ImplicitEuler) { rksch = RungeKuttaScheme.ImplicitEuler; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK_CrankNic) { rksch = RungeKuttaScheme.CrankNicolson; } else if (this.Control.TimeSteppingScheme == TimeSteppingScheme.RK_IMEX3) { rksch = RungeKuttaScheme.IMEX3; } else { throw new NotImplementedException(); } if (bdfOrder > -1000) { m_BDF_Timestepper = new XdgBDFTimestepping(new DGField[] { this.u }, new DGField[] { this.Residual }, LsTrk, true, DelComputeOperatorMatrix, null, DelUpdateLevelset, bdfOrder, lsh, MassMatrixShapeandDependence.IsTimeDependent, SpatialOperatorType.LinearTimeDependent, MassScale, null, base.MultigridSequence, this.LsTrk.SpeciesIdS.ToArray(), quadOrder, this.Control.AgglomerationThreshold, false, this.Control.NonLinearSolver, this.Control.LinearSolver); } else { m_RK_Timestepper = new XdgRKTimestepping(new DGField[] { this.u }, new DGField[] { this.Residual }, LsTrk, DelComputeOperatorMatrix, DelUpdateLevelset, rksch, lsh, MassMatrixShapeandDependence.IsTimeDependent, SpatialOperatorType.LinearTimeDependent, MassScale, null, base.MultigridSequence, this.LsTrk.SpeciesIdS.ToArray(), quadOrder, this.Control.AgglomerationThreshold, false, this.Control.NonLinearSolver, this.Control.LinearSolver); } }