Beispiel #1
0
        /// <summary>
        /// The linear flux of the underlying PDE, expressed as F(U) =
        /// M * U + n. The flux may depend on the space
        /// variable <see cref="CommonParamsVol.Xglobal"/> and on the field
        /// values of <see cref="CommonParamsVol.Parameters" /> that can
        /// be defined in <see cref="IEquationComponent.ParameterOrdering" />.
        /// In this implementation, the resulting flux solely depends on the
        /// implementation of <see cref="INonlinearFlux.Flux"/> that
        /// has been supplied to the constructor.
        /// </summary>
        /// <param name="inp"></param>
        /// <param name="U"></param>
        /// <param name="output"></param>
        protected override void Flux(ref CommonParamsVol inp, double[] U, double[] output)
        {
            MultidimensionalArray refFlux = MultidimensionalArray.Create(1, 1, inp.D);

            baseFlux.Flux(
                0.0,
                MultidimensionalArray.CreateWrapper(inp.Xglobal, 1, 1, inp.D),
                inp.Parameters.Select(p =>
                                      MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                0,
                1,
                refFlux);

            double[,] FunctionMatrix = new double[inp.D, inp.Parameters.Length];
            for (int i = 0; i < inp.Parameters.Length; i++)
            {
                double[] perturbedParameters = inp.Parameters.CloneAs();
                double   stepSize            = GetStepSize(perturbedParameters[i]);
                perturbedParameters[i] += stepSize;

                MultidimensionalArray perturbedFlux = MultidimensionalArray.Create(1, 1, inp.D);
                baseFlux.Flux(
                    0.0,
                    MultidimensionalArray.CreateWrapper(inp.Xglobal, 1, 1, inp.D),
                    perturbedParameters.Select(p =>
                                               MultidimensionalArray.CreateWrapper(new double[] { p }, 1, 1)).ToArray(),
                    0,
                    1,
                    perturbedFlux);

                for (int d = 0; d < inp.D; d++)
                {
                    FunctionMatrix[d, i] = (perturbedFlux[0, 0, d] - refFlux[0, 0, d]) / stepSize;
                }
            }

            for (int d = 0; d < inp.D; d++)
            {
                output[d] = refFlux[0, 0, d];
                for (int i = 0; i < inp.Parameters.Length; i++)
                {
                    output[d] += FunctionMatrix[d, i] * (U[i] - inp.Parameters[i]);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// <see cref="INonlinearFlux.Flux"/>
        /// </summary>
        public void Flux(double time, Vector2D x, Vector2D[] FunctionMatrix, out Vector2D AffineOffset)
        {
            Array.Clear(m_Arguments, 0, m_Arguments.Length);

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


            if (!Local)
            {
                Array.Clear(FunctionMatrix, 0, FunctionMatrix.Length);
                AffineOffset = new Vector2D(0.0, 0.0);
            }
        }