Ejemplo n.º 1
0
        /// <summary>
        /// Computes the exact solution of the Riemann problem, samples it at
        /// <paramref name="x"/> (coordinate normal to discontinuity position)
        /// at time <paramref name="t"/>
        /// </summary>
        /// <param name="meanPressure"></param>
        /// <param name="meanVelocity"></param>
        /// <param name="x"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public StateVector GetState(double meanPressure, double meanVelocity, double x, double t)
        {
            double S = x / t;

            Sample(meanPressure, meanVelocity, S, out densityStar, out normalVelocityStar, out pressureStar);

            // Return exact solution in conservative variables
            Vector   u;
            Material material;

            if (S <= meanVelocity)
            {
                // left of the interface
                u        = velocityLeft;
                material = stateLeft.Material;
            }
            else
            {
                // right of the interface
                u        = velocityRight;
                material = stateRight.Material;
            }
            u[0] = normalVelocityStar;

            return(StateVector.FromPrimitiveQuantities(
                       material,
                       densityStar,
                       u.FromEdgeCoordinates(edgeNormal),
                       pressureStar));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Calculates the boundary value for an isolating slip wall according
        /// to the first variant described in VegtVen2002. The basic idea is to
        /// impose \f$ \vec{u} \cdot \vec{n} = 0\f$  (slip wall) by
        /// setting the edge momentum to
        /// \f$ \vec{m}^+ = \vec{m}^- - 2((\rho \vec{u})^- \cdot \vec{n})\vec{n}\f$
        /// which mimics a mirrored flow at the other side of the wall.
        /// </summary>
        /// <param name="time">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="x">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="normal">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="stateIn">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <returns>
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </returns>
        public override StateVector GetBoundaryState(double time, double[] x, double[] normal, StateVector stateIn)
        {
            Vector3D normalVector = GetNormalVector(normal);

            StateVector stateOut;

            if (WallVelocities == null)
            {
                // VegtVen2002, page 14, second equation
                Vector3D mOut = stateIn.Momentum - 2.0 * (stateIn.Momentum * normalVector) * normalVector;
                stateOut = new StateVector(stateIn.Material, stateIn.Density, mOut, stateIn.Energy);
            }
            else
            {
                Vector3D uWall = new Vector3D();
                for (int d = 0; d < CNSEnvironment.NumberOfDimensions; d++)
                {
                    uWall[d] = WallVelocities[d](x, time);
                }

                Vector3D uOut = stateIn.Velocity
                                - 2.0 * ((stateIn.Velocity - uWall) * normalVector) * normalVector;
                stateOut = StateVector.FromPrimitiveQuantities(
                    stateIn.Material, stateIn.Density, uOut, stateIn.Pressure);
            }

            return(stateOut);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Calculates the boundary value for an isolating slip wall according
        /// to the first variant described in VegtVen2002. The basic idea is to
        /// impose \f$ \vec{u} \cdot \vec{n} = 0\f$  (slip wall) by
        /// setting the edge momentum to
        /// \f$ \vec{m}^+ = \vec{m}^- - 2((\rho \vec{u})^- \cdot \vec{n})\vec{n}\f$
        /// which mimics a mirrored flow at the other side of the wall.
        /// </summary>
        /// <param name="time">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="x">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="normal">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="stateIn">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <returns>
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </returns>
        public override StateVector GetBoundaryState(double time, double[] x, double[] normal, StateVector stateIn)
        {
            Vector normalVector = GetNormalVector(normal);

            Debug.Assert(normal.Length == stateIn.Dimension);
            int D = normal.Length;

            StateVector stateOut;

            if (WallVelocities == null)
            {
                // VegtVen2002, page 14, second equation
                Vector mOut = stateIn.Momentum - 2.0 * (stateIn.Momentum * normalVector) * normalVector;
                stateOut = new StateVector(stateIn.Material, stateIn.Density, mOut, stateIn.Energy);
            }
            else
            {
                Vector uWall = new Vector(D);
                for (int d = 0; d < D; d++)
                {
                    uWall[d] = WallVelocities[d](x, time);
                }

                Vector uOut = stateIn.Velocity
                              - 2.0 * ((stateIn.Velocity - uWall) * normalVector) * normalVector;
                stateOut = StateVector.FromPrimitiveQuantities(
                    stateIn.Material, stateIn.Density, uOut, stateIn.Pressure);
            }

            return(stateOut);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Calculates the boundary values for a subsonic outlet (Mach number
 /// smaller than 1). We have to impose one condition (here, we choose
 /// the pressure <see cref="pressureFunction"/>) and extrapolate the
 /// other values following FerzigerPeric2001 (p. 315ff)
 /// </summary>
 /// <param name="time">
 /// <see cref="BoundaryCondition.GetBoundaryState"/>
 /// </param>
 /// <param name="x">
 /// <see cref="BoundaryCondition.GetBoundaryState"/>
 /// </param>
 /// <param name="normal">
 /// <see cref="BoundaryCondition.GetBoundaryState"/>
 /// </param>
 /// <param name="stateIn">
 /// <see cref="BoundaryCondition.GetBoundaryState"/>
 /// </param>
 /// <returns>
 /// \f$
 /// (\rho^-, u^-, p^*)^T
 /// \f$
 /// </returns>
 public override StateVector GetBoundaryState(double time, double[] x, double[] normal, StateVector stateIn)
 {
     return(StateVector.FromPrimitiveQuantities(
                stateIn.Material,
                stateIn.Density,
                stateIn.Velocity,
                pressureFunction(x, time)));
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Calculates the boundary values for a subsonic inlet (Mach number
        /// smaller than 1). Theoretically, we have to impose four conditions
        /// (in the inviscid as well as in the viscid case!) which is why we
        /// extrapolate the fifth value (in this case: the energy) to the
        /// boundary.
        /// </summary>
        /// <param name="time">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="x">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="normal">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="stateIn">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <returns>
        /// \f$ (\rho^*, \vec{u}^*, p^-)^T\f$
        /// </returns>
        public override StateVector GetBoundaryState(double time, double[] x, double[] normal, StateVector stateIn)
        {
            double rhoOut = densityFunction(x, time);

            Vector3D uOut = new Vector3D();

            for (int i = 0; i < CNSEnvironment.NumberOfDimensions; i++)
            {
                uOut[i] = velocityFunctions[i](x, time);
            }

            return(StateVector.FromPrimitiveQuantities(stateIn.Material, rhoOut, uOut, stateIn.Pressure));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Calculates the boundary values for a subsonic inlet (Mach number
        /// smaller than 1). Theoretically, we have to impose four conditions
        /// (in the inviscid as well as in the viscid case!) which is why we
        /// extrapolate the fifth value (in this case: the energy) to the
        /// boundary.
        /// </summary>
        /// <param name="time">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="x">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="normal">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="stateIn">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <returns>
        /// \f$ (\rho^*, \vec{u}^*, p^-)^T\f$
        /// </returns>
        public override StateVector GetBoundaryState(double time, double[] x, double[] normal, StateVector stateIn)
        {
            double rhoOut = densityFunction(x, time);

            Debug.Assert(x.Length == stateIn.Dimension);
            int D = x.Length;

            Vector uOut = new Vector(stateIn.Dimension);

            for (int i = 0; i < D; i++)
            {
                uOut[i] = velocityFunctions[i](x, time);
            }

            return(StateVector.FromPrimitiveQuantities(stateIn.Material, rhoOut, uOut, stateIn.Pressure));
        }
Ejemplo n.º 7
0
        //private static int count = 0;

        //private static StreamWriter writer;

        /// <summary>
        /// Calculates the boundary value for an isolating slip wall according
        /// to the first variant described in VegtVen2002. The basic idea is to
        /// impose \f$ \vec{u} \cdot \vec{n} = 0\f$  (slip wall) by
        /// setting the edge momentum to
        /// \f$ \vec{m}^+ = \vec{m}^- - 2((\rho \vec{u})^- \cdot \vec{n})\vec{n}\f$
        /// which mimics a mirrored flow at the other side of the wall.
        /// </summary>
        public override StateVector GetBoundaryState(double time, Vector x, Vector normal, StateVector stateIn)
        {
            //Convection.OptimizedHLLCFlux.AdiabaticSlipWall.Start();
            Vector normalVector = normal;

            Debug.Assert(normal.Dim == stateIn.Dimension);
            int D = normal.Dim;

            StateVector stateOut;

            if (WallVelocities == null)
            {
                // VegtVen2002, page 14, second equation
                ilPSP.Vector mOut = stateIn.Momentum - 2.0 * (stateIn.Momentum * normalVector) * normalVector;
                stateOut = new StateVector(stateIn.Material, stateIn.Density, mOut, stateIn.Energy);
            }
            else
            {
                ilPSP.Vector uWall = new ilPSP.Vector(D);
                for (int d = 0; d < D; d++)
                {
                    uWall[d] = WallVelocities[d](x, time);
                }

                ilPSP.Vector uOut = stateIn.Velocity
                                    - 2.0 * ((stateIn.Velocity - uWall) * normalVector) * normalVector;
                stateOut = StateVector.FromPrimitiveQuantities(
                    stateIn.Material, stateIn.Density, uOut, stateIn.Pressure);
            }

            //Console.WriteLine(String.Format("{0}: \t x = ({1:0.0000}, {2:0.0000}) \t stateOut = ({3:0.0000}, {4:0.0000}, {5:0.0000}, {6:0.0000}) \t normal = ({7:0.0000}, {8:0.0000})", count, x.x, x.y, stateOut.Density, stateOut.Momentum.x, stateOut.Momentum.y, stateOut.Energy, normal.x, normal.y));
            //count++;

            //// StreamWriter
            //if (writer == null) {
            //    writer = new StreamWriter("QuadraturePoints.txt");
            //}

            //string resultLine;
            //resultLine = x.x + "\t" + x.y + "\t" + stateOut.Density + "\t" + stateOut.Momentum.x + "\t" + stateOut.Momentum.y + "\t" + stateOut.Energy + "\t" + normal.x + "\t" + normal.y;
            //writer.WriteLine(resultLine);
            //writer.Flush();

            //Convection.OptimizedHLLCFlux.AdiabaticSlipWall.Stop();
            return(stateOut);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Calculates the state at the boundary from the prescribed stagnation
        /// pressure and the prescribed stagnation temperature. The calculation
        /// follows FerzigerPeric2001 (p. 315ff). The flow is prescribed to be
        /// normal to the edge.
        /// </summary>
        /// <param name="time">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="x">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="normal">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <param name="stateIn">
        /// <see cref="BoundaryCondition.GetBoundaryState"/>
        /// </param>
        /// <returns>
        /// \f$
        /// T^+ = T_t(x) \frac{p_t(x)}{p^-}^{\frac{1.0 - \gamma}{\gamma}}
        /// \f$
        /// \f$
        /// |\vec{u^+}| = \sqrt{\frac{2 T^+}{(\gamma - 1) \mathrm{Ma}_\infty^2} \left(\frac{T_t(x)}{T^+} -1\right)}
        /// \f$
        /// \f$ \rho^+ = \frac{p^- }{T^+}\f$
        /// \f$
        /// (\rho^+, -\rho^+ |\vec{u^+}| \vec{n}, \frac{p}{\kappa - 1} + \frac{rho^+ |\vec{u^+}|^2}{2})^T
        /// \f$
        /// </returns>
        public override StateVector GetBoundaryState(double time, double[] x, double[] normal, StateVector stateIn)
        {
            double   gamma        = config.EquationOfState.HeatCapacityRatio;
            double   Mach         = config.MachNumber;
            Vector3D inwardNormal = new Vector3D();

            for (int i = 0; i < normal.Length; i++)
            {
                inwardNormal[i] = -normal[i];
            }

            double p0 = TotalPressureFunction(x, time);
            double T0 = TotalTemperatureFunction(x, time);

            double p   = stateIn.Pressure;
            double T   = TotalTemperatureFunction(x, time) * Math.Pow(p0 / p, (1.0 - gamma) / gamma);
            double rho = p / T;

            double   VelocitySquare = 2.0 * T / ((gamma - 1.0) * (Mach * Mach)) * (T0 / T - 1.0);
            Vector3D velocityOut    = Math.Sqrt(VelocitySquare) * inwardNormal;

            return(StateVector.FromPrimitiveQuantities(stateIn.Material, rho, velocityOut, p));
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Calculates the boundary values for a supersonic inlet (Mach number
        /// greater than 1). Theoretically, we have to impose five conditions
        /// (in the inviscid as well as in the viscid case!) which is why
        /// calculate the complete state from the given density, momentum and
        /// pressure
        /// </summary>
        /// <returns>
        /// \f$ (\rho^*, u_0^*[, u_1^*[, u_2^*]], p*)^T\f$
        /// </returns>
        public override StateVector GetBoundaryState(double time, Vector x, Vector normal, StateVector stateIn)
        {
            //Convection.OptimizedHLLCFlux.SupersonicInlet.Start();

            Debug.Assert(x.Dim == stateIn.Dimension);
            int D = x.Dim;

            Vector uOut = new Vector(D);

            for (int i = 0; i < D; i++)
            {
                uOut[i] = VelocityFunctions[i](x, time);
            }

            StateVector retval = StateVector.FromPrimitiveQuantities(
                stateIn.Material,
                DensityFunction(x, time),
                uOut,
                PressureFunction(x, time));

            //Convection.OptimizedHLLCFlux.SupersonicInlet.Stop();
            return(retval);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Template for all shock tube tests
        /// </summary>
        /// <param name="convectiveFlux"></param>
        /// <param name="densityLeft"></param>
        /// <param name="velocityLeft"></param>
        /// <param name="pressureLeft"></param>
        /// <param name="densityRight"></param>
        /// <param name="velocityRight"></param>
        /// <param name="pressureRight"></param>
        /// <param name="discontinuityPosition"></param>
        /// <returns></returns>
        private static CNSControl GetShockTubeControlTemplate(ConvectiveFluxTypes convectiveFlux, double densityLeft, double velocityLeft, double pressureLeft, double densityRight, double velocityRight, double pressureRight, double discontinuityPosition)
        {
            CNSControl c = new CNSControl();

            c.DbPath   = null;
            c.savetodb = false;

            c.ActiveOperators    = Operators.Convection;
            c.ConvectiveFluxType = convectiveFlux;
            c.EquationOfState    = IdealGas.Air;
            c.MachNumber         = 1.0 / Math.Sqrt(c.EquationOfState.HeatCapacityRatio);

            c.ExplicitScheme = ExplicitSchemes.RungeKutta;
            c.ExplicitOrder  = 1;

            int dgDegree = 0;

            c.AddVariable(Variables.Density, dgDegree);
            c.AddVariable(Variables.Momentum.xComponent, dgDegree);
            c.AddVariable(Variables.Energy, dgDegree);

            c.AddVariable(Variables.Pressure, dgDegree);
            c.AddVariable(Variables.Velocity.xComponent, dgDegree);

            c.GridFunc = delegate {
                double[] xNodes = GenericBlas.Linspace(0.0, 1.0, 201);
                var      grid   = Grid1D.LineGrid(xNodes, false);
                grid.EdgeTagNames.Add(1, "supersonicOutlet");
                grid.DefineEdgeTags(X => 1);
                return(grid);
            };

            // Take inner values everywhere
            c.AddBoundaryCondition("supersonicOutlet");

            Material    material  = new Material(c);
            StateVector stateLeft = StateVector.FromPrimitiveQuantities(
                material, densityLeft, new Vector3D(velocityLeft, 0.0, 0.0), pressureLeft);
            StateVector stateRight = StateVector.FromPrimitiveQuantities(
                material, densityRight, new Vector3D(velocityRight, 0.0, 0.0), pressureRight);

            c.InitialValues_Evaluators.Add(
                Variables.Density,
                X => stateLeft.Density + (stateRight.Density - stateLeft.Density) * (X[0] - discontinuityPosition).Heaviside());
            c.InitialValues_Evaluators.Add(
                Variables.Velocity.xComponent,
                X => stateLeft.Velocity.x + (stateRight.Velocity.x - stateLeft.Velocity.x) * (X[0] - discontinuityPosition).Heaviside());
            c.InitialValues_Evaluators.Add(
                Variables.Pressure,
                X => stateLeft.Pressure + (stateRight.Pressure - stateLeft.Pressure) * (X[0] - discontinuityPosition).Heaviside());

            var    riemannSolver = new ExactRiemannSolver(stateLeft, stateRight, new Vector3D(1.0, 0.0, 0.0));
            double pStar, uStar;

            riemannSolver.GetStarRegionValues(out pStar, out uStar);

            c.Queries.Add("L2ErrorDensity", QueryLibrary.L2Error(
                              Variables.Density,
                              (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Density));
            c.Queries.Add("L2ErrorVelocity", QueryLibrary.L2Error(
                              Variables.Velocity.xComponent,
                              (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Velocity.x));
            c.Queries.Add("L2ErrorPressure", QueryLibrary.L2Error(
                              Variables.Pressure,
                              (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Pressure));

            c.dtMin         = 0.0;
            c.dtMax         = 1.0;
            c.CFLFraction   = 0.5;
            c.NoOfTimesteps = int.MaxValue;

            c.PrintInterval = 50;

            return(c);
        }
        private static CNSControl ShockTubeToro1Template(int dgDegree, ExplicitSchemes explicitScheme, int explicitOrder, int noOfCells = 50, double gridStretching = 0.0, bool twoD = false)
        {
            double densityLeft           = 1.0;
            double velocityLeft          = 0.0;
            double pressureLeft          = 1.0;
            double densityRight          = 0.125;
            double velocityRight         = 0.0;
            double pressureRight         = 0.1;
            double discontinuityPosition = 0.5;

            CNSControl c = new CNSControl();

            c.DbPath = null;
            //c.DbPath = @"c:\bosss_db\";
            c.savetodb = false;

            c.ActiveOperators    = Operators.Convection;
            c.ConvectiveFluxType = ConvectiveFluxTypes.OptimizedHLLC;

            c.EquationOfState = IdealGas.Air;
            c.MachNumber      = 1.0 / Math.Sqrt(c.EquationOfState.HeatCapacityRatio);
            c.ReynoldsNumber  = 1.0;
            c.PrandtlNumber   = 0.71;

            c.ExplicitScheme = explicitScheme;
            c.ExplicitOrder  = explicitOrder;

            c.AddVariable(CompressibleVariables.Density, dgDegree);
            c.AddVariable(CompressibleVariables.Momentum.xComponent, dgDegree);
            c.AddVariable(CompressibleVariables.Energy, dgDegree);
            c.AddVariable(CNSVariables.Velocity.xComponent, dgDegree);
            c.AddVariable(CNSVariables.Pressure, dgDegree);
            c.AddVariable(CNSVariables.Rank, 0);

            c.GridFunc = delegate {
                double xMin = 0.0;
                double xMax = 1.0;
                double yMin = 0.0;
                double yMax = 1.0;

                double[] xNodes;
                double[] yNodes;
                if (gridStretching > 0.0)
                {
                    xNodes = Grid1D.TanhSpacing(xMin, xMax, noOfCells + 1, gridStretching, true);
                    yNodes = Grid1D.TanhSpacing(yMin, yMax, 1 + 1, gridStretching, true);
                }
                else
                {
                    xNodes = GenericBlas.Linspace(xMin, xMax, noOfCells + 1);
                    yNodes = GenericBlas.Linspace(yMin, yMax, 1 + 1);
                }

                GridCommons grid;
                if (twoD)
                {
                    grid = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: false, periodicY: false);
                }
                else
                {
                    grid = Grid1D.LineGrid(xNodes, periodic: false);
                }

                // Boundary conditions
                grid.EdgeTagNames.Add(1, "AdiabaticSlipWall");
                grid.DefineEdgeTags(delegate(double[] _X) {
                    return(1);
                });
                return(grid);
            };
            c.AddBoundaryValue("AdiabaticSlipWall");

            Material    material  = c.GetMaterial();
            StateVector stateLeft = StateVector.FromPrimitiveQuantities(
                material, densityLeft, new Vector(velocityLeft, 0.0, 0.0), pressureLeft);
            StateVector stateRight = StateVector.FromPrimitiveQuantities(
                material, densityRight, new Vector(velocityRight, 0.0, 0.0), pressureRight);

            c.InitialValues_Evaluators.Add(
                CompressibleVariables.Density,
                X => stateLeft.Density + (stateRight.Density - stateLeft.Density) * (X[0] - discontinuityPosition).Heaviside());
            c.InitialValues_Evaluators.Add(
                CNSVariables.Velocity.xComponent,
                X => stateLeft.Velocity.x + (stateRight.Velocity.x - stateLeft.Velocity.x) * (X[0] - discontinuityPosition).Heaviside());
            c.InitialValues_Evaluators.Add(
                CNSVariables.Pressure,
                X => stateLeft.Pressure + (stateRight.Pressure - stateLeft.Pressure) * (X[0] - discontinuityPosition).Heaviside());
            if (twoD)
            {
                c.InitialValues_Evaluators.Add(CNSVariables.Velocity.yComponent, X => 0);
            }

            if (!twoD)
            {
                var riemannSolver = new ExactRiemannSolver(stateLeft, stateRight, new Vector(1.0, 0.0, 0.0));
                riemannSolver.GetStarRegionValues(out double pStar, out double uStar);

                c.Queries.Add("L2ErrorDensity", QueryLibrary.L2Error(
                                  CompressibleVariables.Density,
                                  (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Density));
                c.Queries.Add("L2ErrorVelocity", QueryLibrary.L2Error(
                                  CNSVariables.Velocity.xComponent,
                                  (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Velocity.x));
                c.Queries.Add("L2ErrorPressure", QueryLibrary.L2Error(
                                  CNSVariables.Pressure,
                                  (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Pressure));
            }

            c.dtMin = 0.0;
            c.dtMax = 1.0;
            //c.dtFixed = 1.0e-6;
            c.CFLFraction   = 0.1;
            c.Endtime       = 0.2;
            c.NoOfTimesteps = int.MaxValue;

            // Use METIS since ParMETIS is not installed on build server
            c.GridPartType = GridPartType.METIS;

            return(c);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Template of the control file for all shock tube tests using artificial viscosity
        /// </summary>
        /// <param name="convectiveFlux"></param>
        /// <param name="densityLeft"></param>
        /// <param name="velocityLeft"></param>
        /// <param name="pressureLeft"></param>
        /// <param name="densityRight"></param>
        /// <param name="velocityRight"></param>
        /// <param name="pressureRight"></param>
        /// <param name="discontinuityPosition"></param>
        /// <param name="explicitScheme"></param>
        /// <param name="explicitOrder"></param>
        /// <param name="numOfClusters"></param>
        /// <returns></returns>
        private static CNSControl GetArtificialViscosityShockTubeControlTemplate(ConvectiveFluxTypes convectiveFlux, double densityLeft, double velocityLeft, double pressureLeft, double densityRight, double velocityRight, double pressureRight, double discontinuityPosition, ExplicitSchemes explicitScheme, int explicitOrder, int numOfClusters)
        {
            CNSControl c = new CNSControl();

            c.DbPath   = null;
            c.savetodb = false;

            //c.DbPath = @"c:\bosss_db\";
            //c.savetodb = true;
            //c.saveperiod = 100;
            //c.PrintInterval = 100;

            c.ActiveOperators    = Operators.Convection | Operators.ArtificialViscosity;
            c.ConvectiveFluxType = convectiveFlux;

            c.EquationOfState = IdealGas.Air;
            c.MachNumber      = 1.0 / Math.Sqrt(c.EquationOfState.HeatCapacityRatio);
            c.ReynoldsNumber  = 1.0;
            c.PrandtlNumber   = 0.71;

            // Time stepping scheme
            c.ExplicitScheme = explicitScheme;
            c.ExplicitOrder  = explicitOrder;
            if (explicitScheme == ExplicitSchemes.LTS)
            {
                c.NumberOfSubGrids     = numOfClusters;
                c.ReclusteringInterval = 1;
                c.FluxCorrection       = false;
            }

            int dgDegree = 3;
            int noOfCellsPerDirection = 50;

            double   sensorLimit    = 1e-4;
            double   epsilon0       = 1.0;
            double   kappa          = 0.5;
            Variable sensorVariable = Variables.Density;

            c.ShockSensor            = new PerssonSensor(sensorVariable, sensorLimit);
            c.ArtificialViscosityLaw = new SmoothedHeavisideArtificialViscosityLaw(c.ShockSensor, dgDegree, sensorLimit, epsilon0, kappa);

            c.AddVariable(Variables.Density, dgDegree);
            c.AddVariable(Variables.Momentum.xComponent, dgDegree);
            c.AddVariable(Variables.Energy, dgDegree);
            c.AddVariable(Variables.Velocity.xComponent, dgDegree);
            c.AddVariable(Variables.Pressure, dgDegree);
            c.AddVariable(Variables.Entropy, dgDegree);
            c.AddVariable(Variables.Viscosity, dgDegree);
            c.AddVariable(Variables.ArtificialViscosity, 1);
            //c.AddVariable(Variables.Sensor, dgDegree);
            c.AddVariable(Variables.LocalMachNumber, dgDegree);
            if (c.ExplicitScheme.Equals(ExplicitSchemes.LTS))
            {
                c.AddVariable(Variables.LTSClusters, 0);
            }

            c.GridFunc = delegate {
                double[] xNodes = GenericBlas.Linspace(0.0, 1.0, noOfCellsPerDirection + 1);
                var      grid   = Grid1D.LineGrid(xNodes, periodic: false);

                // Boundary conditions
                grid.EdgeTagNames.Add(1, "AdiabaticSlipWall");
                grid.DefineEdgeTags(delegate(double[] _X) {
                    return(1);
                });
                return(grid);
            };

            c.AddBoundaryCondition("AdiabaticSlipWall");

            Material    material  = new Material(c);
            StateVector stateLeft = StateVector.FromPrimitiveQuantities(
                material, densityLeft, new Vector3D(velocityLeft, 0.0, 0.0), pressureLeft);
            StateVector stateRight = StateVector.FromPrimitiveQuantities(
                material, densityRight, new Vector3D(velocityRight, 0.0, 0.0), pressureRight);

            c.InitialValues_Evaluators.Add(
                Variables.Density,
                X => stateLeft.Density + (stateRight.Density - stateLeft.Density) * (X[0] - discontinuityPosition).Heaviside());
            c.InitialValues_Evaluators.Add(
                Variables.Velocity.xComponent,
                X => stateLeft.Velocity.x + (stateRight.Velocity.x - stateLeft.Velocity.x) * (X[0] - discontinuityPosition).Heaviside());
            c.InitialValues_Evaluators.Add(
                Variables.Pressure,
                X => stateLeft.Pressure + (stateRight.Pressure - stateLeft.Pressure) * (X[0] - discontinuityPosition).Heaviside());

            var    riemannSolver = new ExactRiemannSolver(stateLeft, stateRight, new Vector3D(1.0, 0.0, 0.0));
            double pStar, uStar;

            riemannSolver.GetStarRegionValues(out pStar, out uStar);

            c.Queries.Add("L2ErrorDensity", QueryLibrary.L2Error(
                              Variables.Density,
                              (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Density));
            c.Queries.Add("L2ErrorVelocity", QueryLibrary.L2Error(
                              Variables.Velocity.xComponent,
                              (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Velocity.x));
            c.Queries.Add("L2ErrorPressure", QueryLibrary.L2Error(
                              Variables.Pressure,
                              (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Pressure));

            c.dtMin   = 0.0;
            c.dtMax   = 1.0;
            c.dtFixed = 1.0e-6;
            c.Endtime = 5e-04;
            //c.NoOfTimesteps = 500;
            c.NoOfTimesteps = int.MaxValue;

            return(c);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Vectorized implementation of <see cref="GetBoundaryState(double, Vector, Vector, StateVector)"/>
        /// </summary>
        public override void GetBoundaryState(MultidimensionalArray[] StateOut, double time, MultidimensionalArray X, MultidimensionalArray Normals, MultidimensionalArray[] StateIn, int Offset, int NoOfEdges, bool normalFlipped, Material material)
        {
            //Convection.OptimizedHLLCFlux.SupersonicInlet.Start();
            if (X.Dimension != 3)
            {
                throw new ArgumentException();
            }
            int D         = X.GetLength(2);
            int NoOfNodes = X.GetLength(1);

            if (StateIn.Length != D + 2)
            {
                throw new ArgumentException();
            }
            if (StateOut.Length != D + 2)
            {
                throw new ArgumentException();
            }
            bool is3D = D >= 3;

            if (D < 2)
            {
                // base-implementation supports also 1D;
                // The implementation here is (a bit) tuned for performance, we only support 2D and 3D;
                // in 1D, performance is not so relevant anyway.
                base.GetBoundaryState(StateOut, time, X, Normals, StateIn, Offset, NoOfEdges, normalFlipped, material);
                return;
            }

            var Density   = StateOut[0];
            var Energy    = StateOut[D + 1];
            var MomentumX = StateOut[1];
            var MomentumY = StateOut[2];
            var MomentumZ = is3D ? StateOut[3] : null;

            var DensityIn = StateIn[0];
            //var EnergyIn = StateIn[D + 1];
            //var MomentumXin = StateIn[1];
            //var MomentumYin = StateIn[2];
            //var MomentumZin = is3D ? StateIn[3] : null;

            double MachScaling = material.EquationOfState.HeatCapacityRatio * material.MachNumber * material.MachNumber;

            double[] xLocal = new double[D];
            //Vector uOut = new Vector(D);
            for (int e = 0; e < NoOfEdges; e++)
            {
                int edge = e + Offset;

                // Loop over nodes
                for (int n = 0; n < NoOfNodes; n++)
                {
                    xLocal[0] = X[edge, n, 0];
                    xLocal[1] = X[edge, n, 1];
                    double uOut_x             = VelocityFunctions[0](xLocal, time);
                    double uOut_y             = VelocityFunctions[1](xLocal, time);
                    double uOut_z             = 0.0;
                    double velocity_AbsSquare = uOut_x * uOut_x + uOut_y * uOut_y;
                    if (is3D)
                    {
                        xLocal[2]           = X[edge, n, 2];
                        uOut_z              = VelocityFunctions[2](xLocal, time);
                        velocity_AbsSquare += uOut_z * uOut_z;
                    }

#if DEBUG
                    var uOutVec = new Vector(D);
                    uOutVec.x = uOut_x;
                    uOutVec.y = uOut_y;
                    uOutVec.z = uOut_z;
                    StateVector stateBoundary = StateVector.FromPrimitiveQuantities(
                        material,
                        DensityFunction(xLocal, time),
                        uOutVec,
                        PressureFunction(xLocal, time));
#endif
                    double density  = DensityFunction(xLocal, time);
                    double pressure = PressureFunction(xLocal, time);

                    Density[edge, n]   = density;
                    MomentumX[edge, n] = uOut_x * density;
                    MomentumY[edge, n] = uOut_y * density;
                    if (is3D)
                    {
                        MomentumZ[edge, n] = uOut_z * density;
                    }
                    Energy[edge, n] = material.EquationOfState.GetInnerEnergy(density, pressure) + 0.5 * MachScaling * density * velocity_AbsSquare;
#if DEBUG
                    Debug.Assert(Density[edge, n].RelErrorSmallerEps(stateBoundary.Density), "density error");
                    for (int d = 0; d < D; d++)
                    {
                        Debug.Assert(StateOut[d + 1][edge, n].RelErrorSmallerEps(stateBoundary.Momentum[d]), "momentum error");
                    }
                    Debug.Assert(Energy[edge, n].RelErrorSmallerEps(stateBoundary.Energy), "energy error");
#endif
                }
            }

            //Convection.OptimizedHLLCFlux.SupersonicInlet.Stop();
        }
Ejemplo n.º 14
0
        protected override void SetInitial()
        {
            int D = CompressibleEnvironment.NumberOfDimensions;
            CellQuadratureScheme scheme = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData));

            // Level set
            this.LevelSet.ProjectField(1.0, this.Control.LevelSetPos, scheme);
            this.LevelSetTracker.UpdateTracker();

            if (this.Control.uAInitPrimitive != null && this.Control.uBInitPrimitive != null)
            {
                // Initial conditions are specified in primitive variables

                // Density
                this.Density.Clear();
                this.Density.GetSpeciesShadowField("A").ProjectField(1.0, this.Control.uAInitPrimitive[0]);
                this.Density.GetSpeciesShadowField("B").ProjectField(1.0, this.Control.uBInitPrimitive[0]);

                // Momentum (rho * momentum vector)
                for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
                {
                    this.Momentum[d].Clear();
                    this.Momentum[d].GetSpeciesShadowField("A").ProjectField(1.0, X => this.Control.uAInitPrimitive[0](X) * this.Control.uAInitPrimitive[d + 1](X), scheme);
                    this.Momentum[d].GetSpeciesShadowField("B").ProjectField(1.0, X => this.Control.uBInitPrimitive[0](X) * this.Control.uBInitPrimitive[d + 1](X), scheme);
                }

                // Energy
                this.Energy.Clear();
                Energy.GetSpeciesShadowField("A").ProjectField(
                    1.0,
                    delegate(double[] X) {
                    double rho = this.Control.uAInitPrimitive[0](X);
                    double p   = this.Control.uAInitPrimitive[D + 1](X);
                    Vector u   = new Vector(D);
                    for (int d = 0; d < D; d++)
                    {
                        u[d] = this.Control.uAInitPrimitive[d + 1](X);
                    }

                    StateVector state = StateVector.FromPrimitiveQuantities(this.Control.GetMaterial(), rho, u, p);
                    return(state.Energy);
                },
                    scheme);
                Energy.GetSpeciesShadowField("B").ProjectField(
                    1.0,
                    delegate(double[] X) {
                    double rho = this.Control.uBInitPrimitive[0](X);
                    double p   = this.Control.uBInitPrimitive[D + 1](X);
                    Vector u   = new Vector(D);
                    for (int d = 0; d < D; d++)
                    {
                        u[d] = this.Control.uBInitPrimitive[d + 1](X);
                    }

                    StateVector state = StateVector.FromPrimitiveQuantities(this.Control.GetMaterial(), rho, u, p);
                    return(state.Energy);
                },
                    scheme);
            }
            else
            {
                // Initial conditions are specified in conservative variables

                // Density
                this.Density.Clear();
                this.Density.GetSpeciesShadowField("A").ProjectField(1.0, this.Control.uAInitConservative[0]);
                this.Density.GetSpeciesShadowField("B").ProjectField(1.0, this.Control.uBInitConservative[0]);

                // Momentum
                for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
                {
                    this.Momentum[d].Clear();
                    this.Momentum[d].GetSpeciesShadowField("A").ProjectField(1.0, this.Control.uAInitConservative[d + 1]);
                    this.Momentum[d].GetSpeciesShadowField("B").ProjectField(1.0, this.Control.uBInitConservative[d + 1]);
                }

                // Energy
                this.Energy.Clear();
                this.Energy.GetSpeciesShadowField("A").ProjectField(1.0, this.Control.uAInitConservative[D + 1]);
                this.Energy.GetSpeciesShadowField("B").ProjectField(1.0, this.Control.uBInitConservative[D + 1]);
            }

            // Update sensor values
            this.Sensor?.UpdateSensorValues(this.Density);

            // Update artificial viscosity
            if (this.ArtificialViscosityField != null)
            {
                UpdateArtificialViscosity();
            }
        }