예제 #1
0
        // ==========================
        // 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);
            }
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
 /// <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();
     }
 }
예제 #4
0
        /// <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);
        }
예제 #5
0
파일: TestProgram.cs 프로젝트: xyuan/BoSSS
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        /// <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);
            }
        }
예제 #10
0
        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);
        }
예제 #11
0
        /// <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);
        }
예제 #12
0
        /// <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);
        }
예제 #13
0
        /// <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);
        }