예제 #1
0
        public void ComputeSolution(double endTime, double timeStep = 0.0)
        {
            double recentTime = 0.0;
            Matrix3D[] recentTimeDerivatives = new Matrix3D[elements.Length];
            double recentTimeStep = timeStep;

            while (recentTime < endTime)
            {
                if (timeStep == 0.0)
                {
                    double lambdaMax = 1.0;
                    recentTimeStep = ComputeTimeStep(CFL, lambdaMax);
                }

                if (recentTime + recentTimeStep > endTime)
                    recentTimeStep = endTime - recentTime;

                for (int i = 0; i < elements.Length; i++)
                    recentTimeDerivatives[i] = new Matrix3D(N + 1, N+1,  SysDim);

                //Runge Kutte
                for (int k = 0; k < 5; k++)
                {
                    for (int i = 0; i < elements.Length; i++)
                    {
                        Matrix3D solutionSystem = elements[i].Solution;
                        double nextTimeStep = recentTime + B[k] * recentTimeStep;
                        Matrix3D EvaluatedTimeDerivative = elements[i].ComputeTimeDerivative(nextTimeStep);

                        for (int sysIdx = 0; sysIdx < SysDim; sysIdx++)
                        {
                            Matrix tempTimeDerivative = A[k] * recentTimeDerivatives[i][sysIdx] + EvaluatedTimeDerivative[sysIdx];
                            recentTimeDerivatives[i][sysIdx] = tempTimeDerivative;
                            Matrix solution = solutionSystem[sysIdx] + C[k] * recentTimeStep * recentTimeDerivatives[i][sysIdx];
                            solutionSystem[sysIdx] = solution;
                        }

                        elements[i].Solution = solutionSystem;
                    }
                    //Rand updaten
                    for (int i = 0; i < elements.Length; i++)
                    {
                        elements[i].UpdateBorderValues();
                    }
                }
                recentTime += recentTimeStep;
            }
        }
예제 #2
0
        private void InitializeDGElement()
        {
            LegendrePolynomEvaluator.computeGaussLobattoNodesAndWeights(N, out Nodes, out IntegrationWeights);
            InitializeStartSolution();

            BottomBorderValues = new Matrix3D(N + 1, 1, SystemDimension);
            TopBorderValues = new Matrix3D(N + 1, 1, SystemDimension);
            LeftBorderValues = new Matrix3D(N + 1, 1, SystemDimension);
            RightBorderValues = new Matrix3D(N + 1, 1, SystemDimension);

            this.FluxF = new Matrix3D(N + 1, N + 1, SystemDimension);
            this.FluxG = new Matrix3D(N + 1, N + 1, SystemDimension);

            this.UpdateBorderValues();

            S = new Matrix(N + 1, N + 1);
            S[0, 0] = 1.0 / IntegrationWeights[0];
            S[N, N] = -1.0 / IntegrationWeights[N];

            interpolator = new LagrangeInterpolator(Nodes);
            DifferentialMatrix = interpolator.computeLagrangePolynomeDerivativeMatrix();
            DifferentialMatrixTransposed = !DifferentialMatrix;

            J = ((RightXBorder - LeftXBorder) * (TopYBorder - BottomYBorder)) / 4.0;
        }
예제 #3
0
 public void UpdateSolution(Matrix3D solution)
 {
     this.Solution = solution;
 }
예제 #4
0
        public void InitializeStartSolution()
        {
            Matrix3D originNodes = GetOriginNodes();
            Solution = new Matrix3D(N + 1, N + 1, SystemDimension);

            for(int i = 0; i < originNodes.DimX; i++)
            {
                for(int k = 0; k < originNodes.DimY; k++)
                {
                    Solution[i, k] = InitialFunction(originNodes[i, k]);
                }
            }
        }
예제 #5
0
 public Matrix3D GetOriginNodes()
 {
     Matrix3D originNodes = new Matrix3D(Nodes.Length, Nodes.Length, 2);
     for (int x = 0; x < Nodes.Length; x++)
         for (int y = 0; y < Nodes.Length; y++)
         {
             originNodes[x, y, 0] = MapToOriginX(Nodes[x]);
             originNodes[x, y, 1] = MapToOriginY(Nodes[y]);
         }
     return originNodes;
 }
예제 #6
0
        public Matrix3D EvaluateExactSolution(double time)
        {
            Matrix3D originNodes = GetOriginNodes();
            Matrix3D eva = new Matrix3D(N + 1, N + 1, SystemDimension);

            for (int i = 0; i < originNodes.DimX; i++)
            {
                for (int k = 0; k < originNodes.DimY; k++)
                {
                    eva[i, k] = ExactFunction(originNodes[i, k], time);
                }
            }

            return eva;
        }
예제 #7
0
        public Matrix3D ComputeTimeDerivative(double time)
        {
            Matrix3D TimeDerivative = new Matrix3D(N + 1, N + 1, SystemDimension);

            Matrix3D NumFluxFEvaluated = ComputeNumericalFluxFAndScale();

            Matrix3D NumFluxGEvaluated = ComputeNumericalFluxGAndScale();

            UpdateFluxesAndScale();

            for (int i = 0; i < SystemDimension; i++)
            {
                Matrix tempResult = new Matrix(N + 1, N + 1);

                tempResult = S * (NumFluxFEvaluated[i] - FluxF[i])
                            + (NumFluxGEvaluated[i] - FluxG[i]) * S
                            - FluxG[i] * DifferentialMatrixTransposed
                            - DifferentialMatrix * FluxF[i];

                tempResult = (1.0 / J) * tempResult;
                TimeDerivative[i] = tempResult;
            }

            return TimeDerivative;
        }
예제 #8
0
        public Matrix3D ComputeNumericalFluxGAndScaleTaskThree()
        {
            Matrix3D NumFluxG = new Matrix3D(N + 1, N + 1, SystemDimension);

            for (int i = 0; i < N + 1; i++)
            {
                Vector temp;
                if (this.TopYBorder == 1.0)
                {
                    temp = new Vector(3);
                    temp[2] = 2.0;

                    NumFluxG[i, N] = (Vector)(((RightXBorder - LeftXBorder) / 2.0) * NumFluxFunctionG(this.TopBorderValues[i, 0], temp));
                    NumFluxG[i, 0] = (Vector)(((RightXBorder - LeftXBorder) / 2.0) * NumFluxFunctionG(Bottom.TopBorderValues[i, 0], this.BottomBorderValues[i, 0]));

                }
                else if(this.BottomYBorder == 0.0 || (this.BottomYBorder == 0.4 && (this.RightXBorder <= 0.3 || this.LeftXBorder >= 0.7)))
                {
                    temp = this.BottomBorderValues[i, 0];
                    temp[0] = -1.0 * temp[0];

                    NumFluxG[i, 0] = (Vector)(((RightXBorder - LeftXBorder) / 2.0) * NumFluxFunctionG(temp, this.BottomBorderValues[i, 0]));
                    NumFluxG[i, N] = (Vector)(((RightXBorder - LeftXBorder) / 2.0) * NumFluxFunctionG(this.TopBorderValues[i, 0], Top.BottomBorderValues[i, 0]));
                }
                else
                {
                    NumFluxG[i, 0] = (Vector)(((RightXBorder - LeftXBorder) / 2.0) * NumFluxFunctionG(Bottom.TopBorderValues[i, 0], this.BottomBorderValues[i, 0]));
                    NumFluxG[i, N] = (Vector)(((RightXBorder - LeftXBorder) / 2.0) * NumFluxFunctionG(this.TopBorderValues[i, 0], Top.BottomBorderValues[i, 0]));
                }
            }
            return NumFluxG;
        }
예제 #9
0
        public Matrix3D ComputeNumericalFluxGAndScale()
        {
            Matrix3D NumFluxG = new Matrix3D(N + 1, N + 1, SystemDimension);

            for (int i = 0; i < N + 1; i++)
            {
                NumFluxG[i,0] = (Vector)(((RightXBorder - LeftXBorder) / 2.0) * NumFluxFunctionG(Bottom.TopBorderValues[i, 0],this.BottomBorderValues[i, 0]));
                NumFluxG[i,N] = (Vector)(((RightXBorder - LeftXBorder) / 2.0) * NumFluxFunctionG(this.TopBorderValues[i, 0], Top.BottomBorderValues[i, 0]));
            }
            return NumFluxG;
        }
예제 #10
0
        public Matrix3D ComputeNumericalFluxFAndScaleTaskThree()
        {
            Matrix3D NumFluxF = new Matrix3D(N + 1, N + 1, SystemDimension);

            for (int i = 0; i < N + 1; i++)
            {
                Vector temp;
                //Reflektierend
                if (this.LeftXBorder == 0.3 && this.TopYBorder <= 0.4)
                {
                    temp = this.LeftBorderValues[i, 0];
                    temp[1] = -1.0 * temp[1];
                    NumFluxF[0, i] = (Vector)(((TopYBorder - BottomYBorder) / 2.0) * NumFluxFunctionF(temp, this.LeftBorderValues[i, 0]));
                    NumFluxF[N, i] = (Vector)(((TopYBorder - BottomYBorder) / 2.0) * NumFluxFunctionF(this.RightBorderValues[i, 0], Right.LeftBorderValues[i, 0]));
                }
                else if (this.RightXBorder == 0.7 && this.TopYBorder <= 0.4)
                {
                    temp = this.RightBorderValues[i, 0];
                    temp[1] = -1.0 * temp[1];

                    NumFluxF[N, i] = (Vector)(((TopYBorder - BottomYBorder) / 2.0) * NumFluxFunctionF(this.RightBorderValues[i, 0], temp));
                    NumFluxF[0, i] = (Vector)(((TopYBorder - BottomYBorder) / 2.0) * NumFluxFunctionF(Left.RightBorderValues[i, 0], this.LeftBorderValues[i, 0]));

                }
                else if(this.RightXBorder == 1.0)
                {
                    temp = new Vector(3);
                    temp[2] = 2.0;
                    NumFluxF[N, i] = (Vector)(((TopYBorder - BottomYBorder) / 2.0) * NumFluxFunctionF(this.RightBorderValues[i, 0], temp));
                    NumFluxF[0, i] = (Vector)(((TopYBorder - BottomYBorder) / 2.0) * NumFluxFunctionF(Left.RightBorderValues[i, 0], this.LeftBorderValues[i, 0]));
                }
                else if(this.LeftXBorder == 0.0)
                {
                    temp = new Vector(3);
                    temp[2] = 2.0;
                    NumFluxF[0, i] = (Vector)(((TopYBorder - BottomYBorder) / 2.0) * NumFluxFunctionF(temp, this.LeftBorderValues[i, 0]));
                    NumFluxF[N, i] = (Vector)(((TopYBorder - BottomYBorder) / 2.0) * NumFluxFunctionF(this.RightBorderValues[i, 0], Right.LeftBorderValues[i, 0]));
                }
                else {
                    NumFluxF[0, i] = (Vector)(((TopYBorder - BottomYBorder) / 2.0) * NumFluxFunctionF(Left.RightBorderValues[i, 0], this.LeftBorderValues[i, 0]));
                    NumFluxF[N, i] = (Vector)(((TopYBorder - BottomYBorder) / 2.0) * NumFluxFunctionF(this.RightBorderValues[i, 0], Right.LeftBorderValues[i, 0]));
                }
            }

            return NumFluxF;
        }
예제 #11
0
        public Matrix3D ComputeNumericalFluxFAndScale()
        {
            Matrix3D NumFluxF = new Matrix3D(N + 1, N + 1, SystemDimension);

            for(int i = 0; i < N+1; i++)
            {
                NumFluxF[0, i] = (Vector)(((TopYBorder - BottomYBorder) / 2.0) * NumFluxFunctionF(Left.RightBorderValues[i, 0], this.LeftBorderValues[i, 0]));
                NumFluxF[N, i] = (Vector)(((TopYBorder - BottomYBorder) / 2.0) * NumFluxFunctionF(this.RightBorderValues[i, 0], Right.LeftBorderValues[i, 0]));
            }

            return NumFluxF;
        }