private void button3_Click(object sender, EventArgs e) { double x0, X, z0, Z; int x, z; x0 = Convert.ToDouble(textBox1.Text); X = Convert.ToDouble(textBox2.Text); z0 = Convert.ToDouble(textBox3.Text); Z = Convert.ToDouble(textBox4.Text); x = Convert.ToInt32(numericUpDown1.Value); z = Convert.ToInt32(numericUpDown2.Value); абКонсоль.SetPoles(абКонсоль.polesBeg, абКонсоль.polesEnd, абКонсоль.steproot, абКонсоль.epsroot, абКонсоль.countroot); DRealFunc f = (double a, double b) => абКонсоль.uRes(a, b).Abs; if (radioButton2.Checked) { f = (double a, double b) => абКонсоль.uRes(a, b).Re; } if (radioButton3.Checked) { f = (double a, double b) => абКонсоль.uRes(a, b).Im; } ИнтеграцияСДругимиПрограммами.CreatTableInExcel(f, x0, X, x, z0, Z, z); }
/// <summary> /// Кривая по всем своим параметрам /// </summary> /// <param name="a0"></param> /// <param name="b0"></param> /// <param name="uu"></param> /// <param name="vv"></param> /// <param name="BASEradius"></param> /// <param name="uuu"></param> /// <param name="vvv"></param> public Curve(double a0, double b0, Func <double, double> uu, Func <double, double> vv, double BASEradius, DRealFunc uuu, DRealFunc vvv, TripleFunc T, Func <double, double> end) : this(a0, b0, uu, vv, BASEradius) { this.U = uuu; this.V = vvv; this.S = T; this.End = end; }
/// <summary> /// Создать в Excel таблицу, по которой можно построить 3D поверхность /// </summary> /// <param name="f">Функция двух переменных</param> /// <param name="x0">Начало отрезка по первому аргументу</param> /// <param name="X">Конец отрезка по первому аргументу</param> /// <param name="xcount">Число шагов по первому аргументу</param> /// <param name="y0">Начало отрезка по второму аргументу</param> /// <param name="Y">Конец отрезка по второму аргументу</param> /// <param name="ycount">Число шагов по второму аргументу</param> public static void CreatTableInExcel(DRealFunc f, double x0, double X, int xcount, double y0, double Y, int ycount) { Application application = new Application(); application.Workbooks.Add(Type.Missing); Worksheet sheet = (Worksheet)application.Sheets[1]; var t = Type.Missing; double hx = (X - x0) / (xcount - 1), hy = (Y - y0) / (ycount - 1); for (int i = 0; i < ycount; i++) { sheet.Range[CharForExcel('B', i) + "2", t].Value2 = y0 + i * hy; } for (int i = 0; i < xcount; i++) { sheet.Range["A" + (3 + i).ToString(), t].Value2 = x0 + i * hx; } //for (int j = 0; j < xcount; j++) Parallel.For(0, xcount, (int j) => { for (int i = 0; i < ycount; i++) { sheet.Range[CharForExcel('B', i) + (3 + j).ToString(), t].Value2 = f(sheet.Range["A" + (3 + j).ToString(), t].Value2, sheet.Range[CharForExcel('B', i) + "2", t].Value2); } }); sheet.Range["A2", CharForExcel('B', ycount) + (3 + xcount).ToString()].Activate(); Excel.Chart chart = sheet.ChartObjects().Add(10, 10, 500, 500).Chart; chart.ChartType = Excel.XlChartType.xl3DArea; chart.SetSourceData(sheet.Range["A2", CharForExcel('B', ycount) + (3 + xcount).ToString()]); application.Visible = true; }
private static void Get2Tmp(ref double tmp, ref double tmpp, double step, Matrix A, double[] k, DRealFunc f, double u, double t, int r) { tmp = 0; tmpp = 0; for (int i = 0; i < k.Length; i++) { double tmp2 = 0; for (int j = 0; j < i; j++) { tmp2 += A[i, j + 1] * k[j]; } k[i] = f(t + A[i, 0] * step, u + tmp2 * step); tmp += A[r, i + 1] * k[i]; if (A.RowCount != A.ColCount) { tmpp += A[r + 1, i + 1] * k[i]; } } }
/// <summary> /// Решение уравнения теплопроводности явной либо неявной схемой /// </summary> /// <param name="f">Свободная фунция из уравнения</param> /// <param name="f1">Функция из первого краевого условия</param> /// <param name="f2">Функция из второго краевого условия</param> /// <param name="u0">Функция из начальных условий</param> /// <param name="u">Искомая функция (нужна для вычисления точности самого решения)</param> /// <param name="a">Коэффициент при второй производной</param> /// <param name="A1"></param> /// <param name="B1"></param> /// <param name="A2"></param> /// <param name="B2"></param> /// <param name="x0">Начало отрезка по пространству</param> /// <param name="X">Конец отрезка по пространству</param> /// <param name="t0">Начало отрезка по времени</param> /// <param name="T">Конец отрезка по времени</param> /// <param name="xcount">Число шагов по пространству</param> /// <param name="tcount">Число шагов по времени</param> /// <param name="accuracy">Выводимая точность</param> /// <param name="explict">Использовать явную схему либо нет</param> /// <returns></returns> public static List <NetFunc> TU(DRealFunc f, Func <double, double> f1, Func <double, double> f2, Func <double, double> u0, DRealFunc u, double a, double A1, double B1, double A2, double B2, double x0, double X, double t0, double T, int xcount, int tcount, out double accuracy, bool explict = true, bool thirdkind = true) { List <NetFunc> res = new List <NetFunc>(); double h = (X - x0) / (xcount - 1); double tau = (T - t0) / (tcount - 1); double[] x = new double[xcount], t = new double[tcount]; double[] value = new double[xcount]; for (int i = 0; i < xcount; i++) { x[i] = x0 + i * h; } for (int i = 0; i < tcount; i++) { t[i] = t0 + i * tau; } for (int i = 0; i < xcount; i++) { value[i] = u0(x[i]); } res.Add(new NetFunc(x, value)); double th = tau / h / h; double h1 = A1 + h * B1, h2 = A2 + h * B2; //(h1*h1.Reverse()).Show(); if (explict) { for (int i = 1; i < tcount; i++) { for (int j = 1; j < xcount - 1; j++) { value[j] = res[i - 1].Values[j] + a * th * (res[i - 1].Values[j - 1] - 2 * res[i - 1].Values[j] + res[i - 1].Values[j + 1]) + tau * f(t[i /*-1*/], x[j]); } if (thirdkind) { value[0] = (A1 * value[1] + h * f1(t[i])) / h1; value[xcount - 1] = (A2 * value[xcount - 2] + h * f2(t[i])) / h2; } else { value[0] = f1(t[i]) / B1; value[xcount - 1] = f2(t[i]) / B2; } res.Add(new NetFunc(x, value)); //new Vectors (res.Last().Values).Show(); } } else { SLAU s = new SLAU(xcount); for (int i = 1; i < tcount; i++) { if (thirdkind) { s.A[0, 0] = h1; s.A[0, 1] = -A1; s.b[0] = h * f1(t[i]); s.A[xcount - 1, xcount - 1] = h2; s.A[xcount - 1, xcount - 2] = -A2; s.b[xcount - 1] = h * f2(t[i]); } else { s.A[0, 0] = B1; s.b[0] = f1(t[i]); s.A[xcount - 1, xcount - 1] = B2; s.b[xcount - 1] = f2(t[i]); } for (int j = 1; j < xcount - 1; j++) { s.A[j, j - 2 + 1] = -a * th; s.A[j, j - 2 + 2] = a * 2 * th + 1; s.A[j, j - 2 + 3] = -a * th; s.b[j] = res[i - 1].Values[j - 2 + 2] + tau * f(t[i /*-1*/], x[j]); } s.ProRace(); // "".Show(); //s.Show(); value = s.x; res.Add(new NetFunc(x, value)); } } accuracy = 0; double[,] ac = new double[tcount, xcount]; for (int i = 0; i < t.Length; i++) { for (int j = 0; j < x.Length; j++) { ac[i, j] = Math.Abs(u(t[i], x[j]) - res[i].Values[j]); } } accuracy = new Matrix(ac).Max; return(res); }
/// <summary> /// Решение приведённого ОДУ первого порядка /// </summary> /// <param name="f">Свободная функция переменных u и x, где u - искомая функция</param> /// <param name="begin">Начальный аргумент по задаче Коши</param> /// <param name="end">Конечный аргумент</param> /// <param name="stepcount">Количество шагов интегрирования</param> /// <param name="M">Метод поиска решения</param> /// <param name="begval">Значение функции при начальном аргументе</param> public static NetFunc ODUsearch(DRealFunc f, double begin = 0, double end = 10, int stepcount = 50, Method M = Method.E1, double begval = 1, double eps = 0.00001) { double step = (end - begin) / (stepcount); return(ODUsearch(f, begin, end, step, M, begval)); }
/// <summary> /// Решение приведённого ОДУ первого порядка /// </summary> /// <param name="f">Свободная функция переменных u и x, где u - искомая функция</param> /// <param name="begin">Начальный аргумент по задаче Коши</param> /// <param name="end">Конечный аргумент</param> /// <param name="step">Шаг интегрирования</param> /// <param name="M">Метод поиска решения</param> /// <param name="begval">Значение функции при начальном аргументе</param> /// <param name="eps">Допустимый уровень расчётных погрешностей</param> /// <returns></returns> public static NetFunc ODUsearch(DRealFunc f, double begin = 0, double end = 10, double step = 0.01, Method M = Method.E1, double begval = 1, double eps = 0.0001, bool controllingstep = false) { double thisstep = step; NetFunc res = new NetFunc(); res.Add(new Point(begin, begval)); step *= Math.Sign(end - begin); Matrix A; switch (M) { case Method.E1: A = E1; break; case Method.E2: A = E2; break; case Method.H: A = H; break; case Method.RK3: A = RK3; break; case Method.RK4: A = Rk4; break; case Method.P38: A = P38; break; case Method.F: A = F; break; default: A = C; break; } int r = A.RowCount - 1; if (A.RowCount != A.ColCount) { r--; } while (begin < /*=*/ end) { double u = res.LastVal(); double t = res.LastArg(); double[] k = new double[r]; double tmp = 0, tmpp = 0; int stepchange = 0; //double[] h2 = new double[2]; //Get2Tmp(ref tmp, ref tmpp, step/2, A, k, f, u, t, r); //double uh1 = u + tmp * step/2; //Get2Tmp(ref tmp, ref tmpp, step / 2, A, k, f, uh1, t+step/2, r); //double uh2 = uh1 + tmp * step/2; Get2Tmp(ref tmp, ref tmpp, step, A, k, f, u, t, r); double val1 = u + step * tmp, val2 = u + step * tmpp; double R = 0.2 * Math.Abs(val1 - val2); if (controllingstep && stepchange <= MaxStepChange) { Get2Tmp(ref tmp, ref tmpp, step / 2, A, k, f, u, t, r); double uh1 = u + tmp * step / 2; Get2Tmp(ref tmp, ref tmpp, step / 2, A, k, f, uh1, t + step / 2, r); double uh2 = uh1 + tmp * step / 2; int p; switch (M) { case Method.E1: p = 1; break; case Method.E2: p = 2; break; case Method.H: p = 3; break; case Method.RK3: p = 3; break; case Method.RK4: p = 4; break; case Method.P38: p = 4; break; case Method.F: p = 3; break; default: p = 4; break; } double RR; if (A.RowCount != A.ColCount) { RR = Math.Abs((uh2 - val2) / (1 - 1.0 / Math.Pow(2, p))); } else { RR = Math.Abs((uh2 - val1) / (1 - 1.0 / Math.Pow(2, p))); } /*if (RR < eps / 64) { step *= 2; stepchange++; } * else */ if (RR > eps) { step /= 2; stepchange++; } else { begin += step; step = thisstep;//возврат к исходному шагу if (A.RowCount != A.ColCount) { res.Add(new Point(begin, val2)); } else { res.Add(new Point(begin, val1)); } } } else if (A.RowCount != A.ColCount && stepchange <= MaxStepChange) { if (R > eps) { step /= 2; stepchange++; } else if (R <= eps / 64) { begin += step; res.Add(new Point(begin, val2)); step *= 2; stepchange++; } else { begin += step; res.Add(new Point(begin, val2)); } } else { begin += step; res.Add(new Point(begin, val1)); } if (Math.Abs(end - begin) < step) { step = Math.Abs(end - begin); } } return(res); }
/// <summary> /// Кривая по своей параметризации и базовому радиусу /// </summary> /// <param name="a0"></param> /// <param name="b0"></param> /// <param name="uu"></param> /// <param name="vv"></param> /// <param name="BaseRadius"></param> public Curve(double a0, double b0, DRealFunc uu, DRealFunc vv, double BaseRadius) { a = a0; b = b0; U = uu; V = vv; radius = BaseRadius; }