/// <summary>
        /// As implemented for performance measurements in handbook
        /// </summary>
        /// <param name="_DbPath"></param>
        /// <param name="k"></param>
        /// <param name="cells_x"></param>
        /// <param name="cells_yz"></param>
        /// <param name="only_channel"></param>
        /// <param name="pardiso"></param>
        /// <param name="no_p"></param>
        /// <param name="no_it"></param>
        /// <param name="restart"></param>
        /// <param name="load_Grid"></param>
        /// <param name="_GridGuid"></param>
        /// <returns></returns>
        static public IBM_Control SphereFlow_BWS(string _DbPath = null, int k = 3, int cells_x = 128, int cells_yz = 32, bool only_channel = false, bool pardiso = true, int no_p = 1, int no_it = 1, bool restart = false, bool load_Grid = false, string _GridGuid = null)
        {
            IBM_Control C = new IBM_Control();

            C.OperatorMatrixAnalysis = false;
            //C.CutCellQuadratureType = Foundation.XDG.XQuadFactoryHelper.MomentFittingVariants.Saye;

            // basic database options
            // ======================
            //C.DbPath = _DbPath;


            C.DbPath = @"G:\test_db";
            //C.DbPath = @"\\dc1\userspace\krause\BoSSS_DBs\Bug";
            //C.DbPath = @"/home/ws35kire/test_db/";

            C.savetodb = C.DbPath != null;
            //string restartSession = "727da287-1b6a-463e-b7c9-7cc19093b5b3";
            //string restartGrid = "3f8f3445-46f1-47ed-ac0e-8f0260f64d8f";

            //C.DynamicLoadBalancing_Period = 1;
            //C.DynamicLoadBalancing_CellCostEstimatorFactories.Add(delegate (IApplication app, int noOfPerformanceClasses) {
            //    Console.WriteLine("i was called");
            //    int[] map = new int[] { 1, 5, 100 };
            //    return new StaticCellCostEstimator(map);
            //});

            C.GridPartType = GridPartType.none;
            C.SetDGdegree(1);
            C.DynamicLoadBalancing_Period = 1;

            // Assign correct names

            if (pardiso)
            {
                if (only_channel)
                {
                    C.SessionName = "Channel_Pardiso_k" + k + "_" + cells_x + "x" + cells_yz + "x" + cells_yz + "_no_p" + no_p + "_run" + no_it;
                }
                else
                {
                    C.SessionName = "Sphere_Pardiso_k" + k + cells_x + "x" + cells_yz + "x" + cells_yz + "_no_p" + no_p + "_run" + no_it;
                }
            }
            else
            {
                if (only_channel)
                {
                    C.SessionName = "Channel_Mumps_k" + k + cells_x + "x" + cells_yz + "x" + cells_yz + "_no_p" + no_p + "_run" + no_it;
                }
                else
                {
                    C.SessionName = "Sphere_Mumps_k" + k + cells_x + "x" + cells_yz + "x" + cells_yz + "_no_p" + no_p + "_run" + no_it;
                }
            }
            C.saveperiod = 1;
            //C.SessionName = "Sphere_k" + k + "_h" + h+"Re100";
            C.ProjectName        = "Sphere3D_Stokes";
            C.ProjectDescription = "Sphere_k" + k + cells_x + "x" + cells_yz + "x" + cells_yz;
            C.Tags.Add("with immersed boundary method");
            C.Tags.Add("Pardiso " + pardiso);
            C.Tags.Add("only channel " + only_channel);
            C.Tags.Add("k " + k);
            C.Tags.Add("no_p" + no_p);
            C.Tags.Add("run " + no_it);
            C.Tags.Add("cells_x " + cells_x);
            C.Tags.Add("cells_yz " + cells_yz);
            C.Tags.Add("restart " + restart);

            //// Create Fields
            //C.FieldOptions.Add("VelocityX", new FieldOpts() {
            //    Degree = k,
            //    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            //});
            //C.FieldOptions.Add("VelocityY", new FieldOpts() {
            //    Degree = k,
            //    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            //});
            //C.FieldOptions.Add("VelocityZ", new FieldOpts() {
            //    Degree = k,
            //    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            //});
            //C.FieldOptions.Add("Pressure", new FieldOpts() {
            //    Degree = k - 1,
            //    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            //});
            //C.FieldOptions.Add("PhiDG", new FieldOpts() {
            //    Degree = 2,
            //    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            //});
            //C.FieldOptions.Add("Phi", new FieldOpts() {
            //    Degree = 2,
            //    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            //});

            //if (restart)
            //{
            //    C.RestartInfo = new Tuple<Guid, TimestepNumber>(new Guid(restartSession), -1);
            //    C.GridGuid = new Guid(restartGrid);
            //}
            // Load Grid
            if (!restart)
            {
                if (load_Grid == true)
                {
                    Console.WriteLine("...loading grid");
                    C.GridGuid = new Guid(_GridGuid);
                }
                else
                {
                    #region Creates grid () and sets BC
                    //// Create Grid
                    Console.WriteLine("...generating grid");
                    C.GridFunc = delegate {
                        // x-direction
                        var _xNodes = GenericBlas.Linspace(-0.5, 3, cells_x + 1);

                        // y-direction
                        var _yNodes = GenericBlas.Linspace(-0.5, 0.5, cells_yz + 1);

                        // z-direction
                        var _zNodes = GenericBlas.Linspace(-0.5, 0.5, cells_yz + 1);

                        // Cut Out
                        var grd = Grid3D.Cartesian3DGrid(_xNodes, _yNodes, _zNodes, CellType.Cube_Linear, false, false, false);

                        grd.EdgeTagNames.Add(1, "Velocity_inlet");
                        grd.EdgeTagNames.Add(2, "Wall");
                        grd.EdgeTagNames.Add(3, "Pressure_Outlet");

                        grd.DefineEdgeTags(delegate(double[] _X) {
                            var X    = _X;
                            double x = X[0];
                            double y = X[1];
                            double z = X[2];

                            if (Math.Abs(x - (-0.5)) < 1.0e-6)
                            {
                                // inlet
                                return(1);
                            }

                            if (Math.Abs(x - (3)) < 1.0e-6)
                            {
                                // outlet
                                return(3);
                            }

                            if (Math.Abs(y - (-0.5)) < 1.0e-6)
                            {
                                // left
                                return(2);
                            }

                            if (Math.Abs(y - (0.5)) < 1.0e-6)
                            {
                                // right
                                return(2);
                            }

                            if (Math.Abs(z - (-0.5)) < 1.0e-6)
                            {
                                // top left
                                return(2);
                            }

                            if (Math.Abs(z - (0.5)) < 1.0e-6)
                            {
                                // top right
                                return(2);
                            }

                            throw new ArgumentOutOfRangeException();
                        });

                        return(grd);
                    };
                }
                #endregion

                //// Create Grid with HANGING NODES
                //Console.WriteLine("...generating grid");
                //C.GridFunc = delegate {

                //    // Box1
                //    var box1_p1 = new double[3] { -10, -10, -10 };
                //    var box1_p2 = new double[3] { 30, 10, 10 };
                //    var box1 = new GridCommons.GridBox(box1_p1, box1_p2,10,5,5);

                //    // Box2
                //    var box2_p1 = new double[3] { 0, -5, -5 };
                //    var box2_p2 = new double[3] { 20, 5, 5 };
                //    var box2 = new GridCommons.GridBox(box2_p1, box2_p2, 10, 6, 6);

                //    // Cut Out
                //    var grd = Grid3D.HangingNodes3D(false, true, true, box1, box2);

                //    grd.EdgeTagNames.Add(1, "Velocity_inlet");
                //    grd.EdgeTagNames.Add(2, "Pressure_Outlet");
                //    grd.EdgeTagNames.Add(3, "Wall");

                //    grd.DefineEdgeTags(delegate (double[] _X) {
                //        var X = _X;
                //        double x = X[0];
                //        double y = X[1];
                //        double z = X[2];

                //        if (Math.Abs(x - (-10)) < 1.0e-6)
                //            // inlet
                //            return 1;

                //        if (Math.Abs(x - (30)) < 1.0e-6)
                //            // outlet
                //            return 2;

                //        if (Math.Abs(y - (-10)) < 1.0e-6)
                //            // left
                //            return 1;

                //        if (Math.Abs(y - (10)) < 1.0e-6)
                //            // right
                //            return 1;

                //        if (Math.Abs(z - (-10)) < 1.0e-6)
                //            // top left
                //            return 1;

                //        if (Math.Abs(z - (10)) < 1.0e-6)
                //            // top right
                //            return 1;

                //        throw new ArgumentOutOfRangeException();
                //    });

                //    Console.WriteLine("Cells:    {0}", grd.NumberOfCells);

                //    return grd;
                //};

                #region Creates grid (17710 Cells) and sets BC
                //// Create Grid
                //Console.WriteLine("...generating grid");
                //C.GridFunc = delegate {

                //    // x-direction
                //    var _xNodes1 = Grid1D.ExponentialSpaceing(-9.5, -3, 11, 0.98);
                //    _xNodes1 = _xNodes1.GetSubVector(0, (_xNodes1.Length - 1));
                //    var _xNodes2 = Grid1D.ExponentialSpaceing(-3, -1, 9, 0.95);
                //    _xNodes2 = _xNodes2.GetSubVector(0, (_xNodes2.Length - 1));
                //    var _xNodes3 = Grid1D.ExponentialSpaceing(-1, 0, 8, 1);
                //    _xNodes3 = _xNodes3.GetSubVector(0, (_xNodes3.Length - 1));
                //    var _xNodes4 = Grid1D.ExponentialSpaceing(0, 2, 9, 1.05);
                //    _xNodes4 = _xNodes4.GetSubVector(0, (_xNodes4.Length - 1));
                //    var _xNodes5 = Grid1D.ExponentialSpaceing(2, 8.5, 16, 1.02);
                //    _xNodes5 = _xNodes5.GetSubVector(0, (_xNodes5.Length - 1));
                //    var _xNodes6 = Grid1D.ExponentialSpaceing(8.5, 12.5, 5, 1);

                //    var _xNodes = ArrayTools.Cat(_xNodes1, _xNodes2, _xNodes3, _xNodes4, _xNodes5, _xNodes6);

                //    // y-direction
                //    var _yNodes1 = Grid1D.ExponentialSpaceing(-9, -2.5, 8, 0.91);
                //    _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1));
                //    var _yNodes2 = Grid1D.ExponentialSpaceing(-2.5, -0.5, 8, 0.95);
                //    _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1));
                //    var _yNodes3 = Grid1D.ExponentialSpaceing(-0.5, 0.5, 8, 1.0);
                //    _yNodes3 = _yNodes3.GetSubVector(0, (_yNodes3.Length - 1));
                //    var _yNodes4 = Grid1D.ExponentialSpaceing(0.5, 2.5, 8, 1.05);
                //    _yNodes4 = _yNodes4.GetSubVector(0, (_yNodes4.Length - 1));
                //    var _yNodes5 = Grid1D.ExponentialSpaceing(2.5, 9, 8, 1.1);

                //    var _yNodes = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3, _yNodes4, _yNodes5);

                //    // z-direction
                //    var _zNodes = GenericBlas.Linspace(-3, 3, 11);

                //    // Cut Out
                //    double[] CutOutPoint1 = new double[3];
                //    CutOutPoint1[0] = -1;
                //    CutOutPoint1[1] = -0.5;
                //    CutOutPoint1[2] = -3;

                //    double[] CutOutPoint2 = new double[3];
                //    CutOutPoint2[0] = 0;
                //    CutOutPoint2[1] = 0.5;
                //    CutOutPoint2[2] = 3;

                //    var CutOut = new BoundingBox(3);
                //    CutOut.AddPoint(CutOutPoint1);
                //    CutOut.AddPoint(CutOutPoint2);

                //    var grd = Grid3D.Cartesian3DGrid(_xNodes, _yNodes, _zNodes, false, false, true, CellType.Cube_Linear, CutOut);

                //    grd.EdgeTagNames.Add(1, "Velocity_inlet");
                //    grd.EdgeTagNames.Add(2, "Pressure_Outlet");
                //    grd.EdgeTagNames.Add(3, "Wall");

                //    grd.DefineEdgeTags(delegate(double[] _X) {
                //        var X = _X;
                //        double x = X[0];
                //        double y = X[1];
                //        double z = X[2];

                //        if (Math.Abs(x - (-9.5)) < 1.0e-6)
                //            // inlet
                //            return 1;

                //        if (Math.Abs(x - (12.5)) < 1.0e-6)
                //            // outlet
                //            return 2;

                //        if (Math.Abs(z - (-3)) < 1.0e-6)
                //            // left
                //            return 2;

                //        if (Math.Abs(z - (3)) < 1.0e-6)
                //            // right
                //            return 2;

                //        if (Math.Abs(x - (-1)) < 1.0e-6)
                //            // Cube front
                //            return 3;

                //        if (Math.Abs(x - (0)) < 1.0e-6)
                //            // cube back
                //            return 3;

                //        if (Math.Abs(y - (-0.5)) < 1.0e-6)
                //            // cube left
                //            return 3;

                //        if (Math.Abs(y - (0.5)) < 1.0e-6)
                //            // cube right
                //            return 3;

                //        throw new ArgumentOutOfRangeException();
                //    });

                //    return grd;
                //};
                #endregion

                // Set Initial Conditions
                C.InitialValues_Evaluators.Add("VelocityX", X => 0);
                C.InitialValues_Evaluators.Add("VelocityY", X => 0);
                C.InitialValues_Evaluators.Add("VelocityZ", X => 0);
                C.InitialValues_Evaluators.Add("Pressure", X => 0);

                if (only_channel)
                {
                    C.InitialValues_Evaluators.Add("Phi", X => - 1);
                }
                else
                {
                    C.InitialValues_Evaluators.Add("Phi", X => - (X[0]).Pow2() + -(X[1]).Pow2() + -(X[2]).Pow2() + C.particleRadius.Pow2());
                }
            }
            Console.WriteLine("...starting calculation of Sphere3D");

            // Initial Solution

            // Physical values
            C.particleRadius           = 0.1;
            C.PhysicalParameters.rho_A = 1;
            C.PhysicalParameters.mu_A  = 0.0001 / 1;

            // Boundary conditions
            C.AddBoundaryValue("Velocity_inlet", "VelocityX", (X, t) => 100 - 400 * (X[2] * X[2]) - 400 * (X[1] * X[1]));
            C.AddBoundaryValue("Velocity_inlet", "VelocityY", (X, t) => 0);
            C.AddBoundaryValue("Velocity_inlet", "VelocityZ", (X, t) => 0);
            C.AddBoundaryValue("Wall");
            C.AddBoundaryValue("Pressure_Outlet");


            // misc. solver options
            // ====================
            C.PhysicalParameters.IncludeConvection        = false;
            C.AdvancedDiscretizationOptions.PenaltySafety = 4;
            C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2;
            C.LevelSetSmoothing                   = false;
            C.LinearSolver.MaxKrylovDim           = 30;
            C.LinearSolver.MaxSolverIterations    = 50;
            C.NonLinearSolver.MaxSolverIterations = 50;
            C.NonLinearSolver.SolverCode          = NonLinearSolverCode.NewtonGMRES;
            //C.LinearSolver.SolverCode = LinearSolverCode.exp_schwarz_Kcycle_directcoarse;
            //C.LinearSolver.SolverCode = LinearSolverCode.exp_gmres_levelpmg;
            C.LinearSolver.verbose    = true;
            C.NonLinearSolver.verbose = true;
            C.NonLinearSolver.PrecondSolver.verbose = true;
            //C.NonLinearSolver.ConvergenceCriterion = 1E-10;
            C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite;

            // Timestepping
            // ============

            //if (pardiso) {
            //    C.LinearSolver.SolverCode = LinearSolverCode.classic_pardiso;
            //} else {
            //    C.LinearSolver.SolverCode = LinearSolverCode.classic_mumps;
            //}

            //C.whichSolver = DirectSolver._whichSolver.MUMPS;
            C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.BDF2;
            double dt = 0.01;
            C.dtFixed = dt;
            //C.dtMax = dt;
            //C.dtMin = 0;
            //C.Endtime = 1000;
            //C.NoOfTimesteps = 10;
            C.NoOfTimesteps = 100;
            C.LinearSolver.NoOfMultigridLevels = 3;

            return(C);
        }
Exemple #2
0
        static public IBM_Control PrecTest3DChannel(int k, int cells_x, int cells_yz)
        {
            IBM_Control C = new IBM_Control();

            // basic database options
            // ======================
            C.savetodb = false;
            //C.DbPath = @"/home/oe11okuz/BoSSS_DB/Lichtenberg_DB";
            //C.DbPath = @"P:\BoSSS_DBs\Bug";

            //string restartSession = "727da287-1b6a-463e-b7c9-7cc19093b5b3";
            //string restartGrid = "3f8f3445-46f1-47ed-ac0e-8f0260f64d8f";

            //C.DynamicLoadBalancing_Period = 1;
            //C.DynamicLoadBalancing_CellCostEstimatorFactories.Add(delegate (IApplication app, int noOfPerformanceClasses) {
            //    Console.WriteLine("i was called");
            //    int[] map = new int[] { 1, 5, 100 };
            //    return new StaticCellCostEstimator(map);
            //});
            C.DynamicLoadBalancing_RedistributeAtStartup = false;

            //c.DynamicLoadBalancing_CellClassifier = new IndifferentCellClassifier();
            C.DynamicLoadBalancing_CellCostEstimatorFactories.Add((p, i) => new StaticCellCostEstimator(new[] { 1 }));
            //c.DynamicLoadBalancing_CellCostEstimatorFactories.Add((p, i) => new StaticCellCostEstimator(new[] { 10, 1 }));
            //c.DynamicLoadBalancing_CellCostEstimatorFactories.AddRange(ArtificialViscosityCellCostEstimator.GetStaticCostBasedEstimator());
            //c.DynamicLoadBalancing_CellCostEstimatorFactories.AddRange(ArtificialViscosityCellCostEstimator.GetMultiBalanceConstraintsBasedEstimators());

            // Assign correct names
            C.SessionName = "Channel_" + k + "_" + cells_x + "x" + cells_yz;

            C.saveperiod = 1;
            //C.SessionName = "Sphere_k" + k + "_h" + h+"Re100";
            C.ProjectName        = "3DChannel";
            C.ProjectDescription = "Sphere_k" + k + cells_x + "x" + cells_yz + "x" + cells_yz;
            C.Tags.Add("Prec Test");

            // Create Fields
            C.SetDGdegree(k);

            #region Creates grid () and sets BC
            //// Create Grid
            Console.WriteLine("...generating grid");
            C.GridFunc = delegate {
                // x-direction
                var _xNodes = GenericBlas.Linspace(-0.5, 1.5, cells_x + 1);

                // y-direction
                var _yNodes = GenericBlas.Linspace(-0.5, 0.5, cells_yz + 1);

                // z-direction
                var _zNodes = GenericBlas.Linspace(-0.5, 0.5, cells_yz + 1);

                // Cut Out
                var grd = Grid3D.Cartesian3DGrid(_xNodes, _yNodes, _zNodes, CellType.Cube_Linear, false, true, false);

                grd.EdgeTagNames.Add(1, "Velocity_inlet");
                grd.EdgeTagNames.Add(2, "Wall");
                grd.EdgeTagNames.Add(3, "Pressure_Outlet");

                grd.DefineEdgeTags(delegate(double[] _X) {
                    var X    = _X;
                    double x = X[0];
                    double y = X[1];
                    double z = X[2];

                    if (Math.Abs(x - (-0.5)) < 1.0e-6)
                    {
                        // inlet
                        return(1);
                    }

                    if (Math.Abs(x - (1.5)) < 1.0e-6)
                    {
                        // outlet
                        return(3);
                    }

                    if (Math.Abs(y - (-0.5)) < 1.0e-6)
                    {
                        // left
                        return(2);
                    }

                    if (Math.Abs(y - (0.5)) < 1.0e-6)
                    {
                        // right
                        return(2);
                    }

                    if (Math.Abs(z - (-0.5)) < 1.0e-6)
                    {
                        // top left
                        return(2);
                    }

                    if (Math.Abs(z - (0.5)) < 1.0e-6)
                    {
                        // top right
                        return(2);
                    }

                    throw new ArgumentOutOfRangeException();
                });

                return(grd);
            };

            #endregion



            // Set Initial Conditions
            C.InitialValues_Evaluators.Add("VelocityX", X => 1 - 4 * (X[2] * X[2]));
            C.InitialValues_Evaluators.Add("VelocityY", X => 0);
            C.InitialValues_Evaluators.Add("VelocityZ", X => 0);
            C.InitialValues_Evaluators.Add("Pressure", X => 0);

            // Because its only channeö
            C.InitialValues_Evaluators.Add("Phi", X => - 1);

            Console.WriteLine("...starting calculation of Preconditioning test with 3D Channel");

            // Physical values
            C.PhysicalParameters.rho_A = 1;
            C.PhysicalParameters.mu_A  = 1.0 / 10.0;

            // Boundary conditions
            C.AddBoundaryValue("Velocity_inlet", "VelocityX", (X, t) => 1 - 4 * (X[2] * X[2]));
            C.AddBoundaryValue("Velocity_inlet", "VelocityY", (X, t) => 0);
            C.AddBoundaryValue("Wall");
            C.AddBoundaryValue("Pressure_Outlet");


            // misc. solver options
            // ====================
            C.PhysicalParameters.IncludeConvection        = true;
            C.AdvancedDiscretizationOptions.PenaltySafety = 4;
            C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2;
            C.LevelSetSmoothing                    = false;
            C.LinearSolver.MaxKrylovDim            = 1000;
            C.LinearSolver.MaxSolverIterations     = 1;
            C.NonLinearSolver.MaxSolverIterations  = 1;
            C.LinearSolver.ConvergenceCriterion    = 1E-5;
            C.NonLinearSolver.ConvergenceCriterion = 1E-5;
            C.VelocityBlockPrecondMode             = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite;

            // Solver configuration
            C.NonLinearSolver.SolverCode = NonLinearSolverCode.Newton; // Newton GMRES will be executed if a GMRES linsolver is chosen
            C.LinearSolver.SolverCode    = LinearSolverCode.classic_mumps;


            // Timestepping
            // ============
            C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.BDF2;
            double dt = 1E20;
            C.dtFixed       = dt;
            C.dtMax         = dt;
            C.dtMin         = dt;
            C.Endtime       = 10000000;
            C.NoOfTimesteps = 1;
            C.LinearSolver.NoOfMultigridLevels = 7;

            return(C);
        }
        static public IBM_Control ChannelFlow(int k = 2, bool periodic = false, bool pardiso = false, int xCells = 10, int yCells = 10)
        {
            IBM_Control C = new IBM_Control();

            // Solver Options
            C.NoOfTimesteps = 100;
            C.LinearSolver.MaxSolverIterations    = 50;
            C.NonLinearSolver.MaxSolverIterations = 50;
            C.savetodb    = false;
            C.ProjectName = "ChannelFlow";

            // Calculate Navier-Stokes?
            C.PhysicalParameters.IncludeConvection = true;

            // Timestepper
            C.FixedStreamwisePeriodicBC = periodic;
            C.SrcPressureGrad           = new double[] { -0.1, 0 };

            if (pardiso)
            {
                C.LinearSolver.SolverCode = LinearSolverCode.classic_pardiso;
            }
            else
            {
                C.LinearSolver.SolverCode = LinearSolverCode.classic_mumps;
            }
            C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.ImplicitEuler;
            double dt = 1E20;

            C.dtMax         = dt;
            C.dtMin         = dt;
            C.Endtime       = 60;
            C.NoOfTimesteps = 1;

            // Physical values
            C.PhysicalParameters.rho_A = 1;

            // 1/Re
            C.PhysicalParameters.mu_A = 1.0 / 20;


            // Create Fields
            C.SetDGdegree(k);

            // Create Grid
            C.GridFunc = delegate {
                var _xNodes = GenericBlas.Linspace(0, 10, 21);
                var _yNodes = GenericBlas.Linspace(-1, 1, 11);

                var grd = Grid2D.Cartesian2DGrid(_xNodes, _yNodes, Foundation.Grid.RefElements.CellType.Square_Linear, periodicX: periodic);

                if (!periodic)
                {
                    grd.EdgeTagNames.Add(1, "Velocity_inlet");
                    grd.EdgeTagNames.Add(4, "Pressure_Outlet");
                }

                grd.EdgeTagNames.Add(2, "Wall_bottom");
                grd.EdgeTagNames.Add(3, "Wall_top");

                grd.DefineEdgeTags(delegate(double[] _X) {
                    var X    = _X;
                    double x = X[0];
                    double y = X[1];

                    if (Math.Abs(y - (-1)) < 1.0e-6)
                    {
                        // bottom
                        return(2);
                    }

                    if (Math.Abs(y - (+1)) < 1.0e-6)
                    {
                        // top
                        return(3);
                    }

                    if (!periodic)
                    {
                        if (Math.Abs(x - (0)) < 1.0e-6)
                        {
                            // left
                            return(1);
                        }

                        if (Math.Abs(x - (10)) < 1.0e-6)
                        {
                            // right
                            return(4);
                        }
                    }
                    throw new ArgumentOutOfRangeException();
                });

                Console.WriteLine("2D Channel Flow");

                return(grd);
            };


            Func <double[], double, double> VelocityX = (X, t) => (1 - (X[1] * X[1]));
            Func <double[], double, double> VelocityY = (X, t) => 0;
            Func <double[], double, double> Pressure  = (X, t) => 0;


            C.ExSol_Velocity_Evaluator = new Func <double[], double, double>[] { VelocityX, VelocityY };

            //Func<double[], double, double> Velocity = new  Func<double[], double, double>;
            //C.ExSol_Velocity[0] = (X, t) => (1 - (X[1] * X[1]));
            //C.ExSol_Velocity["A"][1] = (X, t) => (1 - (X[1] * X[1]));
            //C.ExSol_Pressure["A"] = (X, t) => 0;

            if (!periodic)
            {
                C.AddBoundaryValue("Velocity_inlet", "VelocityX", X => 1 - X[1] * X[1]);
                C.AddBoundaryValue("Pressure_Outlet");
            }

            C.AddBoundaryValue("Wall_bottom");
            C.AddBoundaryValue("Wall_top");

            // Set Initial Conditions
            C.InitialValues_Evaluators.Add("VelocityX", X => 0);
            C.InitialValues_Evaluators.Add("VelocityY", X => 0);
            C.InitialValues_Evaluators.Add("Phi", X => - 1);

            return(C);
        }