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; } }
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; }
public void UpdateSolution(Matrix3D solution) { this.Solution = solution; }
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]); } } }
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; }
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; }
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; }
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; }
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; }
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; }
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; }