Beispiel #1
0
        /// <summary>
        /// Test using subsonicInlet at the inlet and
        /// supersonicInlet (Dirichlet) at the outlet
        /// </summary>
        /// <returns></returns>
        public static CNSControl[] EulerSubsonicInlet1D()
        {
            CNSControl[] templates = GetTemplates();

            foreach (CNSControl c in templates)
            {
                int divisions = (int)c.Paramstudy_CaseIdentification.Single(t => t.Item1 == "divisions").Item2;

                int noOfCells = (2 << divisions) * 8;
                c.GridFunc = delegate {
                    GridCommons grid = Grid1D.LineGrid(
                        GenericBlas.Linspace(0.0, Math.PI / 2.0 + 0.0, noOfCells + 1));
                    grid.EdgeTagNames.Add(1, "supersonicInlet");
                    grid.EdgeTagNames.Add(2, "subsonicInlet");
                    grid.DefineEdgeTags((Vector x) => Math.Abs(x[0]) < 1e-14 ? (byte)2 : (byte)1);
                    return(grid);
                };
                c.ProjectName += "_subsonicInlet2";

                c.AddBoundaryValue("subsonicInlet", CompressibleVariables.Density, exactDensity);
                c.AddBoundaryValue("subsonicInlet", CNSVariables.Velocity[0], exactVelocity);

                c.AddBoundaryValue("supersonicInlet", CompressibleVariables.Density, exactDensity);
                c.AddBoundaryValue("supersonicInlet", CNSVariables.Velocity[0], exactVelocity);
                c.AddBoundaryValue("supersonicInlet", CNSVariables.Pressure, exactPressure);
            }

            return(templates);
        }
Beispiel #2
0
        /// <summary>
        /// Test using SubsonicPressureInlet at the inlet and
        /// SubsonicOutlet at the outlet. That is, this test case
        /// uses physically correct boundary conditions
        /// </summary>
        /// <returns></returns>
        public static CNSControl[] EulerSubsonicPressureInletAndOutletTest1D()
        {
            CNSControl[] templates = GetTemplates();

            foreach (CNSControl c in templates)
            {
                int divisions = (int)c.Paramstudy_CaseIdentification.Single(t => t.Item1 == "divisions").Item2;

                int noOfCells = (2 << divisions) * 8;
                c.GridFunc = delegate {
                    GridCommons grid = Grid1D.LineGrid(
                        GenericBlas.Linspace(0.0, Math.PI / 2.0 + 0.0, noOfCells + 1));
                    grid.EdgeTagNames.Add(1, "subsonicPressureInlet");
                    grid.EdgeTagNames.Add(2, "subsonicOutlet");
                    grid.DefineEdgeTags((Vector x) => Math.Abs(x[0]) < 1e-14 ? (byte)1 : (byte)2);
                    return(grid);
                };

                c.AddBoundaryValue("subsonicPressureInlet", "p0", totalPressure);
                c.AddBoundaryValue("subsonicPressureInlet", "T0", totalTemperature);

                c.AddBoundaryValue("subsonicOutlet", CNSVariables.Pressure, exactPressure);
            }

            return(templates);
        }
Beispiel #3
0
        /// <summary>
        /// Uses <see cref="SubsonicPressureInlet"/> at the inlet and
        /// <see cref="SupersonicInlet"/> (Dirichlet) at the outlet
        /// </summary>
        /// <returns></returns>
        public static CNSControl[] EulerSubsonicPressureInletTest1D()
        {
            CNSControl[] templates = GetTemplates();

            foreach (CNSControl c in templates)
            {
                int divisions = (int)c.Paramstudy_CaseIdentification.Single(t => t.Item1 == "divisions").Item2;

                int noOfCells = (2 << divisions) * 8;
                c.GridFunc = delegate {
                    GridCommons grid = Grid1D.LineGrid(
                        GenericBlas.Linspace(0.0, Math.PI / 2.0 + 0.0, noOfCells + 1));
                    grid.EdgeTagNames.Add(1, "supersonicInlet");
                    grid.EdgeTagNames.Add(2, "subsonicPressureInlet");
                    grid.DefineEdgeTags(x => Math.Abs(x[0]) < 1e-14 ? (byte)2 : (byte)1);
                    return(grid);
                };
            }

            return(templates);
        }
Beispiel #4
0
        /// <summary>
        /// Test using <see cref="SupersonicInlet"/> (Dirichlet) everywhere
        /// </summary>
        /// <returns></returns>
        public static CNSControl[] EulerSupersonicInlet1D()
        {
            CNSControl[] templates = GetTemplates();

            foreach (CNSControl c in templates)
            {
                int divisions = (int)c.Paramstudy_CaseIdentification.Single(t => t.Item1 == "divisions").Item2;

                int noOfCells = (2 << divisions) * 8;
                c.GridFunc = delegate {
                    GridCommons grid = Grid1D.LineGrid(
                        GenericBlas.Linspace(0.0, Math.PI / 2.0 + 0.0, noOfCells + 1));
                    grid.EdgeTagNames.Add(1, "supersonicInlet");
                    grid.DefineEdgeTags(x => 1);
                    return(grid);
                };
                c.ProjectName += "_supersonicAll";
            }

            return(templates.ToArray());
        }
Beispiel #5
0
        protected override GridCommons CreateOrLoadGrid()
        {
            // Options
            string dataPath     = @"\\fdyprime\userspace\mueller\Jan\waves\";
            string databasePath = @"e:\bosss_db\GridOfTomorrow\";

            noOfCellsX       = 64;
            noOfNodesPerEdge = 4;
            dgDegree         = 6;

            //noOfCellsX = 85;
            //noOfNodesPerEdge = 4;
            //dgDegree = 6;

            Directory.SetCurrentDirectory(dataPath);
            DatabaseInfo database           = new DatabaseInfo(databasePath);
            string       sessionDescription = "Blafasel";

            // Create the grid
            aspectRatio = 4;
            GridCommons grid = Grid2D.Cartesian2DGrid(
                GenericBlas.Linspace(0.0, 1.0, noOfCellsX + 1),
                GenericBlas.Linspace(-1.5, 2.5, aspectRatio * noOfCellsX + 1),
                CellType.Square_Linear,
                periodicX: true,
                periodicY: false);

            grid.EdgeTagNames.Add(1, "subsonicOutlet");
            grid.EdgeTagNames.Add(2, "supersonicInlet");
            grid.DefineEdgeTags(delegate(double[] x) {
                if (x[1] > 0.0)
                {
                    return(2);
                }
                else
                {
                    return(1);
                }
            });
            gridData = new GridData(grid);

            // Read the values
            MultidimensionalArray rho = ReadVariableValues("rho");
            MultidimensionalArray u   = ReadVariableValues("vx1");
            MultidimensionalArray v   = ReadVariableValues("vx2");
            MultidimensionalArray p   = ReadVariableValues("prs");

            // Assemble node set corresponding to the ordering from Matlab
            double[] nodes1D          = GenericBlas.Linspace(-1.0, 1.0, noOfNodesPerEdge);
            int      noOfNodesPerCell = noOfNodesPerEdge * noOfNodesPerEdge;

            double[,] localNodes = new double[noOfNodesPerCell, gridData.SpatialDimension];
            for (int i = 0; i < noOfNodesPerEdge; i++)
            {
                for (int j = 0; j < noOfNodesPerEdge; j++)
                {
                    int localNodeIndex = i * noOfNodesPerEdge + j;
                    localNodes[localNodeIndex, 0] = nodes1D[i];
                    localNodes[localNodeIndex, 1] = nodes1D[j];
                }
            }
            nodeSet = new NodeSet(gridData.Grid.RefElements[0], localNodes);

            // Interpolate
            //SinglePhaseField[] fields = LeastSquaresInterpolation(rho, u, v, p);
            SinglePhaseField[] fields = SpecFEMInterpolation(rho, u, v, p);

            // Save everything
            database.Controller.DBDriver.SaveGrid(grid);

            SessionInfo session = database.Controller.DBDriver.CreateNewSession(database);

            session.Description = sessionDescription;
            session.Save();

            database.Controller.DBDriver.SaveTimestep(
                0.0, 0, session, gridData, fields);

            return(grid);
        }
Beispiel #6
0
        public static IBMControl IBMNACA0012(int MeshPara, int dgDegree, double CFL, double agglomeration, double alpha)
        {
            IBMControl c = new IBMControl();

            // Solver Settings
            c.dtMin         = 0.0;
            c.dtMax         = 1.0;
            c.Endtime       = 1000.0;
            c.CFLFraction   = CFL;
            c.NoOfTimesteps = 200000;

            c.PrintInterval = 10;
            //c.ResidualInterval = 100;
            //c.ResidualLoggerType = ResidualLoggerTypes.ChangeRate | ResidualLoggerTypes.Query;
            //c.ResidualBasedTerminationCriteria.Add("changeRate_L2_abs_rhoE", 1E-8);

            //IBM Settings
            c.LevelSetBoundaryTag     = "AdiabaticSlipWall";
            c.LevelSetQuadratureOrder = 2 * dgDegree + 2;
            c.AgglomerationThreshold  = agglomeration;

            // NEXT STEP: SET THIS BOOL TO FALSE AND JUST USE IN POSITIVE SUB_VOLUME;
            // THEN TRY BOUNDING BOX APPROACH?
            // WHY THE HELL DOES THIS CONFIGURATION FAIL!??!?!?!?
            c.CutCellQuadratureType             = XQuadFactoryHelper.MomentFittingVariants.Classic;
            c.SurfaceHMF_ProjectNodesToLevelSet = false;
            c.SurfaceHMF_RestrictNodes          = true;
            c.SurfaceHMF_UseGaussNodes          = false;
            c.VolumeHMF_NodeCountSafetyFactor   = 3.0;
            c.VolumeHMF_RestrictNodes           = true;
            c.VolumeHMF_UseGaussNodes           = false;

            //Guid restart = new Guid("cd061fe3-3215-483a-8790-f6fd686d6676");
            //c.RestartInfo = new Tuple<Guid, BoSSS.Foundation.IO.TimestepNumber>(restart, -1);

            // Session Settings
            //c.DbPath = @"\\fdyprime\userspace\kraemer-eis\FDY-Cluster\dbe_NACA\";
            c.savetodb           = false;
            c.saveperiod         = 10000;
            c.ProjectName        = "MeshPara:" + MeshPara + "_CFL=" + c.CFLFraction + "_p=" + dgDegree + "_agg=" + c.AgglomerationThreshold + "_alpha=" + alpha + "_HMF=" + c.CutCellQuadratureType;
            c.ProjectDescription = "NACA0012 Steady Test with Ma=0.5";
            c.Tags.Add("NACA0012");
            c.Tags.Add("IBM Test");
            c.Tags.Add("steady");

            // Solver Type
            c.DomainType         = DomainTypes.StaticImmersedBoundary;
            c.ActiveOperators    = Operators.Convection;
            c.ConvectiveFluxType = ConvectiveFluxTypes.OptimizedHLLC;

            // Time-Stepping Settings
            c.ExplicitScheme = ExplicitSchemes.RungeKutta;
            c.ExplicitOrder  = 1;

            //Material Settings
            c.EquationOfState = IdealGas.Air;
            c.MachNumber      = 1.0 / Math.Sqrt(c.EquationOfState.HeatCapacityRatio);

            // Primary CNSVariables
            c.AddVariable(CompressibleVariables.Density, dgDegree);
            c.AddVariable(CompressibleVariables.Momentum.xComponent, dgDegree);
            c.AddVariable(CompressibleVariables.Momentum.yComponent, dgDegree);
            c.AddVariable(CompressibleVariables.Energy, dgDegree);

            c.AddVariable(IBMVariables.LevelSet, 8);

            // Refined Region
            double xBegin = -0.012;
            double xEnd   = 1.01;

            c.GridFunc = delegate {
                int chords = 100;

                int xleft   = -chords;
                int xRight  = chords;
                int yBottom = -chords;
                int yTop    = chords;

                double spacingFactor = 3.95;

                double[] xnodes1 = Grid1D.TanhSpacing(xleft, xBegin, MeshPara + 1, spacingFactor, false);
                double[] xnodes2 = Grid1D.TanhSpacing_DoubleSided(xBegin, xEnd, MeshPara + 1, 2.0);
                double[] xnodes3 = Grid1D.TanhSpacing(xEnd, xRight, MeshPara + 1, spacingFactor, true);

                double[] xComplete = new double[xnodes1.Length + xnodes2.Length + xnodes3.Length - 2];
                for (int i = 0; i < xnodes1.Length; i++)
                {
                    xComplete[i] = xnodes1[i];
                }
                for (int i = 1; i < xnodes2.Length; i++)
                {
                    xComplete[i + xnodes1.Length - 1] = xnodes2[i];
                }
                for (int i = 1; i < xnodes3.Length; i++)
                {
                    xComplete[i + xnodes1.Length + xnodes2.Length - 2] = xnodes3[i];
                }

                double yrefinedTop    = 0.2;
                double yrefinedBottom = -0.2;

                double[] ynodes1 = Grid1D.TanhSpacing(yBottom, yrefinedBottom, MeshPara + 1, spacingFactor, false);
                double[] ynodes2 = GenericBlas.Linspace(yrefinedBottom, yrefinedTop, (int)(0.75 * MeshPara) + 1);
                double[] ynodes3 = Grid1D.TanhSpacing(yrefinedTop, yTop, MeshPara + 1, spacingFactor, true);

                double[] yComplete = new double[ynodes1.Length + ynodes2.Length + ynodes3.Length - 2];
                for (int i = 0; i < ynodes1.Length; i++)
                {
                    yComplete[i] = ynodes1[i];
                }
                for (int i = 1; i < ynodes2.Length; i++)
                {
                    yComplete[i + ynodes1.Length - 1] = ynodes2[i];
                }
                for (int i = 1; i < ynodes3.Length; i++)
                {
                    yComplete[i + ynodes1.Length + ynodes2.Length - 2] = ynodes3[i];
                }

                int numOfCellsX = (xRight - xleft) * MeshPara;
                int numOfCellsY = (yTop - yBottom) * MeshPara;

                GridCommons grid = Grid2D.Cartesian2DGrid(xComplete, yComplete);

                grid.EdgeTagNames.Add(1, "supersonicinlet");
                grid.EdgeTagNames.Add(2, "AdiabaticSlipWall");
                grid.DefineEdgeTags((Vector X) => 1);
                grid.Name = "[" + xleft + "," + xRight + "]x[" + yBottom + "," + yTop + "]_Cells:(" + (xComplete.Length - 1) + "x" + (yComplete.Length - 1) + ")";

                return(grid);
            };

            // Functions
            Func <double[], double, double> rho      = (X, t) => 1.0;
            Func <double[], double, double> u0       = (X, t) => 1.0;
            Func <double[], double, double> u1       = (X, t) => 0.0;
            Func <double[], double, double> pressure = (X, t) => 2.8571428571428;

            Func <double[], double> test = X => 1 - 0.05 * 0.4 / 1.4 * Math.Pow(Math.Exp(1 - X[0] * X[0] - X[1] * X[1]), (1 / 0.4));

            Func <double[], double, double> levelSet = delegate(double[] X, double t) {
                double value = 0.0;

                double radian = alpha * Math.PI / 180;

                double xRotated = 1 + Math.Cos(radian) * (X[0] - 1) - Math.Sin(radian) * (X[1]);
                double yRotated = Math.Sin(radian) * (X[0] - 1) + Math.Cos(radian) * (X[1]);

                double a = 0.6;
                //double b = 0.2969;
                double c1 = 0.126;
                double d  = 0.3516;
                double e  = 0.2843;
                double f  = 0.1036;


                if (yRotated >= 0.0 || (X[0] > 0.562875 && X[1] > 0))
                {
                    //if (yRotated >= 0.0 ){
                    value = Math.Pow((yRotated + a * (c1 * xRotated + d * Math.Pow(xRotated, 2) - e * Math.Pow(xRotated, 3) + f * Math.Pow(xRotated, 4))), 2) - 0.0317338596 * xRotated;
                }
                else
                {
                    value = Math.Pow((-yRotated + a * (c1 * xRotated + d * Math.Pow(xRotated, 2) - e * Math.Pow(xRotated, 3) + f * Math.Pow(xRotated, 4))), 2) - 0.0317338596 * xRotated;
                }

                //value = yRotated - Math.Tan(radian)*xRotated;

                return(value);
            };

            c.LevelSetFunction = levelSet;

            //Initial Values
            c.InitialValues_Evaluators.Add(CompressibleVariables.Density, X => rho(X, 0.0));
            c.InitialValues_Evaluators.Add(CNSVariables.Velocity.xComponent, X => u0(X, 0.0));
            c.InitialValues_Evaluators.Add(CNSVariables.Velocity.yComponent, X => u1(X, 0.0));
            c.InitialValues_Evaluators.Add(CNSVariables.Pressure, X => pressure(X, 0.0));

            //BoundaryConditions
            c.AddBoundaryValue("AdiabaticSlipWall");
            c.AddBoundaryValue("supersonicInlet", CompressibleVariables.Density, rho);
            c.AddBoundaryValue("supersonicInlet", CNSVariables.Velocity.xComponent, u0);
            c.AddBoundaryValue("supersonicInlet", CNSVariables.Velocity.yComponent, u1);
            c.AddBoundaryValue("supersonicInlet", CNSVariables.Pressure, pressure);

            // Queries
            //c.Queries.Add("L2ErrorEntropy", IBMQueries.L2Error(state => state.Entropy, (X, t) => 2.8571428571428));
            //c.Queries.Add("IBMDragForce", IBMQueries.IBMDragForce());
            //c.Queries.Add("IBMLiftForce", IBMQueries.IBMLiftForce());
            return(c);
        }
        /// <summary>
        /// Test on a Cartesian grid, with a sinusodial solution.
        /// </summary>
        /// <param name="Res">
        /// Grid resolution
        /// </param>
        /// <param name="Dim">
        /// spatial dimension
        /// </param>
        /// <param name="deg">
        /// polynomial degree
        /// </param>
        /// <param name="solver_name">
        /// Name of solver to use.
        /// </param>
        public static SipControl TestCartesian2(int Res, int Dim, LinearSolverConfig.Code solver_name = LinearSolverConfig.Code.exp_softpcg_schwarz_directcoarse, int deg = 3)
        {
            if (Dim != 2 && Dim != 3)
            {
                throw new ArgumentOutOfRangeException();
            }

            var R = new SipControl();

            R.ProjectName = "ipPoison/cartesian";
            R.savetodb    = false;

            R.FieldOptions.Add("T", new FieldOpts()
            {
                Degree = deg, SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            R.FieldOptions.Add("Tex", new FieldOpts()
            {
                Degree = deg * 2
            });
            R.InitialValues_Evaluators.Add("RHS", X => - Math.Sin(X[0]));
            R.InitialValues_Evaluators.Add("Tex", X => Math.Sin(X[0]));
            R.ExactSolution_provided           = true;
            R.LinearSolver.NoOfMultigridLevels = int.MaxValue;
            R.LinearSolver.SolverCode          = solver_name;
            //R.TargetBlockSize = 100;



            R.GridFunc = delegate()
            {
                GridCommons grd = null;
                if (Dim == 2)
                {
                    double[] xNodes = GenericBlas.Linspace(0, 10, Res * 5 + 1);
                    double[] yNodes = GenericBlas.SinLinSpacing(-1, +1, 0.6, Res + 1);

                    grd = Grid2D.Cartesian2DGrid(xNodes, yNodes);
                }
                else if (Dim == 3)
                {
                    double[] xNodes = GenericBlas.Linspace(0, 10, Res * 5 + 1);
                    double[] yNodes = GenericBlas.SinLinSpacing(-1, +1, 0.6, Res + 1);
                    double[] zNodes = GenericBlas.SinLinSpacing(-1, +1, 0.6, Res + 1);

                    grd = Grid3D.Cartesian3DGrid(xNodes, yNodes, zNodes);
                }
                else
                {
                    throw new NotSupportedException();
                }
                grd.EdgeTagNames.Add(1, BoundaryType.Dirichlet.ToString());
                grd.EdgeTagNames.Add(2, BoundaryType.Neumann.ToString());
                grd.DefineEdgeTags(delegate(double[] X)
                {
                    byte ret;
                    if (Math.Abs(X[0] - 0.0) <= 1.0e-6)
                    {
                        ret = 1;
                    }
                    else
                    {
                        ret = 2;
                    }
                    return(ret);
                });

                return(grd);
            };

            R.AddBoundaryValue(BoundaryType.Dirichlet.ToString(), "T",
                               delegate(double[] X)
            {
                double x = X[0], y = X[1];

                if (Math.Abs(X[0] - (0.0)) < 1.0e-8)
                {
                    return(0.0);
                }

                throw new ArgumentOutOfRangeException();
            });

            R.AddBoundaryValue(BoundaryType.Neumann.ToString(), "T",
                               delegate(double[] X)
            {
                if (Math.Abs(X[1] - 1.0) < 1.0e-8 || Math.Abs(X[1] + 1.0) < 1.0e-8)      // y = -1, y = +1
                {
                    return(0);
                }

                if (X.Length > 2 && (Math.Abs(X[2] - 1.0) < 1.0e-8 || Math.Abs(X[2] + 1.0) < 1.0e-8))      // z = -1, z = +1
                {
                    return(0);
                }

                if (Math.Abs(X[0] - (+10.0)) < 1.0e-8)
                {
                    return(Math.Cos(10.0));
                }

                throw new ArgumentOutOfRangeException();
            });
            return(R);
        }
Beispiel #8
0
        private static IBMControl ControlCutNextToCut(bool agglomeration)
        {
            IBMControl c = new IBMControl();

            c.savetodb = false;

            int    dgDegree    = 2;
            double vortexSpeed = 1.0;

            // IBM Settings
            c.CutCellQuadratureType   = XQuadFactoryHelper.MomentFittingVariants.Classic;
            c.LevelSetQuadratureOrder = 5;
            c.AgglomerationThreshold  = agglomeration ? 0.3 : 0.0;

            c.DomainType         = DomainTypes.StaticImmersedBoundary;
            c.ActiveOperators    = Operators.Convection;
            c.ConvectiveFluxType = ConvectiveFluxTypes.Rusanov;
            c.ExplicitScheme     = ExplicitSchemes.RungeKutta;
            c.ExplicitOrder      = 1;
            c.EquationOfState    = IdealGas.Air;

            c.MachNumber = 1 / Math.Sqrt(c.EquationOfState.HeatCapacityRatio);

            c.AddVariable(Variables.Density, dgDegree);
            c.AddVariable(Variables.Momentum.xComponent, dgDegree);
            c.AddVariable(Variables.Momentum.yComponent, dgDegree);
            c.AddVariable(Variables.Energy, dgDegree);
            c.AddVariable(IBMVariables.LevelSet, 2);

            c.GridFunc = delegate {
                GridCommons grid = Grid2D.Cartesian2DGrid(
                    GenericBlas.Linspace(-5.0, 5.0, 21),
                    GenericBlas.Linspace(-0.5, 0.5, 3));
                grid.EdgeTagNames.Add(1, "supersonicInlet");
                grid.DefineEdgeTags(X => 1);
                return(grid);
            };

            c.LevelSetBoundaryTag = "supersonicInlet";

            IsentropicVortexExactSolution solution = new IsentropicVortexExactSolution(c, vortexSpeed);

            c.InitialValues_Evaluators.Add(Variables.Density, X => solution.rho()(X, 0.0));
            c.InitialValues_Evaluators.Add(Variables.Velocity.xComponent, X => solution.u()(X, 0.0));
            c.InitialValues_Evaluators.Add(Variables.Velocity.yComponent, X => solution.v()(X, 0.0));
            c.InitialValues_Evaluators.Add(Variables.Pressure, X => solution.p()(X, 0.0));
            if (agglomeration)
            {
                c.LevelSetFunction = (X, t) => - ((X[1] - 0.17) * (X[1] - 0.17) - 0.1);
            }
            else
            {
                c.LevelSetFunction = (X, t) => - (X[1] * X[1] - 0.2);
            }


            c.AddBoundaryValue("supersonicInlet", Variables.Density, solution.rho());
            c.AddBoundaryValue("supersonicInlet", Variables.Velocity[0], solution.u());
            c.AddBoundaryValue("supersonicInlet", Variables.Velocity[1], solution.v());
            c.AddBoundaryValue("supersonicInlet", Variables.Pressure, solution.p());

            c.Queries.Add("L2ErrorDensity", IBMQueries.L2Error(Variables.Density, solution.rho()));
            c.Queries.Add("L2ErrorPressure", IBMQueries.L2Error(state => state.Pressure, solution.p()));
            c.Queries.Add("L2ErrorEntropy", IBMQueries.L2Error(state => state.Entropy, (X, t) => 1.0));

            c.dtMin         = 0.0;
            c.dtMax         = 1.0;
            c.CFLFraction   = 0.2;
            c.Endtime       = double.MaxValue;
            c.NoOfTimesteps = 100;

            return(c);
        }
Beispiel #9
0
        private static IBMControl ControlTemplate(int dgDegree, int divisions, double levelSetPosition)
        {
            IBMControl c = new IBMControl();

            c.savetodb = false;

            double vortexSpeed = 1.0;

            c.DomainType         = DomainTypes.StaticImmersedBoundary;
            c.ActiveOperators    = Operators.Convection;
            c.ConvectiveFluxType = ConvectiveFluxTypes.Rusanov;
            c.ExplicitScheme     = ExplicitSchemes.RungeKutta;
            c.ExplicitOrder      = 1;
            c.EquationOfState    = IdealGas.Air;

            c.MachNumber = 1.0 / Math.Sqrt(c.EquationOfState.HeatCapacityRatio);

            c.AddVariable(Variables.Density, dgDegree);
            c.AddVariable(Variables.Momentum.xComponent, dgDegree);
            c.AddVariable(Variables.Momentum.yComponent, dgDegree);
            c.AddVariable(Variables.Energy, dgDegree);
            c.AddVariable(IBMVariables.LevelSet, 1);

            c.GridFunc = delegate {
                int         noOfCellsPerDirection = (2 << divisions) * 10;
                GridCommons grid = Grid2D.Cartesian2DGrid(
                    GenericBlas.Linspace(-10.0, 10.0, noOfCellsPerDirection + 1),
                    GenericBlas.Linspace(-10.0, 10.0, noOfCellsPerDirection + 1));
                grid.EdgeTagNames.Add(1, "supersonicInlet");
                grid.DefineEdgeTags(X => 1);
                return(grid);
            };

            c.LevelSetBoundaryTag = "supersonicInlet";

            IsentropicVortexExactSolution solution = new IsentropicVortexExactSolution(c, vortexSpeed);

            c.InitialValues_Evaluators.Add(Variables.Density, X => solution.rho()(X, 0.0));
            c.InitialValues_Evaluators.Add(Variables.Velocity.xComponent, X => solution.u()(X, 0.0));
            c.InitialValues_Evaluators.Add(Variables.Velocity.yComponent, X => solution.v()(X, 0.0));
            c.InitialValues_Evaluators.Add(Variables.Pressure, X => solution.p()(X, 0.0));

            c.LevelSetFunction = (X, t) => X[1] - levelSetPosition;

            c.AddBoundaryValue("supersonicInlet", Variables.Density, solution.rho());
            c.AddBoundaryValue("supersonicInlet", Variables.Velocity[0], solution.u());
            c.AddBoundaryValue("supersonicInlet", Variables.Velocity[1], solution.v());
            c.AddBoundaryValue("supersonicInlet", Variables.Pressure, solution.p());

            c.Queries.Add("L2ErrorDensity", IBMQueries.L2Error(Variables.Density, solution.rho()));
            c.Queries.Add("L2ErrorPressure", IBMQueries.L2Error(state => state.Pressure, solution.p()));
            c.Queries.Add("L2ErrorEntropy", IBMQueries.L2Error(state => state.Entropy, (X, t) => 1.0));

            c.dtMin         = 0.0;
            c.dtMax         = 1.0;
            c.CFLFraction   = 0.2;
            c.Endtime       = 0.5;
            c.NoOfTimesteps = 100;

            return(c);
        }
Beispiel #10
0
        /// <summary>
        /// Creates the control file
        /// </summary>
        /// <param name="noOfCells">number of Cells in each direction=3 for the reference solution</param>
        /// <param name="dgDegree">polynomial DG degree</param>
        /// <param name="optimized">SIPG flux: 0=normal, 1=optimized</param>
        /// <returns></returns>
        new public static CNSControl Control(int noOfCells, int dgDegree, int optimized)
        {
            CNSControl c = new CNSControl();

            c.savetodb      = false;
            c.NoOfTimesteps = 1;
            c.CFLFraction   = 0.1;

            c.ActiveOperators = Operators.Diffusion;
            switch (optimized)
            {
            case 0:
                c.DiffusiveFluxType = DiffusiveFluxTypes.SIPG;
                break;

            case 1:
                c.DiffusiveFluxType = DiffusiveFluxTypes.OptimizedSIPG;
                break;

            default:
                throw new ArgumentException("Wrong diffusive type, only SIPG (0) and OptimizedSIPG (1) exist");
            }
            c.SIPGPenaltyScaling = 1.0;
            c.ExplicitScheme     = ExplicitSchemes.RungeKutta;
            c.ExplicitOrder      = 1;

            c.EquationOfState = new IdealGas(2.0);
            c.MachNumber      = 1.0 / Math.Sqrt(c.EquationOfState.HeatCapacityRatio);
            c.ReynoldsNumber  = 1.0;
            c.PrandtlNumber   = 1.0;
            c.ViscosityLaw    = new SutherlandLaw();
            c.MachNumber      = 1 / Math.Sqrt(c.EquationOfState.HeatCapacityRatio);

            c.AddVariable(Variables.Density, dgDegree);
            c.AddVariable(Variables.Momentum[0], dgDegree);
            c.AddVariable(Variables.Momentum[1], dgDegree);
            c.AddVariable(Variables.Energy, dgDegree);

            c.GridFunc = delegate() {
                GridCommons grid = Grid2D.Cartesian2DGrid(
                    GenericBlas.Linspace(0.0, 2 * Math.PI, noOfCells + 1),
                    GenericBlas.Linspace(0.0, 2 * Math.PI, noOfCells + 1),
                    periodicX: false,
                    periodicY: false);
                grid.EdgeTagNames.Add(1, "supersonicinlet");
                grid.DefineEdgeTags(x => 1);

                return(grid);
            };

            Func <double[], double> rho = X => 0.1 * Math.Sin(X[0]) + 0.1 * Math.Cos(X[1]) + 1.0;
            Func <double[], double> u0  = X => Math.Sin(X[0]) + Math.Cos(X[1]) + 1.0;
            Func <double[], double> u1  = X => Math.Cos(X[0]) + Math.Sin(X[1]) + 1.0;
            Func <double[], double> p   = X => Math.Cos(X[0]) + Math.Sin(X[0]) + 4.0;

            c.InitialValues_Evaluators.Add(Variables.Density, rho);
            c.InitialValues_Evaluators.Add(Variables.Velocity[0], u0);
            c.InitialValues_Evaluators.Add(Variables.Velocity[1], u1);
            c.InitialValues_Evaluators.Add(Variables.Pressure, p);

            c.AddBoundaryCondition("supersonicinlet", Variables.Density, rho);
            c.AddBoundaryCondition("supersonicinlet", Variables.Velocity[0], u0);
            c.AddBoundaryCondition("supersonicinlet", Variables.Velocity[1], u1);
            c.AddBoundaryCondition("supersonicinlet", Variables.Pressure, p);

            return(c);
        }
Beispiel #11
0
        public static IBMControl IBMBump(int noOfCells, int dgDegree, int lsDegree, double CFL, double epsilonX = 0.0, double epsilonY = 0.0)
        {
            IBMControl c = new IBMControl();

            // Solver Settings
            c.dtMin         = 0.0;
            c.dtMax         = 1.0;
            c.Endtime       = 1000.0;
            c.CFLFraction   = CFL;
            c.NoOfTimesteps = 200000;

            c.PrintInterval      = 100;
            c.ResidualInterval   = 100;
            c.ResidualLoggerType = ResidualLoggerTypes.ChangeRate | ResidualLoggerTypes.Query;
            c.ResidualBasedTerminationCriteria.Add("changeRate_L2_abs_rhoE", 1E-8);

            //IBM Settings
            c.LevelSetBoundaryTag     = "adiabaticSlipWall";
            c.LevelSetQuadratureOrder = 2 * dgDegree;
            c.AgglomerationThreshold  = 0.3;

            // NEXT STEP: SET THIS BOOL TO FALSE AND JUST USE IN POSITIVE SUB_VOLUME;
            // THEN TRY BOUNDING BOX APPROACH?
            // WHY THE HELL DOES THIS CONFIGURATION FAIL!??!?!?!?
            c.CutCellQuadratureType             = XQuadFactoryHelper.MomentFittingVariants.Classic;
            c.SurfaceHMF_ProjectNodesToLevelSet = false;
            c.SurfaceHMF_RestrictNodes          = true;
            c.SurfaceHMF_UseGaussNodes          = false;
            c.VolumeHMF_NodeCountSafetyFactor   = 3.0;
            c.VolumeHMF_RestrictNodes           = true;
            c.VolumeHMF_UseGaussNodes           = false;

            //Guid restart = new Guid(" 60688cbc-707d-4777-98e6-d237796ec14c");
            //c.RestartInfo = new Tuple<Guid, BoSSS.Foundation.IO.TimestepNumber>(restart, -1);

            // Session Settings
            c.DbPath = @"\\fdyprime\userspace\kraemer-eis\FDY-Cluster\dbe_bump\";
            //c.DbPath = @"/home/kraemer/GaussianBump/dbev2/";
            c.savetodb           = true;
            c.saveperiod         = 20000;
            c.ProjectName        = "BoxHMF=" + c.CutCellQuadratureType + "_Ma=0.5_(" + 2 * noOfCells + "x" + noOfCells + ")_CFL=" + c.CFLFraction + "_lsQuadOrder=" + c.LevelSetQuadratureOrder + "_p=" + dgDegree + "_agg=" + c.AgglomerationThreshold + "_epsX=" + epsilonX + "_epsY=" + epsilonY;
            c.ProjectDescription = "GaussianBump with Ma=0.5";
            c.Tags.Add("Gaussian Bump");
            c.Tags.Add("IBM Test");

            // Solver Type
            c.DomainType         = DomainTypes.StaticImmersedBoundary;
            c.ActiveOperators    = Operators.Convection;
            c.ConvectiveFluxType = ConvectiveFluxTypes.OptimizedHLLC;

            // Time-Stepping Settings
            c.ExplicitScheme = ExplicitSchemes.RungeKutta;
            c.ExplicitOrder  = 1;

            //Material Settings
            c.EquationOfState = IdealGas.Air;



            // Primary CNSVariables
            c.AddVariable(CompressibleVariables.Density, dgDegree);
            c.AddVariable(CompressibleVariables.Momentum.xComponent, dgDegree);
            c.AddVariable(CompressibleVariables.Momentum.yComponent, dgDegree);
            c.AddVariable(CompressibleVariables.Energy, dgDegree);

            c.AddVariable(IBMVariables.LevelSet, lsDegree);



            // Grid

            //switch (noOfCells) {
            //    case 8:
            //        c.GridGuid = new Guid("7337e273-542f-4b97-b592-895ac3422621");
            //        break;
            //    case 16:
            //        c.GridGuid = new Guid("32e5a779-2aef-4ea2-bdef-b158ae785f01");
            //        break;
            //    case 32:
            //        c.GridGuid = new Guid("e96c9f83-3486-4e45-aa3b-9a436445a059");
            //        break;
            //    case 64:
            //        c.GridGuid = new Guid("a86f1b67-4fa3-48ed-b6df-dcea370eb2c0");
            //        break;
            //    default:
            //        throw new ArgumentException("Wrong Grid Input");
            //}



            c.GridFunc = delegate {
                double xBoundary = 12.0;
                double yBoundary = 12.0;
                double yBottom   = 0.0;

                double[] xnodes = GenericBlas.Linspace(-xBoundary, xBoundary, 2 * noOfCells + 1);

                //double ySplit = 6.0;
                //int ySplitNoOfCells = (int) (0.5*noOfCells);
                //double[] ynodes1 = GenericBlas.Linspace(yBottom, ySplit, ySplitNoOfCells + 1);
                //double[] ynodes2 = GenericBlas.Linspace(ySplit, yBoundary, noOfCells-ySplitNoOfCells + 1);
                //ynodes1 = ynodes1.GetSubVector(0, ynodes1.Length - 1);
                //double[] ynodes = ArrayTools.Cat(ynodes1, ynodes2);

                double[] ynodes = GenericBlas.Linspace(yBottom, yBoundary, noOfCells + 1);

                GridCommons grid = Grid2D.Cartesian2DGrid(
                    xnodes,
                    ynodes
                    );

                grid.EdgeTagNames.Add(1, "supersonicinlet");
                grid.EdgeTagNames.Add(2, "adiabaticSlipWall");

                Func <double[], byte> func = delegate(double[] x) {
                    if (Math.Abs(x[0] + xBoundary) < 1e-5)   // Inflow
                    {
                        return(1);
                    }
                    else if (Math.Abs(x[0] - xBoundary) < 1e-5)     // Outflow
                    {
                        return(1);
                    }
                    else if (Math.Abs(x[1] - yBoundary) < 1e-5)     // Top
                    {
                        return(1);
                    }
                    else     // Bottom
                    {
                        return(2);
                    }
                };
                grid.DefineEdgeTags(func);
                grid.Name = "IBM-[" + -xBoundary + "," + xBoundary + "]x[" + yBottom + "," + yBoundary + "]_Cells:(" + 2 * noOfCells + "x" + noOfCells + ")";
                return(grid);
            };

            // Functions
            Func <double[], double, double> rho      = (X, t) => 1.0;
            Func <double[], double, double> u0       = (X, t) => 1.0;
            Func <double[], double, double> u1       = (X, t) => 0.0;
            Func <double[], double, double> pressure = (X, t) => 2.8571428571428;

            //Initial Values
            c.InitialValues_Evaluators.Add(CompressibleVariables.Density, X => rho(X, 0.0));
            c.InitialValues_Evaluators.Add(CNSVariables.Velocity.xComponent, X => u0(X, 0.0));
            c.InitialValues_Evaluators.Add(CNSVariables.Velocity.yComponent, X => u1(X, 0.0));
            c.InitialValues_Evaluators.Add(CNSVariables.Pressure, X => pressure(X, 0.0));

            c.LevelSetFunction = (X, t) => X[1] - epsilonY - 0.01 - 0.3939 * Math.Exp(-0.5 * (X[0] - epsilonX) * (X[0] - epsilonX));

            //BoundaryConditions
            c.AddBoundaryValue("adiabaticSlipWall");
            c.AddBoundaryValue("supersonicInlet", CompressibleVariables.Density, rho);
            c.AddBoundaryValue("supersonicInlet", CNSVariables.Velocity.xComponent, u0);
            c.AddBoundaryValue("supersonicInlet", CNSVariables.Velocity.yComponent, u1);
            c.AddBoundaryValue("supersonicInlet", CNSVariables.Pressure, pressure);


            // Queries

            c.Queries.Add("L2ErrorEntropy", IBMQueries.L2Error(state => state.Entropy, (X, t) => 2.8571428571428));
            return(c);
        }
Beispiel #12
0
        public static IBMControl IBMBumpTest(int noOfCells, int dgDegree, int lsDegree, double CFL)
        {
            IBMControl c = new IBMControl();

            // Solver Settings
            c.dtMin         = 0.0;
            c.dtMax         = 1.0;
            c.Endtime       = 1000.0;
            c.CFLFraction   = CFL;
            c.NoOfTimesteps = 250000;

            c.PrintInterval      = 100;
            c.ResidualInterval   = 100;
            c.ResidualLoggerType = ResidualLoggerTypes.ChangeRate | ResidualLoggerTypes.Query;
            c.ResidualBasedTerminationCriteria.Add("changeRate_L2_abs_rhoE", 1E-8);

            //Guid restart = new Guid(" 60688cbc-707d-4777-98e6-d237796ec14c");
            //c.RestartInfo = new Tuple<Guid, BoSSS.Foundation.IO.TimestepNumber>(restart, -1);

            // Session Settings
            c.DbPath = @"C:\bosss_dbv2\GaussianBump_hhlr";
            //c.DbPath = @"\\fdyprime\userspace\kraemer-eis\FDY-Cluster\dbe_bump\";
            //c.DbPath = @"/home/kraemer/GaussianBump/dbev2/";
            c.savetodb           = true;
            c.saveperiod         = 100;
            c.ProjectName        = "TestsCutCells_(" + 2 * noOfCells + "x" + noOfCells + ")_CFL=" + c.CFLFraction + "_ls=" + lsDegree + "_p=" + dgDegree + "_agg=" + 0.53;
            c.ProjectDescription = "GaussianBump with Ma=0.5";
            c.Tags.Add("Gaussian Bump");
            c.Tags.Add("IBM Test");

            // Solver Type
            c.DomainType         = DomainTypes.StaticImmersedBoundary;
            c.ActiveOperators    = Operators.Convection;
            c.ConvectiveFluxType = ConvectiveFluxTypes.OptimizedHLLC;

            // Time-Stepping Settings
            c.ExplicitScheme = ExplicitSchemes.RungeKutta;
            c.ExplicitOrder  = 1;

            //Material Settings
            c.EquationOfState = IdealGas.Air;

            //IBM Settings
            c.LevelSetBoundaryTag     = "adiabaticSlipWall";
            c.LevelSetQuadratureOrder = 2 * lsDegree;
            c.CutCellQuadratureType   = XQuadFactoryHelper.MomentFittingVariants.Classic;
            c.AgglomerationThreshold  = 0.3;

            // Primary CNSVariables
            c.AddVariable(CompressibleVariables.Density, dgDegree);
            c.AddVariable(CompressibleVariables.Momentum.xComponent, dgDegree);
            c.AddVariable(CompressibleVariables.Momentum.yComponent, dgDegree);
            c.AddVariable(CompressibleVariables.Energy, dgDegree);

            c.AddVariable(IBMVariables.LevelSet, lsDegree);

            c.GridFunc = delegate {
                double xBoundary = 2.0625;
                double yBoundary = 2.0525;
                double yBottom   = -0.01;

                double[] xnodes = GenericBlas.Linspace(-xBoundary, xBoundary, 2 * noOfCells + 1);
                double[] ynodes = GenericBlas.Linspace(yBottom, yBoundary, noOfCells + 1);

                GridCommons grid = Grid2D.Cartesian2DGrid(
                    xnodes,
                    ynodes
                    );

                grid.EdgeTagNames.Add(1, "supersonicinlet");
                grid.EdgeTagNames.Add(2, "adiabaticSlipWall");

                Func <double[], byte> func = delegate(double[] x) {
                    if (Math.Abs(x[0] + xBoundary) < 1e-5)   // Inflow
                    {
                        return(1);
                    }
                    else if (Math.Abs(x[0] - xBoundary) < 1e-5)     // Outflow
                    {
                        return(1);
                    }
                    else if (Math.Abs(x[1] - yBoundary) < 1e-5)     // Top
                    {
                        return(1);
                    }
                    else     // Bottom
                    {
                        return(2);
                    }
                };
                grid.DefineEdgeTags(func);
                grid.Name = "IBM-[" + -xBoundary + "," + xBoundary + "]x[" + yBottom + "," + yBoundary + "]_Cells:(" + 2 * noOfCells + "x" + noOfCells + ")";
                return(grid);
            };

            // Functions
            Func <double[], double, double> rho      = (X, t) => 1.0;
            Func <double[], double, double> u0       = (X, t) => 1.0;
            Func <double[], double, double> u1       = (X, t) => 0.0;
            Func <double[], double, double> pressure = (X, t) => 2.8571428571428;

            //Initial Values
            c.InitialValues_Evaluators.Add(CompressibleVariables.Density, X => rho(X, 0.0));
            c.InitialValues_Evaluators.Add(CNSVariables.Velocity.xComponent, X => u0(X, 0.0));
            c.InitialValues_Evaluators.Add(CNSVariables.Velocity.yComponent, X => u1(X, 0.0));
            c.InitialValues_Evaluators.Add(CNSVariables.Pressure, X => pressure(X, 0.0));

            c.LevelSetFunction = (X, t) => X[1] - 0.3939 * Math.Exp(-0.5 * X[0] * X[0]);

            //BoundaryConditions
            c.AddBoundaryValue("adiabaticSlipWall");
            c.AddBoundaryValue("supersonicInlet", CompressibleVariables.Density, rho);
            c.AddBoundaryValue("supersonicInlet", CNSVariables.Velocity.xComponent, u0);
            c.AddBoundaryValue("supersonicInlet", CNSVariables.Velocity.yComponent, u1);
            c.AddBoundaryValue("supersonicInlet", CNSVariables.Pressure, pressure);


            // Queries

            c.Queries.Add("L2ErrorEntropy", IBMQueries.L2Error(state => state.Entropy, (X, t) => 2.8571428571428));
            return(c);
        }
Beispiel #13
0
        /// <summary>
        /// Test on a Cartesian grid, with a sinusodial solution.
        /// </summary>
        /// <param name="Res">
        /// Grid resolution
        /// </param>
        /// <param name="Dim">
        /// spatial dimension
        /// </param>
        /// <param name="deg">
        /// polynomial degree
        /// </param>
        /// <param name="solver_name">
        /// Name of solver to use.
        /// </param>
        public static SipControl TestCartesian2(int Res, int Dim, LinearSolverCode solver_name = LinearSolverCode.exp_Kcycle_schwarz, int deg = 5)
        {
            //BoSSS.Application.SipPoisson.SipHardcodedControl.TestCartesian2(8,3,deg:2)


            if (Dim != 2 && Dim != 3)
            {
                throw new ArgumentOutOfRangeException();
            }

            var R = new SipControl();

            R.ProjectName = "ipPoison/cartesian";
            R.savetodb    = false;

            R.FieldOptions.Add("T", new FieldOpts()
            {
                Degree = deg, SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            R.FieldOptions.Add("Tex", new FieldOpts()
            {
                Degree = deg + 2
            });
            R.InitialValues_Evaluators.Add("RHS", X => - Math.Sin(X[0]));
            R.InitialValues_Evaluators.Add("Tex", X => Math.Sin(X[0]));
            R.ExactSolution_provided           = true;
            R.LinearSolver.NoOfMultigridLevels = int.MaxValue;
            R.LinearSolver.SolverCode          = solver_name;
            // exp_Kcycle_schwarz
            // exp_gmres_levelpmg

#if DEBUG
            // For testing in DEBUG mode, this setting enforces the use
            // of many multigrid-levels. In 2D, the examples are so small that
            R.LinearSolver.TargetBlockSize = 100;
#endif


            R.GridFunc = delegate() {
                GridCommons grd = null;
                if (Dim == 2)
                {
                    double[] xNodes = GenericBlas.Linspace(0, 10, Res * 5 + 1);
                    double[] yNodes = GenericBlas.SinLinSpacing(-1, +1, 0.6, Res + 1);

                    grd = Grid2D.Cartesian2DGrid(xNodes, yNodes);
                }
                else if (Dim == 3)
                {
                    double[] xNodes = GenericBlas.Linspace(0, 10, Res * 5 + 1);
                    //double[] yNodes = GenericBlas.SinLinSpacing(-1, +1, 0.6, Res + 1);
                    //double[] zNodes = GenericBlas.SinLinSpacing(-1, +1, 0.6, Res + 1);
                    double[] yNodes = GenericBlas.Linspace(-1, +1, Res + 1);
                    double[] zNodes = GenericBlas.Linspace(-1, +1, Res + 1);

                    grd = Grid3D.Cartesian3DGrid(xNodes, yNodes, zNodes);
                }
                else
                {
                    throw new NotSupportedException();
                }
                grd.EdgeTagNames.Add(1, BoundaryType.Dirichlet.ToString());
                grd.EdgeTagNames.Add(2, BoundaryType.Neumann.ToString());
                grd.DefineEdgeTags(delegate(double[] X) {
                    byte ret;
                    double x = X[0];
                    if (Math.Abs(x - 0.0) <= 1.0e-8)
                    {
                        ret = 1; // Dirichlet
                    }
                    else
                    {
                        ret = 2; // Neumann
                    }
                    return(ret);
                });

                return(grd);
            };

            R.AddBoundaryValue(BoundaryType.Dirichlet.ToString(), "T",
                               delegate(double[] X) {
                double x = X[0], y = X[1];


                return(Math.Sin(x));
                //if (Math.Abs(X[0] - (0.0)) < 1.0e-8)
                //    return 0.0;

                //throw new ArgumentOutOfRangeException();
            });

            R.AddBoundaryValue(BoundaryType.Neumann.ToString(), "T",
                               delegate(double[] X) {
                double x = X[0], y = X[1], z = X.Length > 2 ? X[2] : 0.0;

                if (Math.Abs(y - 1.0) < 1.0e-8 || Math.Abs(y + 1.0) < 1.0e-8)      // y = -1, y = +1
                {
                    return(0);
                }

                if (X.Length > 2 && (Math.Abs(z - 1.0) < 1.0e-8 || Math.Abs(z + 1.0) < 1.0e-8))      // z = -1, z = +1
                {
                    return(0);
                }

                //if (Math.Abs(X[0] - (+10.0)) < 1.0e-8)
                return(Math.Cos(x));

                //throw new ArgumentOutOfRangeException();
            });
            return(R);
        }
        public static SipControl ConvergenceTest(int Res = 20, int Dim = 2, LinearSolverCode solver_name = LinearSolverCode.exp_Kcycle_schwarz, int deg = 1)
        {
            if (Dim != 2 && Dim != 3)
            {
                throw new ArgumentOutOfRangeException();
            }

            var R = new SipControl();

            R.ProjectName = "ipPoison/cartesian";
            R.savetodb    = false;

            R.FieldOptions.Add("T", new FieldOpts()
            {
                Degree = deg, SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            R.FieldOptions.Add("Tex", new FieldOpts()
            {
                Degree = deg + 2
            });
            R.InitialValues_Evaluators.Add("RHS", X => - 1.0); // constant force i.e. gravity
            R.ExactSolution_provided           = false;        //true;
            R.LinearSolver.NoOfMultigridLevels = int.MaxValue;
            R.LinearSolver.SolverCode          = solver_name;
            R.LinearSolver.MaxSolverIterations = 200;
            R.LinearSolver.TargetBlockSize     = 10000;
            R.LinearSolver.MaxKrylovDim        = 2000;



            R.GridFunc = delegate() {
                GridCommons grd = null;
                if (Dim == 2)
                {
                    double[] xNodes = GenericBlas.Linspace(-10, 10, Res * 5 + 1);
                    double[] yNodes = GenericBlas.Linspace(-10, 10, Res * 5 + 1);
                    grd = Grid2D.Cartesian2DGrid(xNodes, yNodes);
                }
                else
                {
                    throw new NotSupportedException();
                }

                grd.EdgeTagNames.Add(1, BoundaryType.Dirichlet.ToString());
                grd.DefineEdgeTags(delegate(double[] X) {
                    byte ret;

                    ret = 1; // all dirichlet
                    return(ret);
                });

                return(grd);
            };

            R.AddBoundaryValue(BoundaryType.Dirichlet.ToString(), "T",
                               delegate(double[] X) {
                double x = X[0], y = X[1];
                return(0.0);
            });

            return(R);
        }