Example #1
0
        /// <summary>
        /// <see cref="INonlinearFlux.BorderEdgeFlux"/>
        /// </summary>
        /// <param name="time"></param>
        /// <param name="jEdge"></param>
        /// <param name="x"></param>
        /// <param name="normal"></param>
        /// <param name="normalFlipped"></param>
        /// <param name="EdgeTags"></param>
        /// <param name="EdgeTagsOffset"></param>
        /// <param name="Uin"></param>
        /// <param name="Offset"></param>
        /// <param name="Lenght"></param>
        /// <param name="Output"></param>
        public void BorderEdgeFlux(
            double time,
            int jEdge,
            MultidimensionalArray x,
            MultidimensionalArray normal,
            bool normalFlipped,
            byte[] EdgeTags,
            int EdgeTagsOffset,
            MultidimensionalArray[] Uin,
            int Offset,
            int Lenght,
            MultidimensionalArray Output)
        {
            int    NoOfNodes = Uin[0].GetLength(1);
            int    D         = CNSEnvironment.NumberOfDimensions;
            double sign      = normalFlipped ? -1.0 : 1.0;

            MultidimensionalArray[] Uout = new MultidimensionalArray[Uin.Length];
            for (int i = 0; i < Uin.Length; i++)
            {
                Uout[i] = MultidimensionalArray.Create(Uin[i].GetLength(0), Uin[i].GetLength(1));
            }

            Material material = speciesMap.GetMaterial(double.NaN);

            for (int e = 0; e < Lenght; e++)
            {
                int edge = e + Offset;
                for (int n = 0; n < NoOfNodes; n++)
                {
                    double[] xLocal      = new double[D];
                    double[] normalLocal = new double[D];
                    for (int d = 0; d < D; d++)
                    {
                        xLocal[d]      = x[edge, n, d];
                        normalLocal[d] = normal[edge, n, d] * sign;
                    }

                    StateVector stateIn       = new StateVector(material, Uin, edge, n);
                    StateVector stateBoundary = boundaryMap.GetBoundaryState(
                        EdgeTags[e + EdgeTagsOffset], time, xLocal, normalLocal, stateIn);

                    Uout[0][edge, n] = stateBoundary.Density;
                    for (int d = 0; d < D; d++)
                    {
                        Uout[d + 1][edge, n] = stateBoundary.Momentum[d];
                    }
                    Uout[D + 1][edge, n] = stateBoundary.Energy;
                }
            }

            InnerEdgeFlux(time, jEdge, x, normal, Uin, Uout, Offset, Lenght, Output);
        }
Example #2
0
        /// <summary>
        /// Weakly imposes the specific boundary condition for this boundary
        /// type (defined by the edge tag) by calculating the outer value via a
        /// subclass of <see cref="BoundaryCondition"/> and
        /// inserting it into
        /// <see cref="InnerEdgeFlux(double, double[], double[], double[], double[], int)"/>
        /// </summary>
        /// <param name="time">
        /// <see cref="NonlinearFlux.BorderEdgeFlux(double, double[], double[], byte, double[], int)"/>
        /// </param>
        /// <param name="x">
        /// <see cref="NonlinearFlux.BorderEdgeFlux(double, double[], double[], byte, double[], int)"/>
        /// </param>
        /// <param name="normal">
        /// <see cref="NonlinearFlux.BorderEdgeFlux(double, double[], double[], byte, double[], int)"/>
        /// </param>
        /// <param name="EdgeTag">
        /// <see cref="NonlinearFlux.BorderEdgeFlux(double, double[], double[], byte, double[], int)"/>
        /// </param>
        /// <param name="Uin">
        /// <see cref="NonlinearFlux.BorderEdgeFlux(double, double[], double[], byte, double[], int)"/>
        /// </param>
        /// <param name="jEdge">
        /// <see cref="NonlinearFlux.BorderEdgeFlux(double, double[], double[], byte, double[], int)"/>
        /// </param>
        /// <returns>
        /// <see cref="InnerEdgeFlux(double, double[], double[], double[], double[], int)"/>
        /// </returns>
        protected override double BorderEdgeFlux(double time, double[] x, double[] normal, byte EdgeTag, double[] Uin, int jEdge)
        {
            Vector3D Normal = new Vector3D();

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

            StateVector stateIn       = new StateVector(Uin, speciesMap.GetMaterial(double.NaN));
            StateVector stateBoundary = boundaryMap.GetBoundaryState(
                EdgeTag, time, x, normal, stateIn);

            double flux = InnerEdgeFlux(x, time, stateIn, stateBoundary, ref Normal, jEdge);

            Debug.Assert(!double.IsNaN(flux));
            return(flux);
        }
Example #3
0
        /// <summary>
        /// Weakly imposition of the boundary conditions (defined by the <see cref="CommonParamsBnd.EdgeTag"/>) by calculating the
        /// outer value via a subclass of <see cref="BoundaryCondition"/>
        /// </summary>
        /// <param name="inp">
        /// <see cref="IEdgeForm.BoundaryEdgeForm(ref CommonParamsBnd, double[], double[,], double, double[])"/></param>
        /// <param name="_uA">
        /// <see cref="IEdgeForm.BoundaryEdgeForm(ref CommonParamsBnd, double[], double[,], double, double[])"/></param>
        /// <param name="_Grad_uA">
        /// <see cref="IEdgeForm.BoundaryEdgeForm(ref CommonParamsBnd, double[], double[,], double, double[])"/></param>
        /// <param name="_vA">
        /// <see cref="IEdgeForm.BoundaryEdgeForm(ref CommonParamsBnd, double[], double[,], double, double[])"/></param>
        /// <param name="_Grad_vA">
        /// <see cref="IEdgeForm.BoundaryEdgeForm(ref CommonParamsBnd, double[], double[,], double, double[])"/></param>
        /// <returns>Flux across the boundary edge</returns>
        public double BoundaryEdgeForm(ref CommonParamsBnd inp, double[] _uA, double[,] _Grad_uA, double _vA, double[] _Grad_vA)
        {
            stateIn  = new StateVector(_uA, speciesMap.GetMaterial(double.NaN));
            stateOut = boundaryMap.GetBoundaryState(inp.EdgeTag, 0.0, inp.X, inp.Normal, stateIn);

            bool adiabaticWall = edgeTagBool[inp.EdgeTag];

            double[] _uBC = stateOut.ToArray();

            double ret     = 0.0;
            double Penalty = penalty(inp.jCellIn, -1);

            UpdateTensorComponent(stateOut, adiabaticWall, GTensorOut, inp.jCellIn);

            for (int k = 0; k < dimension; k++)
            {
                for (int l = 0; l < dimension; l++)
                {
                    for (int j = 0; j < dimension + 2; j++)
                    {
                        // _Grad_vB=0 per definition of the Ansatz functions
                        ret -= (GTensorOut[k, l, j] * _Grad_vA[k]) * (_uA[j] - _uBC[j]) * inp.Normal[l];
                        // Term 2
                        // Grad_uB = grad_uA, implicit boundary condition for viscous stress tensor!
                        ret -= (GTensorOut[k, l, j] * _Grad_uA[j, l]) * (_vA - 0) * inp.Normal[k];
                        //ret -= (G_Out[k, l][j] * grad_uB[j]) * (_vA - 0) * inp.Normale[k];
                        //Penalty-Term
                        ret += (GTensorOut[k, l, j]) * (_uA[j] - _uBC[j]) * inp.Normal[l] * Penalty * (_vA - 0) * inp.Normal[k];
                    }
                }
            }

#if DEBUG
            if (double.IsNaN(ret))
            {
                throw new System.Exception();
            }
#endif

            return(ret);
        }
Example #4
0
        void INonlinBoundaryEdgeForm_GradV.NonlinBoundaryEdge_GradV(ref EdgeFormParams efp,
                                                                    MultidimensionalArray[] Uin, MultidimensionalArray[] GradUin,
                                                                    MultidimensionalArray fin)
        {
            int NumOfCells = efp.Len;

            Debug.Assert(fin.GetLength(0) == NumOfCells);
            int NumOfNodes = fin.GetLength(1); // no of nodes per cell

            int NumOfArguments = this.ArgumentOrdering.Count;

            Debug.Assert(NumOfArguments == Uin.Length);
            Debug.Assert(NumOfArguments == GradUin.Length);

            double[] U_in = new double[NumOfArguments];
            double[] U_ot = new double[NumOfArguments];

            StateVector stateIn;
            StateVector stateOut;

            for (int cell = 0; cell < NumOfCells; cell++)   // loop over cells...
            {
                int iEdge = efp.e0 + cell;
                //double Penalty = penalty(gridDat.Edges.CellIndices[iEdge, 0], gridDat.Edges.CellIndices[iEdge, 1], gridDat.Cells.cj);

                for (int node = 0; node < NumOfNodes; node++)   // loop over nodes...

                {
                    for (int na = 0; na < NumOfArguments; na++)
                    {
                        U_in[na] = Uin[na][cell, node];
                    }
                    //Preparing for BoundaryState
                    double[] X       = new double[dimension];
                    double[] Normale = new double[dimension];
                    for (int i = 0; i < dimension; i++)
                    {
                        X[i]       = efp.Nodes[cell, node, i];
                        Normale[i] = efp.Normals[cell, node, i];
                    }

                    stateIn  = new StateVector(U_in, speciesMap.GetMaterial(double.NaN));
                    stateOut = boundaryMap.GetBoundaryState(efp.GridDat.iGeomEdges.EdgeTags[iEdge], 0.0, X, Normale, stateIn);
                    U_ot     = stateOut.ToArray();

                    bool adiabaticWall = edgeTagBool[efp.GridDat.iGeomEdges.EdgeTags[iEdge]];

                    unsafe
                    {
                        fixed(double *pGOut = GTensorOut)
                        {
                            UpdateBoundaryTensorComponent(U_ot, adiabaticWall, dimension, pGOut, material, cell);
                        }
                    }


                    //// Reference implementation
                    //for (int k = 0; k < dimension; k++) {
                    //    for (int l = 0; l < dimension; l++) {
                    //        double n = efp.Normals[cell, node, l];
                    //        for (int j = 0; j < NumOfArguments; j++) {
                    //            fin[cell, node, k] -= GTensorOut[k, l, j] * (U_in[j] - U_ot[j]) * n;
                    //        }
                    //    }
                    //}

                    unsafe
                    {
                        fixed(double *pGot = GTensorOut, gUin = U_in, gUot = U_ot)
                        {
                            double *pGotVar = pGot;

                            for (int k = 0; k < dimension; k++)
                            {
                                for (int l = 0; l < dimension; l++)
                                {
                                    double  n       = efp.Normals[cell, node, l];
                                    double *pUinVar = gUin;
                                    double *pUotVar = gUot;
                                    for (int j = 0; j < NumOfArguments; j++)
                                    {
                                        fin[cell, node, k] -= *pGotVar * (*pUinVar - *pUotVar) * n;
                                        //Increment Pointer
                                        pGotVar++;
                                        pUinVar++;
                                        pUotVar++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }