public override void FillMatrix(TriDiagMatrix matrix, SequenceBundle bundle, Grid grid, double t, double dt) { var Un = bundle.CurrentLayer; for (int i = 1; i < matrix.N - 1; i++) { double ri = grid[i]; double rim1 = grid[i - 1]; double rip1 = grid[i + 1]; double Ui = Un[i]; double Uip1 = Un[i + 1]; double Uim1 = Un[i - 1]; double dr = grid.h; double ki = KFunc(ri, Ui, (Ui - Uim1) / dr); double kip1 = KFunc(rip1, Ui, (Uip1 - Ui) / dr); //matrix.A[i] =-dt/(dr*dr*ri)*(ki*ri);//-ki * dt / dr * (1 / dr - 1 / (2 * ri)-(ki-kim1)/dr); //matrix.C[i] = 1 + dt / (dr * dr * ri) * (kip1 * rip1 + ki * ri);//1 + ki * 2 * dt / (dr * dr); //matrix.B[i] = -dt / (dr * dr * ri) * (kip1 * rip1); //matrix.F[i] = Un[i] + dt * FFunc(ri, t); matrix.A[i] = -dt / (dr * dr) + dt / (ri * dr) * (1 - (ri * ki) / dr); matrix.C[i] = 1 + 2 * dt / (dr * dr) + dt / (ri * dr * dr) * (rip1 * kip1 + ri * ki); matrix.B[i] = -dt / (dr * dr) + dt / (ri * dr) * (-1 - (rip1 * kip1) / dr); matrix.F[i] = Un[i] + dt * FFunc(ri, t); } }
public void Solve(string name, TData data, IScheme1D scheme, double[] initialValues, BoundaryCondition leftBoundaryCondition, BoundaryCondition rightBoundaryCondition, params IContinue[] continues) { var bundle = (SequenceBundle)CreateBundle(name, data); try { bundle.BeginEdit(); bundle.Save(); double t = 0; int number = 0; var grid = bundle.GetGrid(); double dt = bundle.dt(); // Начальные условия. string layerName = GetLayerName(bundle, number); bundle.AddArray(layerName, number, initialValues); while (continues.All(c => c.Continue(bundle))) { number++; t += dt; var matrix = new TriDiagMatrix(grid.N); // На левой границе. SetLeftBoundaryCondition(matrix, leftBoundaryCondition, t); // Построение матрицы. scheme.FillMatrix(matrix, bundle, grid, t, dt); // На правой границе. SetRightBoundaryCondition(matrix, rightBoundaryCondition, t); // Решение СЛАУ методом прогонки. var newLayer = matrix.Solve(); // Добавления нового слоя в результат. layerName = GetLayerName(bundle, number); bundle.AddArray(layerName, number, newLayer); } OnSolved(bundle, true); } catch (Exception exception) { OnSolved(bundle, false, exception); } }
public override void FillMatrix(TriDiagMatrix matrix, SequenceBundle bundle, Grid grid, double t, double dt) { var Un = bundle.CurrentLayer; for (int i = 1; i < matrix.N - 1; i++) { double r = grid[i]; double dr = grid.h; double a2 = a * a; matrix.F[i] = Un[i - 1] * (a2 * dt / dr * (1 / dr - 1 / (2 * r))) + Un[i] * (1 - a2 * 2 * dt / (dr * dr)) + Un[i + 1] * (a2 * dt / dr * (1 / dr + 1 / (2 * r))) + dt * FFunc(r, t); matrix.C[i] = 1; } }
protected internal virtual void SetLeftBoundaryCondition(TriDiagMatrix matrix, BoundaryCondition leftBoundaryCondition, double t) { matrix.F[0] = leftBoundaryCondition.Value(t); switch (leftBoundaryCondition.Type) { case BoundaryConditionType.Dirichlet: matrix.C[0] = 1; break; case BoundaryConditionType.Neumann: matrix.B[0] = 1; matrix.C[0] = -1; break; } }
public override void FillMatrix(TriDiagMatrix matrix, SequenceBundle bundle, Grid grid, double t, double dt) { var Un = bundle.CurrentLayer; for (int i = 1; i < matrix.N - 1; i++) { double r = grid[i]; double dr = grid.h; double a2 = a * a; matrix.A[i] = -a2 * (dt / 2) / dr * (1 / dr - 1 / (2 * r)); matrix.C[i] = 1 + a2 * dt / (dr * dr); matrix.B[i] = -a2 * (dt / 2) / dr * (1 / dr + 1 / (2 * r)); matrix.F[i] = Un[i] + dt / 2 * (FFunc(r, t) + FFunc(r, t - dt)) + a2 * (dt / 2) * ((Un[i + 1] - 2 * Un[i] + Un[i - 1]) / (dr * dr) + 1 / r * (Un[i + 1] - Un[i - 1]) / (2 * dr)); } }
protected internal virtual void SetRightBoundaryCondition(TriDiagMatrix matrix, BoundaryCondition rightBoundaryCondition, double t) { // Правая граница. int N = matrix.N; matrix.F[N - 1] = rightBoundaryCondition.Value(t); switch (rightBoundaryCondition.Type) { case BoundaryConditionType.Dirichlet: matrix.C[N - 1] = 1; break; case BoundaryConditionType.Neumann: matrix.A[N - 1] = -1; matrix.C[N - 1] = 1; break; } }
public abstract void FillMatrix(TriDiagMatrix matrix, SequenceBundle bundle, Grid grid, double t, double dt);