// ========================== // Check boundary conditions // ========================== // ======================== // Check level set movement // ======================== //[Test] Deactivated, because failing & to much variations public static void LineMovementTest( [Values(LevelSetEvolution.FastMarching, LevelSetEvolution.ExtensionVelocity, LevelSetEvolution.ScalarConvection, LevelSetEvolution.Fourier)] LevelSetEvolution lsEvo, [Values(LevelSetHandling.Coupled_Once, LevelSetHandling.LieSplitting, LevelSetHandling.Coupled_Iterative)] LevelSetHandling lsHandl, [Values(TimeSteppingScheme.ImplicitEuler, TimeSteppingScheme.CrankNicolson, TimeSteppingScheme.BDF2)] TimeSteppingScheme tsScheme, [Values(0.5)] double cLength) { var C = PhysicalBasedTestcases.ChannelFlow.CF_LevelSetMovementTest(1, cLength, lsEvo, lsHandl, tsScheme); using (var solver = new XNSE_SolverMain()) { solver.Init(C); solver.RunSolverMode(); double[] BmQ_LL = solver.ComputeBenchmarkQuantities_LineInterface(); double err_thrsld = 1e-4; // length of contact-line double err = Math.Abs(2 - BmQ_LL[0]); Assert.Less(err, err_thrsld, "error interface length"); Console.WriteLine("error in interface length = {0}", err); // area of species err = Math.Abs(cLength * 1 - BmQ_LL[1]); Assert.Less(err, err_thrsld, "error in area"); Console.WriteLine("error in area = {0}", err); } }
/// <summary> /// Constructor for conventional (single-phase, non-X) DG /// </summary> public XdgTimestepping( SpatialOperator op, IEnumerable <DGField> Fields, IEnumerable <DGField> IterationResiduals, TimeSteppingScheme __Scheme, MultigridOperator.ChangeOfBasisConfig[][] _MultigridOperatorConfig = null, AggregationGridData[] _MultigridSequence = null, LinearSolverConfig LinearSolver = null, NonLinearSolverConfig NonLinearSolver = null) // { this.Scheme = __Scheme; this.DgOperator = op; this.Parameters = op.InvokeParameterFactory(Fields); var spc = CreateDummyTracker(Fields); ConstructorCommon(op, false, Fields, this.Parameters, IterationResiduals, new[] { spc }, UpdateLevelsetWithNothing, LevelSetHandling.None, _MultigridOperatorConfig, _MultigridSequence, 0.0, LinearSolver, NonLinearSolver); }
/// <summary> /// translates a time-stepping scheme code /// </summary> /// <param name="Scheme"></param> /// <param name="rksch">if <paramref name="Scheme"/> denotes a Runge-Kutta scheme, well, the Runge-Kutta scheme</param> /// <param name="bdfOrder">if <paramref name="Scheme"/> denotes a BDF-scheme, its order</param> static public void DecodeScheme(TimeSteppingScheme Scheme, out RungeKuttaScheme rksch, out int bdfOrder) { rksch = null; bdfOrder = -1000; if (Scheme == TimeSteppingScheme.CrankNicolson) { bdfOrder = -1; } else if (Scheme == TimeSteppingScheme.ExplicitEuler) { bdfOrder = 0; } else if (Scheme == TimeSteppingScheme.ImplicitEuler) { bdfOrder = 1; } else if (Scheme.ToString().StartsWith("BDF")) { bdfOrder = Convert.ToInt32(Scheme.ToString().Substring(3)); } else if (Scheme == TimeSteppingScheme.RK1) { rksch = RungeKuttaScheme.ExplicitEuler; } else if (Scheme == TimeSteppingScheme.RK1u1) { rksch = RungeKuttaScheme.ExplicitEuler2; } else if (Scheme == TimeSteppingScheme.RK2) { rksch = RungeKuttaScheme.Heun2; } else if (Scheme == TimeSteppingScheme.RK3) { rksch = RungeKuttaScheme.TVD3; } else if (Scheme == TimeSteppingScheme.RK4) { rksch = RungeKuttaScheme.RungeKutta1901; } else if (Scheme == TimeSteppingScheme.RK_ImplicitEuler) { rksch = RungeKuttaScheme.ImplicitEuler; } else if (Scheme == TimeSteppingScheme.RK_CrankNic) { rksch = RungeKuttaScheme.CrankNicolson; } else if (Scheme == TimeSteppingScheme.RK_IMEX3) { rksch = RungeKuttaScheme.IMEX3; } else { throw new NotImplementedException(); } }
/// <summary> /// Constructor for an XDG operator /// </summary> public XdgTimestepping( XSpatialOperatorMk2 op, IEnumerable <DGField> Fields, IEnumerable <DGField> IterationResiduals, TimeSteppingScheme __Scheme, DelUpdateLevelset _UpdateLevelset = null, LevelSetHandling _LevelSetHandling = LevelSetHandling.None, MultigridOperator.ChangeOfBasisConfig[][] _MultigridOperatorConfig = null, AggregationGridData[] _MultigridSequence = null, double _AgglomerationThreshold = 0.1, LinearSolverConfig LinearSolver = null, NonLinearSolverConfig NonLinearSolver = null) // { this.Scheme = __Scheme; this.XdgOperator = op; this.Parameters = op.InvokeParameterFactory(Fields); foreach (var f in Fields.Cat(IterationResiduals).Cat(Parameters)) { if (f != null && f is XDGField xf) { if (LsTrk == null) { LsTrk = xf.Basis.Tracker; } else { if (!object.ReferenceEquals(LsTrk, xf.Basis.Tracker)) { throw new ArgumentException(); } } } } if (LsTrk == null) { throw new ArgumentException("unable to get Level Set Tracker reference"); } bool UseX = Fields.Any(f => f is XDGField) || IterationResiduals.Any(f => f is XDGField); SpeciesId[] spcToCompute = op.Species.Select(spcName => LsTrk.GetSpeciesId(spcName)).ToArray(); ConstructorCommon(op, UseX, Fields, this.Parameters, IterationResiduals, spcToCompute, _UpdateLevelset, _LevelSetHandling, _MultigridOperatorConfig, _MultigridSequence, _AgglomerationThreshold, LinearSolver, NonLinearSolver); }
public static void TestConvection_Splitting_LowOrder( [Values(TimeSteppingScheme.ExplicitEuler, TimeSteppingScheme.CrankNicolson, TimeSteppingScheme.ImplicitEuler, TimeSteppingScheme.BDF2, TimeSteppingScheme.BDF3, TimeSteppingScheme.BDF4, TimeSteppingScheme.RK1, TimeSteppingScheme.RK1u1, TimeSteppingScheme.RK3, TimeSteppingScheme.RK4, TimeSteppingScheme.RK_ImplicitEuler, TimeSteppingScheme.RK_CrankNic, TimeSteppingScheme.RK_IMEX3)] TimeSteppingScheme tsc, [Values(0.2, 0.23)] double TimestepSize, [Values(8)] int NoOfTs, [Values(0.0)] double TimeOffest ) { // set up // ------------------------------------------ XdgTimesteppingTestControl ctrl = HardCodedControl.Gerade(angle: 0, degree: 0, GridResolutionFactor: 1); ctrl.NoOfTimesteps = NoOfTs; ctrl.dtFixed = TimestepSize; ctrl.Endtime = ctrl.dtFixed * ctrl.NoOfTimesteps; ctrl.MultiStepInit = false; ctrl.TimeSteppingScheme = tsc; ctrl.InterfaceMode = InterfaceMode.Splitting; // run // ------------------------------------------ XdgTimesteppingMain p = new XdgTimesteppingMain(); p.Init(ctrl); p.RunSolverMode(); // evaluate/check // ------------------------------------------ double thres = 5.0e-13; double uA_Err = (double)p.QueryHandler.QueryResults["uA_Err"]; double uB_Err = (double)p.QueryHandler.QueryResults["uB_Err"]; double JmpL2Err = (double)p.QueryHandler.QueryResults["uJmp_Err"]; Console.WriteLine("L2 Error of solution (A/B/jmp): {0}/{1}/{2} (threshold is {3}).", uA_Err, uB_Err, JmpL2Err, thres); Assert.LessOrEqual(uA_Err, thres); double uB_Min = (double)p.QueryHandler.QueryResults["uB_Min"]; double uB_Max = (double)p.QueryHandler.QueryResults["uB_Max"]; Console.WriteLine("Min/Max of uB: {0} / {1}", uB_Min, uB_Max); Assert.GreaterOrEqual(uB_Min, ctrl.uA_Ex(new double[2], 0) * 0.99999); Assert.LessOrEqual(uB_Max, ctrl.uB_Ex(new double[2], 0) * 1.00001); //Assert.LessOrEqual(uB_Err, thres); //Assert.LessOrEqual(JmpL2Err, thres); }
public static void TestConvection_MovingInterface_SingleInitLowOrder_RK_dt023( #if DEBUG [Values(TimeSteppingScheme.RK1u1, TimeSteppingScheme.RK3, TimeSteppingScheme.RK_CrankNic, TimeSteppingScheme.RK_IMEX3)] #else [Values(TimeSteppingScheme.RK1, TimeSteppingScheme.RK1u1, TimeSteppingScheme.RK3, TimeSteppingScheme.RK4, TimeSteppingScheme.RK_ImplicitEuler, TimeSteppingScheme.RK_CrankNic, TimeSteppingScheme.RK_IMEX3)] #endif TimeSteppingScheme tsc, [Values(8)] int NoOfTs ) { TestConvection_MovingInterface_SingleInitLowOrder(tsc, 0.23, NoOfTs); }
public static void TestConvection_MovingInterface_SingleInitLowOrder_BDF_dt023( #if DEBUG [Values(TimeSteppingScheme.ExplicitEuler, TimeSteppingScheme.CrankNicolson, TimeSteppingScheme.BDF2)] #else [Values(TimeSteppingScheme.ExplicitEuler, TimeSteppingScheme.CrankNicolson, TimeSteppingScheme.ImplicitEuler, TimeSteppingScheme.BDF2, TimeSteppingScheme.BDF3, TimeSteppingScheme.BDF4)] #endif TimeSteppingScheme tsc, [Values(8)] int NoOfTs ) { TestConvection_MovingInterface_SingleInitLowOrder(tsc, 0.23, NoOfTs); }
public static void CircleMovementTest_WithSurfaceTension( [Values(LevelSetEvolution.FastMarching, LevelSetEvolution.ExtensionVelocity)] LevelSetEvolution lsEvo, [Values(LevelSetHandling.LieSplitting, LevelSetHandling.Coupled_Once, LevelSetHandling.Coupled_Iterative)] LevelSetHandling lsHandl, [Values(TimeSteppingScheme.CrankNicolson, TimeSteppingScheme.BDF2)] TimeSteppingScheme tsScheme) { var C = PhysicalBasedTestcases.ChannelFlow.CF_LevelSetMovementTest(2, 4, lsEvo, lsHandl, tsScheme); double sigma = 1.0; C.PhysicalParameters.Sigma = sigma; double Pjump = sigma / 0.25; C.InitialValues_Evaluators.Add("Pressure#A", X => Pjump); }
/// <summary> /// /// </summary> //[Test] Deactivated, because failing & to much variations public static void CircleMovementTest( [Values(LevelSetEvolution.FastMarching, LevelSetEvolution.ExtensionVelocity, LevelSetEvolution.ScalarConvection, LevelSetEvolution.Fourier)] LevelSetEvolution lsEvo, [Values(LevelSetHandling.Coupled_Once, LevelSetHandling.LieSplitting, LevelSetHandling.Coupled_Iterative)] LevelSetHandling lsHandl, [Values(TimeSteppingScheme.ImplicitEuler, TimeSteppingScheme.CrankNicolson, TimeSteppingScheme.BDF2)] TimeSteppingScheme tsScheme, [Values(0.25)] double cLength) { Assert.False(lsEvo == LevelSetEvolution.ScalarConvection, "ScalarConvection is not working due to wrong Agglomeration!"); var C = PhysicalBasedTestcases.ChannelFlow.CF_LevelSetMovementTest(2, cLength, lsEvo, lsHandl, tsScheme); using (var solver = new XNSE_SolverMain()) { solver.Init(C); solver.RunSolverMode(); double[] BmQ_RB = solver.ComputeBenchmarkQuantities_RisingBubble(); double err_thrsld = 1e-4; // area double err = Math.Abs(cLength * cLength * Math.PI - BmQ_RB[0]); Assert.Less(err, err_thrsld, "error in area"); Console.WriteLine("error in area = {0}", err); // x-position err = Math.Abs(0.6 - BmQ_RB[1]); Assert.Less(err, err_thrsld, "error in x-position too high"); Console.WriteLine("error in x-position = {0}", err); // y-position err = Math.Abs(0.5 - BmQ_RB[2]); Assert.Less(err, err_thrsld, "error in y-position too high"); Console.WriteLine("error in y-position = {0}", err); // circularity err = Math.Abs(1.0 - BmQ_RB[3]); Assert.Less(err, err_thrsld, "error in circularity too high"); Console.WriteLine("error in circularity = {0}", err); // x-velocity err = Math.Abs(1.0 - BmQ_RB[4]); Assert.Less(err, err_thrsld, "error in x-velocity too high"); Console.WriteLine("error in x-velocity = {0}", err); // y-velocity err = Math.Abs(BmQ_RB[5]); Assert.Less(err, err_thrsld, "error in y-velocity too high"); Console.WriteLine("error in y-velocity = {0}", err); } }
public static void TestConvection_MovingInterface_SingleInitLowOrder( [Values(TimeSteppingScheme.ExplicitEuler, TimeSteppingScheme.CrankNicolson, TimeSteppingScheme.ImplicitEuler, TimeSteppingScheme.BDF2, TimeSteppingScheme.BDF3, TimeSteppingScheme.BDF4, TimeSteppingScheme.RK1, TimeSteppingScheme.RK1u1, TimeSteppingScheme.RK3, TimeSteppingScheme.RK4, TimeSteppingScheme.RK_ImplicitEuler, TimeSteppingScheme.RK_CrankNic, TimeSteppingScheme.RK_IMEX3)] TimeSteppingScheme tsc, [Values(0.2, 0.23)] double TimestepSize, [Values(8)] int NoOfTs ) { // set up // ------------------------------------------ XdgTimesteppingTestControl ctrl = HardCodedControl.Gerade(angle: 0, degree: 0, GridResolutionFactor: 1); ctrl.NoOfTimesteps = NoOfTs; ctrl.dtFixed = TimestepSize; ctrl.Endtime = ctrl.dtFixed * ctrl.NoOfTimesteps; ctrl.MultiStepInit = false; ctrl.TimeSteppingScheme = tsc; ctrl.InterfaceMode = InterfaceMode.MovingInterface; BoSSS.Solution.Application <XdgTimesteppingTestControl> .CommandLineOptions ops = null; //Console.WriteLine("remove me VVVV"); //ops = new BoSSS.Solution.Application<XdgTimesteppingTestControl>.CommandLineOptions() { // delPlt = true, // ImmediatePlotPeriod = 1, // SuperSampling = 5 //}; // run // ------------------------------------------ XdgTimesteppingMain p = new XdgTimesteppingMain(); p.Init(ctrl, ops); p.RunSolverMode(); // evaluate/check // ------------------------------------------ double thres = 5.0e-13; double uA_Err = (double)p.QueryHandler.QueryResults["uA_Err"]; double uB_Err = (double)p.QueryHandler.QueryResults["uB_Err"]; double JmpL2Err = (double)p.QueryHandler.QueryResults["uJmp_Err"]; Console.WriteLine("L2 Error of solution (A/B/jmp): {0}/{1}/{2} (threshold is {3}).", uA_Err, uB_Err, JmpL2Err, thres); Assert.LessOrEqual(uA_Err, thres); Assert.LessOrEqual(uB_Err, thres); Assert.LessOrEqual(JmpL2Err, thres); }
/// <summary> /// Tests the <see cref="BoSSS.Solution.XdgTimestepping.XdgBDFTimestepping"/> /// as well as the <see cref="BoSSS.Solution.XdgTimestepping.XdgRKTimestepping"/> time-stepper at /// polynomial order 0 with single-value init, see <see cref="BoSSS.Solution.XdgTimestepping.XdgBDFTimestepping.SingleInit"/>. /// </summary> public static void TestConvection_MovingInterface_SingleInitLowOrder( TimeSteppingScheme tsc, double TimestepSize, int NoOfTs ) { // set up // ------------------------------------------ XdgTimesteppingTestControl ctrl = HardCodedControl.Gerade(angle: 0, degree: 0, GridResolutionFactor: 1); ctrl.NoOfTimesteps = NoOfTs; ctrl.dtFixed = TimestepSize; ctrl.Endtime = ctrl.dtFixed * ctrl.NoOfTimesteps; ctrl.MultiStepInit = false; ctrl.TimeSteppingScheme = tsc; ctrl.InterfaceMode = InterfaceMode.MovingInterface; // run // ------------------------------------------ XdgTimesteppingMain p = new XdgTimesteppingMain(); p.Init(ctrl); p.RunSolverMode(); // evaluate/check // ------------------------------------------ double thres = 5.0e-13; double uA_Err = (double)p.QueryHandler.QueryResults["uA_Err"]; double uB_Err = (double)p.QueryHandler.QueryResults["uB_Err"]; double JmpL2Err = (double)p.QueryHandler.QueryResults["uJmp_Err"]; Console.WriteLine("L2 Error of solution (A/B/jmp): {0}/{1}/{2} (threshold is {3}).", uA_Err, uB_Err, JmpL2Err, thres); Assert.LessOrEqual(uA_Err, thres); Assert.LessOrEqual(uB_Err, thres); Assert.LessOrEqual(JmpL2Err, thres); }
/// <summary> /// /// </summary> /// <returns></returns> public static XRheology_Control CF_LevelSetMovementTest(int boundarySetup = 2, double characteristicLength = 1.0, LevelSetEvolution lsEvo = LevelSetEvolution.FastMarching, LevelSetHandling lsHandl = LevelSetHandling.Coupled_Once, TimeSteppingScheme tsScheme = TimeSteppingScheme.ImplicitEuler) { int p = 2; int kelem = 16; double cLength = characteristicLength; XRheology_Control C = new XRheology_Control(); // basic database options // ====================== #region db C.DbPath = null; //_DbPath; C.savetodb = C.DbPath != null; C.ProjectName = "XNSE/elementalTest"; C.ProjectDescription = "Two-phase Channel flow for testing the level set movement"; #endregion // DG degrees // ========== #region degrees C.FieldOptions.Add("VelocityX", new FieldOpts() { Degree = p, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("VelocityY", new FieldOpts() { Degree = p, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Pressure", new FieldOpts() { Degree = p - 1, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("PhiDG", new FieldOpts() { SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Phi", new FieldOpts() { Degree = p, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Curvature", new FieldOpts() { Degree = p, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); #endregion // Physical Parameters // =================== #region physics C.PhysicalParameters.rho_A = 1; C.PhysicalParameters.rho_B = 1; C.PhysicalParameters.mu_A = 1; C.PhysicalParameters.mu_B = 1; C.PhysicalParameters.Sigma = 0.0; C.PhysicalParameters.IncludeConvection = true; C.PhysicalParameters.Material = true; #endregion // grid generation // =============== #region grid double L = 2; double H = 1; C.GridFunc = delegate() { double[] Xnodes = GenericBlas.Linspace(0, L, 2 * kelem + 1); double[] Ynodes = GenericBlas.Linspace(0, H, kelem + 1); bool xPeriodic = (boundarySetup == 1) ? true : false; var grd = Grid2D.Cartesian2DGrid(Xnodes, Ynodes, periodicX: xPeriodic); grd.EdgeTagNames.Add(1, "velocity_inlet_lower"); grd.EdgeTagNames.Add(2, "velocity_inlet_upper"); switch (boundarySetup) { case 1: grd.EdgeTagNames.Add(3, "velocity_inlet_left"); grd.EdgeTagNames.Add(4, "pressure_outlet_right"); break; case 2: grd.EdgeTagNames.Add(3, "velocity_inlet_left"); grd.EdgeTagNames.Add(4, "pressure_outlet_right"); break; default: throw new ArgumentException("invalid boundary setup"); } grd.DefineEdgeTags(delegate(double[] X) { byte et = 0; if (Math.Abs(X[1]) <= 1.0e-8) { et = 1; } if (Math.Abs(X[1] - H) <= 1.0e-8) { et = 2; } if (!xPeriodic) { if (Math.Abs(X[0]) <= 1.0e-8) { et = 3; } if (Math.Abs(X[0] - L) <= 1.0e-8) { et = 4; } } return(et); }); return(grd); }; #endregion // Initial Values // ============== #region init Func <double[], double> PhiFunc; switch (boundarySetup) { case 1: { // horizontal interface PhiFunc = (X => ((X[0] - cLength).Pow2()).Sqrt() - cLength / 2); break; } case 2: { // radial interface double[] center = new double[] { L / 4.0, H / 2.0 }; double radius = cLength; PhiFunc = (X => ((X[0] - center[0]).Pow2() + (X[1] - center[1]).Pow2()).Sqrt() - radius); break; } default: PhiFunc = (X => - 1); break; } C.InitialValues_Evaluators.Add("Phi", PhiFunc); double U = 1.0; switch (boundarySetup) { case 1: //C.InitialValues_Evaluators.Add("VelocityY#A", X => U); //C.InitialValues_Evaluators.Add("VelocityY#B", X => U); C.InitialValues_Evaluators.Add("VelocityX#A", X => U); C.InitialValues_Evaluators.Add("VelocityX#B", X => U); break; case 2: C.InitialValues_Evaluators.Add("VelocityX#A", X => U); C.InitialValues_Evaluators.Add("VelocityX#B", X => U); break; default: throw new ArgumentException("invalid boundary setup"); } #endregion // boundary conditions // =================== #region BC switch (boundarySetup) { case 1: //C.AddBoundaryValue("velocity_inlet_lower", "VelocityY#A", X => U); //C.AddBoundaryValue("velocity_inlet_lower", "VelocityY#B", X => U); //C.AddBoundaryValue("velocity_inlet_upper", "VelocityY#A", X => U); //C.AddBoundaryValue("velocity_inlet_upper", "VelocityY#B", X => U); C.AddBoundaryValue("velocity_inlet_lower", "VelocityX#A", X => U); C.AddBoundaryValue("velocity_inlet_lower", "VelocityX#B", X => U); C.AddBoundaryValue("velocity_inlet_upper", "VelocityX#A", X => U); C.AddBoundaryValue("velocity_inlet_upper", "VelocityX#B", X => U); C.AddBoundaryValue("velocity_inlet_left", "VelocityX#A", X => U); C.AddBoundaryValue("velocity_inlet_left", "VelocityX#B", X => U); C.AddBoundaryValue("pressure_outlet_right"); break; case 2: C.AddBoundaryValue("velocity_inlet_lower", "VelocityX#A", X => U); C.AddBoundaryValue("velocity_inlet_lower", "VelocityX#B", X => U); C.AddBoundaryValue("velocity_inlet_upper", "VelocityX#A", X => U); C.AddBoundaryValue("velocity_inlet_upper", "VelocityX#B", X => U); C.AddBoundaryValue("velocity_inlet_left", "VelocityX#A", X => U); C.AddBoundaryValue("velocity_inlet_left", "VelocityX#B", X => U); C.AddBoundaryValue("pressure_outlet_right"); break; default: break; } #endregion // advanced settings for Fourier-Level-Set // ====================== #region Fourier level-set switch (lsEvo) { case LevelSetEvolution.Fourier: { switch (boundarySetup) { case 1: { throw new ArgumentException("Fourier Level-Set not implemented in Line Movement Test"); } case 2: { int numSp = 640; double[] FourierP = new double[numSp]; double[] samplP = new double[numSp]; double[] center = new double[] { L / 4.0, H / 2.0 }; double radius = cLength; for (int sp = 0; sp < numSp; sp++) { FourierP[sp] = sp * (2 * Math.PI / (double)numSp); samplP[sp] = radius; } C.FourierLevSetControl = new FourierLevSetControl(FourierType.Polar, 2 * Math.PI, FourierP, samplP, 1.0 / (double)kelem) { center = center, FourierEvolve = Fourier_Evolution.MaterialPoints, centerMove = CenterMovement.Reconstructed, }; C.AdvancedDiscretizationOptions.SST_isotropicMode = SurfaceStressTensor_IsotropicMode.Curvature_Fourier; break; } default: break; } break; } default: break; } #endregion // misc. solver options // ==================== #region solver C.ComputeEnergy = false; C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib; C.LinearSolver.NoOfMultigridLevels = 1; C.NonLinearSolver.MaxSolverIterations = 50; C.LinearSolver.MaxSolverIterations = 50; C.NonLinearSolver.MinSolverIterations = 4; C.LinearSolver.MinSolverIterations = 4; //C.Solver_MaxIterations = 50; C.NonLinearSolver.ConvergenceCriterion = 1e-8; C.LinearSolver.ConvergenceCriterion = 1e-8; //C.Solver_ConvergenceCriterion = 1e-8; C.LevelSet_ConvergenceCriterion = 1e-6; C.LSContiProjectionMethod = Solution.LevelSetTools.ContinuityProjectionOption.ConstrainedDG; C.Option_LevelSetEvolution = lsEvo; C.AdvancedDiscretizationOptions.FilterConfiguration = CurvatureAlgorithms.FilterConfiguration.NoFilter; C.AdvancedDiscretizationOptions.SST_isotropicMode = Solution.XNSECommon.SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine; #endregion // Timestepping // ============ #region time C.TimesteppingMode = AppControl._TimesteppingMode.Transient; C.Timestepper_LevelSetHandling = lsHandl; C.TimeSteppingScheme = tsScheme; double dt = 1e-2; C.dtMax = dt; C.dtMin = dt; C.Endtime = 1000; C.NoOfTimesteps = 10; C.saveperiod = 1; #endregion return(C); }
/// <summary> /// /// </summary> /// <returns></returns> public static XNSE_Control CF_LevelSetRotationTest(int boundarySetup = 1, double characteristicLength = 1.0, LevelSetEvolution lsEvo = LevelSetEvolution.FastMarching, LevelSetHandling lsHandl = LevelSetHandling.Coupled_Once, TimeSteppingScheme tsScheme = TimeSteppingScheme.ImplicitEuler) { int p = 2; int kelem = 16; double cLength = characteristicLength; XNSE_Control C = new XNSE_Control(); // basic database options // ====================== #region db C.DbPath = null; //_DbPath; C.savetodb = C.DbPath != null; C.ProjectName = "XNSE/elementalTest"; C.ProjectDescription = "Two-phase flow for testing the level set movement in solid body rotation"; #endregion // DG degrees // ========== #region degrees C.FieldOptions.Add("VelocityX", new FieldOpts() { Degree = p, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("VelocityY", new FieldOpts() { Degree = p, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Pressure", new FieldOpts() { Degree = p - 1, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("PhiDG", new FieldOpts() { SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Phi", new FieldOpts() { Degree = p, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Curvature", new FieldOpts() { Degree = p, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); #endregion // Physical Parameters // =================== #region physics C.PhysicalParameters.rho_A = 1; C.PhysicalParameters.rho_B = 1; C.PhysicalParameters.mu_A = 1; C.PhysicalParameters.mu_B = 1; C.PhysicalParameters.Sigma = 0.0; C.PhysicalParameters.IncludeConvection = true; C.PhysicalParameters.Material = true; #endregion // grid generation // =============== #region grid double L = 1; double H = 1; C.GridFunc = delegate() { double[] Xnodes = GenericBlas.Linspace(-L / 2, L / 2, kelem + 1); double[] Ynodes = GenericBlas.Linspace(-H / 2, H / 2, kelem + 1); var grd = Grid2D.Cartesian2DGrid(Xnodes, Ynodes, periodicX: false); grd.EdgeTagNames.Add(1, "velocity_inlet_lower"); grd.EdgeTagNames.Add(2, "velocity_inlet_upper"); grd.EdgeTagNames.Add(3, "velocity_inlet_left"); grd.EdgeTagNames.Add(4, "velocity_inlet_right"); grd.DefineEdgeTags(delegate(double[] X) { byte et = 0; if (Math.Abs(X[1] + H / 2) <= 1.0e-8) { et = 1; } if (Math.Abs(X[1] - H / 2) <= 1.0e-8) { et = 2; } if (Math.Abs(X[0] + L / 2) <= 1.0e-8) { et = 3; } if (Math.Abs(X[0] - L / 2) <= 1.0e-8) { et = 4; } return(et); }); return(grd); }; #endregion // Initial Values // ============== #region init Func <double[], double> PhiFunc; switch (boundarySetup) { case 1: { // elliptoid double[] center = new double[] { 0.15, 0.0 }; double[] shape = new double[] { 1, 0.36 }; double radius = cLength; PhiFunc = (X => ((X[0] - center[0]).Pow2() / shape[0] + (X[1] - center[1]).Pow2() / shape[1]).Sqrt() - radius); break; } case 2: { // slotted disk double[] xCutout = new double[] { -0.1, 0.1 }; double yCutout = -0.1; double radius = cLength; ZalesaksDisk disk = new ZalesaksDisk(xCutout, yCutout, radius); PhiFunc = (X => disk.SignedDistanceLevelSet(X)); break; } default: PhiFunc = (X => - 1); break; } C.InitialValues_Evaluators.Add("Phi", PhiFunc); C.InitialValues_Evaluators.Add("VelocityX#A", X => - X[1]); C.InitialValues_Evaluators.Add("VelocityX#B", X => - X[1]); C.InitialValues_Evaluators.Add("VelocityY#A", X => X[0]); C.InitialValues_Evaluators.Add("VelocityY#B", X => X[0]); #endregion // boundary conditions // =================== #region BC C.AddBoundaryValue("velocity_inlet_lower", "VelocityX#A", X => - X[1]); C.AddBoundaryValue("velocity_inlet_lower", "VelocityX#B", X => - X[1]); C.AddBoundaryValue("velocity_inlet_upper", "VelocityX#A", X => - X[1]); C.AddBoundaryValue("velocity_inlet_upper", "VelocityX#B", X => - X[1]); C.AddBoundaryValue("velocity_inlet_left", "VelocityX#A", X => - X[1]); C.AddBoundaryValue("velocity_inlet_left", "VelocityX#B", X => - X[1]); C.AddBoundaryValue("velocity_inlet_right", "VelocityX#A", X => - X[1]); C.AddBoundaryValue("velocity_inlet_right", "VelocityX#B", X => - X[1]); C.AddBoundaryValue("velocity_inlet_lower", "VelocityY#A", X => X[0]); C.AddBoundaryValue("velocity_inlet_lower", "VelocityY#B", X => X[0]); C.AddBoundaryValue("velocity_inlet_upper", "VelocityY#A", X => X[0]); C.AddBoundaryValue("velocity_inlet_upper", "VelocityY#B", X => X[0]); C.AddBoundaryValue("velocity_inlet_left", "VelocityY#A", X => X[0]); C.AddBoundaryValue("velocity_inlet_left", "VelocityY#B", X => X[0]); C.AddBoundaryValue("velocity_inlet_right", "VelocityY#A", X => X[0]); C.AddBoundaryValue("velocity_inlet_right", "VelocityY#B", X => X[0]); #endregion // advanced settings for Fourier-Level-Set // ====================== #region Fourier level-set switch (lsEvo) { case LevelSetEvolution.Fourier: { switch (boundarySetup) { case 1: { int numSp = 640; double[] FourierP = new double[numSp]; double[] samplP = new double[numSp]; double[] center = new double[] { 0.15, 0.0 }; double radius = cLength; for (int sp = 0; sp < numSp; sp++) { FourierP[sp] = sp * (2 * Math.PI / (double)numSp); samplP[sp] = radius / (Math.Cos(FourierP[sp]).Pow2() + Math.Sin(FourierP[sp]).Pow2() / 0.36).Sqrt(); } C.FourierLevSetControl = new FourierLevSetControl(FourierType.Polar, 2 * Math.PI, FourierP, samplP, 1.0 / (double)kelem) { center = center, FourierEvolve = Fourier_Evolution.MaterialPoints, centerMove = CenterMovement.Reconstructed, PeriodicFunc = (X => radius / (Math.Cos(X).Pow2() + Math.Sin(X).Pow2() / 0.36).Sqrt()) }; C.AdvancedDiscretizationOptions.SST_isotropicMode = SurfaceStressTensor_IsotropicMode.Curvature_Fourier; break; } case 2: { throw new ArgumentException("Fourier Level-Set is not suitable for Slotted Disk"); } default: break; } break; } default: break; } #endregion // misc. solver options // ==================== #region solver C.ComputeEnergyProperties = false; C.LinearSolver.NoOfMultigridLevels = 1; C.NonLinearSolver.MaxSolverIterations = 50; C.LinearSolver.MaxSolverIterations = 50; C.NonLinearSolver.MinSolverIterations = 4; C.LinearSolver.MinSolverIterations = 4; //C.Solver_MaxIterations = 50; C.NonLinearSolver.ConvergenceCriterion = 1e-8; C.LinearSolver.ConvergenceCriterion = 1e-8; //C.Solver_ConvergenceCriterion = 1e-8; C.LevelSet_ConvergenceCriterion = 1e-6; C.LSContiProjectionMethod = Solution.LevelSetTools.ContinuityProjectionOption.ConstrainedDG; C.Option_LevelSetEvolution = lsEvo; C.AdvancedDiscretizationOptions.FilterConfiguration = CurvatureAlgorithms.FilterConfiguration.NoFilter; C.AdvancedDiscretizationOptions.SST_isotropicMode = Solution.XNSECommon.SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine; #endregion // Timestepping // ============ #region time C.TimesteppingMode = AppControl._TimesteppingMode.Transient; C.Timestepper_LevelSetHandling = lsHandl; C.TimeSteppingScheme = tsScheme; double dt = 1e-2; C.dtMax = dt; C.dtMin = dt; C.Endtime = 1000; C.NoOfTimesteps = 10; C.saveperiod = 1; #endregion return(C); }