예제 #1
0
        /// <summary>
        /// <see cref="INonlinearFlux.InnerEdgeFlux"/>
        /// </summary>
        public void InnerEdgeFlux(double time, Vector2D x, Vector2D n, double[] FunctionMatrixIn, double[] FunctionMatrixOut, out double AffineOffset)
        {
            Array.Clear(m_Arguments, 0, m_Arguments.Length);
            Array.Clear(m_Arguments2, 0, m_Arguments.Length);

            AffineOffset = m_Flux.InnerEdgeFlux(time, x, n, m_Arguments, m_Arguments2);
            for (int i = m_Arguments.Length - 1; i >= 0; i--)
            {
                m_Arguments[i]       = 1;
                FunctionMatrixIn[i]  = m_Flux.InnerEdgeFlux(time, x, n, m_Arguments, m_Arguments2);
                FunctionMatrixIn[i] -= AffineOffset;
                m_Arguments[i]       = 0;

                m_Arguments2[i]       = 1;
                FunctionMatrixOut[i]  = m_Flux.InnerEdgeFlux(time, x, n, m_Arguments, m_Arguments2);
                FunctionMatrixOut[i] -= AffineOffset;
                m_Arguments2[i]       = 0;
            }

            if (!_Flux)
            {
                Array.Clear(FunctionMatrixIn, 0, FunctionMatrixIn.Length);
                Array.Clear(FunctionMatrixOut, 0, FunctionMatrixOut.Length);
                AffineOffset = 0.0;
            }
            //if (!Neighbour) {
            //    Array.Clear(FunctionMatrixOut, 0, FunctionMatrixOut.Length);
            //    AffineOffset = 0.0;
            //}
            //if (!Local) {
            //    Array.Clear(FunctionMatrixIn, 0, FunctionMatrixIn.Length);
            //    AffineOffset = 0.0;
            //}
        }
예제 #2
0
        /// <summary>
        /// Evaluates the configured flux function (see
        /// <see cref="BoundaryConditionSourceFromINonlinearFlux.BoundaryConditionSourceFromINonlinearFlux(CNSControl, ISpeciesMap, BoundaryCondition, INonlinearFlux)"/>
        /// using the present flow state <paramref name="U"/> and the boundary
        /// value provided by the configured boundary condition.
        /// </summary>
        /// <param name="time"></param>
        /// <param name="x"></param>
        /// <param name="U"></param>
        /// <param name="IndexOffset"></param>
        /// <param name="FirstCellInd"></param>
        /// <param name="Lenght"></param>
        /// <param name="Output"></param>
        public void Source(double time, MultidimensionalArray x, MultidimensionalArray[] U, int IndexOffset, int FirstCellInd, int Lenght, MultidimensionalArray Output)
        {
            int D             = CompressibleEnvironment.NumberOfDimensions;
            int noOfNodes     = x.GetLength(1);
            int noOfVariables = D + 2;

            MultidimensionalArray normal = MultidimensionalArray.Create(Lenght, noOfNodes, D);

            MultidimensionalArray[] Uout = new MultidimensionalArray[noOfVariables];
            for (int i = 0; i < noOfVariables; i++)
            {
                Uout[i] = MultidimensionalArray.Create(Lenght, noOfNodes);
            }

            double[] xLocal   = new double[D];
            Material material = speciesMap.GetMaterial(double.NaN);

            for (int i = 0; i < Lenght; i++)
            {
                for (int j = 0; j < noOfNodes; j++)
                {
                    StateVector stateIn = new StateVector(material, U, i, j, CompressibleEnvironment.NumberOfDimensions);

                    Vector levelSetNormal = new Vector(CompressibleEnvironment.NumberOfDimensions);
                    int    offset         = CompressibleEnvironment.NumberOfDimensions + 2;
                    for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
                    {
                        levelSetNormal[d] = U[offset + d][i + IndexOffset, j];
                    }
                    levelSetNormal.Normalize();
                    Debug.Assert(Math.Abs(levelSetNormal.Abs() - 1.0) < 1e-13, "Abnormal normal vector");

                    for (int d = 0; d < D; d++)
                    {
                        xLocal[d]       = x[i + IndexOffset, j, d];
                        normal[i, j, d] = levelSetNormal[d];
                    }

                    StateVector stateOut = boundaryCondition.GetBoundaryState(time, xLocal, levelSetNormal, stateIn);
                    Debug.Assert(stateOut.IsValid, "Invalid boundary state");

                    Uout[0][i, j] = stateOut.Density;
                    for (int d = 0; d < D; d++)
                    {
                        Uout[d + 1][i, j] = stateOut.Momentum[d];
                    }
                    Uout[D + 1][i, j] = stateOut.Energy;
                }
            }

            fluxFunction.InnerEdgeFlux(time, -1, x, normal, U, Uout, IndexOffset, Lenght, Output);
        }
예제 #3
0
        /// <summary>
        /// Affine-linear flux function on an inner edge. An affine-linear flux
        /// must implemented as two matrices and an offset vector: The linear
        /// flux, in a mathematical notation is defined as InnerFlux(Uin,Uout) =
        /// BorderFlux(U) =  M_in*Uin + M_out*Uout + b
        /// where Uin and Uout are column vectors containing function values of
        /// other fields on the respective side of the concerned edge. Which
        /// fields in which order is specified by
        /// <see cref="IEquationComponent.ArgumentOrdering" /> property. In
        /// this implementation, the resulting flux solely depends on the
        /// implementation of <see cref="INonlinearFlux.InnerEdgeFlux"/> that
        /// has been supplied to the constructor.
        /// </summary>
        /// <param name="inp">
        /// A set of input parameters such as time, coordinate and values of
        /// parameters. Given as reference for performance reasons; DO NOT
        /// WRITE to this structure.
        /// </param>
        /// <param name="Uin"></param>
        /// <param name="Uout"></param>
        protected override double InnerEdgeFlux(ref CommonParams inp, double[] Uin, double[] Uout)
        {
            MultidimensionalArray refFlux = MultidimensionalArray.Create(1, 1);

            baseFlux.InnerEdgeFlux(
                0.0,
                inp.iEdge,
                MultidimensionalArray.CreateWrapper(inp.X, 1, 1, inp.D),
                MultidimensionalArray.CreateWrapper(inp.Normal, 1, inp.D),
                inp.Parameters_IN.Select(p =>
                                         MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                inp.Parameters_OUT.Select(p =>
                                          MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                0,
                1,
                refFlux);

            double[] FunctionMatrixIn = new double[inp.Parameters_IN.Length];
            for (int i = 0; i < inp.Parameters_IN.Length; i++)
            {
                double[] perturbedParameters = inp.Parameters_IN.CloneAs();
                double   stepSize            = GetStepSize(perturbedParameters[i]);
                perturbedParameters[i] += stepSize;

                MultidimensionalArray perturbedFlux = MultidimensionalArray.Create(1, 1);
                baseFlux.InnerEdgeFlux(
                    0.0,
                    inp.iEdge,
                    MultidimensionalArray.CreateWrapper(inp.X, 1, 1, inp.D),
                    MultidimensionalArray.CreateWrapper(inp.Normal, 1, inp.D),
                    perturbedParameters.Select(p =>
                                               MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                    inp.Parameters_OUT.Select(p =>
                                              MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                    0,
                    1,
                    perturbedFlux);

                FunctionMatrixIn[i] = (perturbedFlux[0, 0] - refFlux[0, 0]) / stepSize;
            }

            double[] FunctionMatrixOut = new double[inp.Parameters_OUT.Length];
            for (int i = 0; i < inp.Parameters_OUT.Length; i++)
            {
                double[] perturbedParameters = inp.Parameters_OUT.CloneAs();
                double   stepSize            = GetStepSize(perturbedParameters[i]);
                perturbedParameters[i] += stepSize;

                MultidimensionalArray perturbedFlux = MultidimensionalArray.Create(1, 1);
                baseFlux.InnerEdgeFlux(
                    0.0,
                    inp.iEdge,
                    MultidimensionalArray.CreateWrapper(inp.X, 1, 1, inp.D),
                    MultidimensionalArray.CreateWrapper(inp.Normal, 1, inp.D),
                    inp.Parameters_IN.Select(p =>
                                             MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                    perturbedParameters.Select(p =>
                                               MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                    0,
                    1,
                    perturbedFlux);

                FunctionMatrixOut[i] = (perturbedFlux[0, 0] - refFlux[0, 0]) / stepSize;
            }

            double result = refFlux[0, 0];

            for (int i = 0; i < inp.Parameters_IN.Length; i++)
            {
                result += FunctionMatrixIn[i] * (Uin[i] - inp.Parameters_IN[i])
                          + FunctionMatrixOut[i] * (Uout[i] - inp.Parameters_OUT[i]);
            }
            return(result);
        }
예제 #4
0
        //private static StreamWriter writer;

        /// <summary>
        /// Evaluates the configured flux function (see
        /// <see cref="BoundaryConditionSourceFromINonlinearFlux.BoundaryConditionSourceFromINonlinearFlux(CNSControl, ISpeciesMap, BoundaryCondition, INonlinearFlux)"/>
        /// using the present flow state <paramref name="U"/> and the boundary
        /// value provided by the configured boundary condition.
        /// </summary>
        /// <param name="time"></param>
        /// <param name="x"></param>
        /// <param name="U"></param>
        /// <param name="IndexOffset"></param>
        /// <param name="FirstCellInd"></param>
        /// <param name="Lenght"></param>
        /// <param name="Output"></param>
        public void Source(double time, MultidimensionalArray x, MultidimensionalArray[] U, int IndexOffset, int FirstCellInd, int Lenght, MultidimensionalArray Output)
        {
            int D             = CompressibleEnvironment.NumberOfDimensions;
            int noOfNodes     = x.GetLength(1);
            int noOfVariables = D + 2;

            MultidimensionalArray normal = MultidimensionalArray.Create(Lenght, noOfNodes, D);

            MultidimensionalArray[] Uout = new MultidimensionalArray[noOfVariables];
            for (int i = 0; i < noOfVariables; i++)
            {
                Uout[i] = MultidimensionalArray.Create(Lenght, noOfNodes);
            }

            //bool writeFluxes = false;

            double[] xLocal   = new double[D];
            Material material = speciesMap.GetMaterial(double.NaN);

            for (int i = 0; i < Lenght; i++)
            {
                for (int j = 0; j < noOfNodes; j++)
                {
                    StateVector stateIn = new StateVector(material, U, i, j, CompressibleEnvironment.NumberOfDimensions);

                    Vector levelSetNormal = new Vector(CompressibleEnvironment.NumberOfDimensions);
                    int    offset         = CompressibleEnvironment.NumberOfDimensions + 2;
                    for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
                    {
                        levelSetNormal[d] = U[offset + d][i + IndexOffset, j];
                    }
                    levelSetNormal.Normalize();
                    Debug.Assert(Math.Abs(levelSetNormal.Abs() - 1.0) < 1e-13, "Abnormal normal vector");

                    for (int d = 0; d < D; d++)
                    {
                        xLocal[d]       = x[i + IndexOffset, j, d];
                        normal[i, j, d] = levelSetNormal[d];
                    }

                    StateVector stateOut = boundaryCondition.GetBoundaryState(time, xLocal, levelSetNormal, stateIn);
                    Debug.Assert(stateOut.IsValid, "Invalid boundary state");

                    Uout[0][i, j] = stateOut.Density;
                    for (int d = 0; d < D; d++)
                    {
                        Uout[d + 1][i, j] = stateOut.Momentum[d];
                    }
                    Uout[D + 1][i, j] = stateOut.Energy;

                    //if (boundaryCondition is AdiabaticSlipWall) {
                    //    writeFluxes = true;
                    //}
                }
            }

            fluxFunction.InnerEdgeFlux(time, -1, x, normal, U, Uout, IndexOffset, Lenght, Output);

            //string bulkFluxName = null;
            //if (fluxFunction is OptimizedHLLCDensityFlux) {
            //    bulkFluxName = "rho";
            //} else if (fluxFunction is OptimizedHLLCMomentumFlux tmp) {
            //    bulkFluxName = "m";
            //} else if (fluxFunction is OptimizedHLLCEnergyFlux) {
            //    bulkFluxName = "rhoE";
            //}

            //if (writeFluxes) {
            //    for (int i = 0; i < x.Lengths[1]; i++) {
            //        //Console.WriteLine(String.Format("Flux at ({0:0.00000000}, {1:0.00000000}) = {2:0.00000000} \t normal = ({3:0.00000000}, {4:0.00000000})", x[0, i, 0], x[0, i, 1], Output[0, i], normal[0, i, 0], normal[0, i, 1]));

            //        // StreamWriter
            //        if (writer == null) {
            //            writer = new StreamWriter("CNS_Flux.txt");
            //            writer.WriteLine("bulkFlux \t\t\t x \t y \t \t \t \t ### \t n_x \t n_y \t flux \t \t \t \t ### \t Uin[0] \t Uin[1] \t Uin[2] \t Uin[3] \t ### \t Uout[0] \t Uout[1] \t Uout[2] \t Uout[3]");
            //        }

            //        string resultLine;
            //        resultLine = String.Format(bulkFluxName + "\t\t ### \t {0:0.000000} \t {1:0.000000} \t ### \t {2:0.000000} \t {3:0.000000} \t {4:0.000000} \t ### \t {5:0.000000} \t {6:0.000000} \t {7:0.000000} \t {8:0.000000} \t ### \t {9:0.000000} \t {10:0.000000} \t {11:0.000000} \t {12:0.000000}", x[0, i, 0], x[0, i, 1], normal[0, i, 0], normal[0, i, 1], Output[0, i], U[0][0, i], U[1][0, i], U[2][0, i], U[3][0, i], Uout[0][0, i], Uout[1][0, i], Uout[2][0, i], Uout[3][0, i]);
            //        writer.WriteLine(resultLine);
            //        writer.Flush();
            //    }
            //}
        }