Esempio n. 1
0
        /// <summary>
        /// Affine-linear flux function on a border edge; Boundary conditions
        /// are implemented here. An affine-linear flux must implemented as a
        /// matrix and an offset vector: The linear border flux, in a
        /// mathematical notation is defined as BorderFlux(U) =
        /// M_in*U + b, where U is a column vector containing function values
        /// of other fields. 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.BorderEdgeFlux"/> 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>
        protected override double BorderEdgeFlux(ref CommonParamsBnd inp, double[] Uin)
        {
            MultidimensionalArray refFlux = MultidimensionalArray.Create(1, 1);

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

            double[] FunctionMatrix = 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.BorderEdgeFlux(
                    0.0,
                    inp.iEdge,
                    MultidimensionalArray.CreateWrapper(inp.X, 1, 1, inp.D),
                    MultidimensionalArray.CreateWrapper(inp.Normal, 1, inp.D),
                    false,
                    new byte[] { inp.EdgeTag },
                    0,
                    perturbedParameters.Select(p =>
                                               MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                    0,
                    1,
                    perturbedFlux);

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

            double result = refFlux[0, 0];

            for (int i = 0; i < inp.Parameters_IN.Length; i++)
            {
                result += FunctionMatrix[i] * (Uin[i] - inp.Parameters_IN[i]);
            }
            return(result);
        }
Esempio n. 2
0
        /// <summary>
        /// <see cref="INonlinearFlux.BorderEdgeFlux"/>
        /// </summary>
        public void BorderEdgeFlux(double time, Vector2D x, Vector2D n, double[] FunctionMatrix, out double AffineOffset)
        {
            Array.Clear(m_Arguments, 0, m_Arguments.Length);
            AffineOffset = 0.0;

            AffineOffset = m_Flux.BorderEdgeFlux(time, x, n, m_Arguments);
            for (int i = m_Arguments.Length - 1; i >= 0; i--)
            {
                m_Arguments[i]     = 1;
                FunctionMatrix[i]  = m_Flux.BorderEdgeFlux(time, x, n, m_Arguments);
                FunctionMatrix[i] -= AffineOffset;
                m_Arguments[i]     = 0;
            }


            if ((!_Flux))
            {
                Array.Clear(FunctionMatrix, 0, FunctionMatrix.Length);
                AffineOffset = 0.0;
            }
        }
Esempio n. 3
0
            /// <summary>
            /// Evaluates the integrand by applying <see cref="flux"/>.
            /// </summary>
            protected override void Evaluate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult)
            {
                NodeSet QuadNodes  = QR.Nodes;
                int     D          = gridData.SpatialDimension;
                int     noOfFields = evaluators.Length;
                int     NoOfNodes  = QuadNodes.NoOfNodes;

                MultidimensionalArray fluxValues = MultidimensionalArray.Create(Length, NoOfNodes);

                MultidimensionalArray[] fieldValues = new MultidimensionalArray[evaluators.Length];
                for (int i = 0; i < evaluators.Length; i++)
                {
                    fieldValues[i] = MultidimensionalArray.Create(Length, NoOfNodes);
                }


                MultidimensionalArray globalCoordinates = MultidimensionalArray.Create(Length, NoOfNodes, D);

                int noOfNodes = QR.NoOfNodes;

                //MultidimensionalArray normals = MultidimensionalArray.Create(Length, noOfNodes, D);
                //gridData.Edges.GetNormals(i0, Length, m_NodeSetFamily[0].NodeSet, normals);
                var Normals = gridData.iGeomEdges.NormalsCache.GetNormals_Edge(QR.Nodes, i0, Length);


                // Loop over edges
                for (int i = 0; i < Length; i++)
                {
                    int cell = gridData.iGeomEdges.CellIndices[i + i0, 0];
                    int edge = gridData.iGeomEdges.FaceIndices[i + i0, 0];
                    int iTrf = gridData.iGeomEdges.Edge2CellTrafoIndex[i + i0, 0];

                    NodeSet CellNodes = QR.Nodes.GetVolumeNodeSet(base.GridDat, iTrf);

                    // Evaluate all fields
                    for (int j = 0; j < noOfFields; j++)
                    {
                        evaluators[j].Evaluate(cell, 1, CellNodes, fieldValues[j], i, 0.0);
                    }

                    // Compute global coordinates
                    gridData.TransformLocal2Global(CellNodes, cell, 1, globalCoordinates, i);

                    // Evaluate integrand
                    flux.BorderEdgeFlux(
                        0.0,
                        i0 + i,
                        globalCoordinates,
                        Normals,
                        false,
                        gridData.iGeomEdges.EdgeTags,
                        i0 + i,
                        fieldValues,
                        i,
                        1,
                        fluxValues);

                    // Save results
                    for (int j = 0; j < NoOfNodes; j++)
                    {
                        EvalResult[i, j, 0] = fluxValues[i, j];
                    }
                }
            }