/// <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]); } } }
/// <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); } }