C#,数值计算——偏微分方程,Mglin的计算方法与源程序

编程入门 行业动态 更新时间:2024-10-26 06:27:48

C#,数值计算——偏<a href=https://www.elefans.com/category/jswz/34/1766609.html style=微分方程,Mglin的计算方法与源程序"/>

C#,数值计算——偏微分方程,Mglin的计算方法与源程序

1 文本格式

using System;
using System.Collections.Generic;

namespace Legalsoft.Truffer
{
    public class Mglin
    {
        private int n { get; set; }
        private int ng { get; set; }
        private double[,] uj1 { get; set; }
        private List<double[,]> rho { get; set; } = new List<double[,]>();

        public Mglin(double[,] u, int ncycle)
        {
            this.n = u.GetLength(0);
            this.ng = 0;
            int nn = n;
            while ((nn >>= 1) != 0)
            {
                ng++;
            }
            if ((n - 1) != (1 << ng))
            {
                throw new Exception("n-1 must be a power of 2 in mglin.");
            }
            nn = n;
            int ngrid = ng - 1;
            //rho.resize(ng);
            rho = new List<double[,]>(ng);
            rho[ngrid] = new double[nn, nn];
            rho[ngrid] = u;
            while (nn > 3)
            {
                nn = nn / 2 + 1;
                rho[--ngrid] = new double[nn, nn];

                //rstrct(ref rho[ngrid], rho[ngrid + 1]);
                double[,] tmp = rho[ngrid];
                rstrct(tmp, rho[ngrid + 1]);
                //rho[ngrid] = new double[,](tmp);
                rho[ngrid] = Globals.CopyFrom(tmp);
            }
            nn = 3;
            double[,] uj = new double[nn, nn];
            slvsml(uj, rho[0]);
            for (int j = 1; j < ng; j++)
            {
                nn = 2 * nn - 1;
                uj1 = uj;
                uj = new double[nn, nn];
                interp(uj, uj1);
                uj1 = null;
                for (int jcycle = 0; jcycle < ncycle; jcycle++)
                {
                    mg(j, uj, rho[j]);
                }
            }
            u = uj;
        }

        public void interp(double[,] uf, double[,] uc)
        {
            int nf = uf.GetLength(0);
            int nc = nf / 2 + 1;
            for (int jc = 0; jc < nc; jc++)
            {
                for (int ic = 0; ic < nc; ic++)
                {
                    uf[2 * ic, 2 * jc] = uc[ic, jc];
                }
            }
            for (int jf = 0; jf < nf; jf += 2)
            {
                for (int iif = 1; iif < nf - 1; iif += 2)
                {
                    uf[iif, jf] = 0.5 * (uf[iif + 1, jf] + uf[iif - 1, jf]);
                }
            }
            for (int jf = 1; jf < nf - 1; jf += 2)
            {
                for (int iif = 0; iif < nf; iif++)
                {
                    uf[iif, jf] = 0.5 * (uf[iif, jf + 1] + uf[iif, jf - 1]);
                }
            }
        }

        public void addint(double[,] uf, double[,] uc, double[,] res)
        {
            int nf = uf.GetLength(0);
            interp(res, uc);
            for (int j = 0; j < nf; j++)
            {
                for (int i = 0; i < nf; i++)
                {
                    uf[i, j] += res[i, j];
                }
            }
        }

        public void slvsml(double[,] u, double[,] rhs)
        {
            double h = 0.5;
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    u[i, j] = 0.0;
                }
            }
            u[1, 1] = -h * h * rhs[1, 1] / 4.0;
        }

        public void relax(double[,] u, double[,] rhs)
        {
            int n = u.GetLength(0);
            double h = 1.0 / (n - 1);
            double h2 = h * h;
            for (int ipass = 0, jsw = 1; ipass < 2; ipass++, jsw = 3 - jsw)
            {
                for (int j = 1, isw = jsw; j < n - 1; j++, isw = 3 - isw)
                {
                    for (int i = isw; i < n - 1; i += 2)
                    {
                        u[i, j] = 0.25 * (u[i + 1, j] + u[i - 1, j] + u[i, j + 1] + u[i, j - 1] - h2 * rhs[i, j]);
                    }
                }
            }
        }

        public void resid(double[,] res, double[,] u, double[,] rhs)
        {
            int n = u.GetLength(0);
            double h = 1.0 / (n - 1);
            double h2i = 1.0 / (h * h);
            for (int j = 1; j < n - 1; j++)
            {
                for (int i = 1; i < n - 1; i++)
                {
                    res[i, j] = -h2i * (u[i + 1, j] + u[i - 1, j] + u[i, j + 1] + u[i, j - 1] - 4.0 * u[i, j]) + rhs[i, j];
                }
            }
            for (int i = 0; i < n; i++)
            {
                res[i, 0] = res[i, n - 1] = res[0, i] = res[n - 1, i] = 0.0;
            }
        }

        public void rstrct(double[,] uc, double[,] uf)
        {
            int nc = uc.GetLength(0);
            int ncc = 2 * nc - 2;
            for (int jf = 2, jc = 1; jc < nc - 1; jc++, jf += 2)
            {
                for (int iif = 2, ic = 1; ic < nc - 1; ic++, iif += 2)
                {
                    uc[ic, jc] = 0.5 * uf[iif, jf] + 0.125 * (uf[iif + 1, jf] + uf[iif - 1, jf] + uf[iif, jf + 1] + uf[iif, jf - 1]);
                }
            }
            for (int jc = 0, ic = 0; ic < nc; ic++, jc += 2)
            {
                uc[ic, 0] = uf[jc, 0];
                uc[ic, nc - 1] = uf[jc, ncc];
            }
            for (int jc = 0, ic = 0; ic < nc; ic++, jc += 2)
            {
                uc[0, ic] = uf[0, jc];
                uc[nc - 1, ic] = uf[ncc, jc];
            }
        }

        public void mg(int j, double[,] u, double[,] rhs)
        {
            const int NPRE = 1;
            const int NPOST = 1;
            int nf = u.GetLength(0);
            int nc = (nf + 1) / 2;
            if (j == 0)
            {
                slvsml(u, rhs);
            }
            else
            {
                double[,] res = new double[nc, nc];
                double[,] v = new double[nc, nc];
                double[,] temp = new double[nf, nf];
                for (int jpre = 0; jpre < NPRE; jpre++)
                {
                    relax(u, rhs);
                }
                resid(temp, u, rhs);
                rstrct(res, temp);
                mg(j - 1, v, res);
                addint(u, v, temp);
                for (int jpost = 0; jpost < NPOST; jpost++)
                {
                    relax(u, rhs);
                }
            }
        }
    }
}
 

2 代码格式

using System;
using System.Collections.Generic;namespace Legalsoft.Truffer
{public class Mglin{private int n { get; set; }private int ng { get; set; }private double[,] uj1 { get; set; }private List<double[,]> rho { get; set; } = new List<double[,]>();public Mglin(double[,] u, int ncycle){this.n = u.GetLength(0);this.ng = 0;int nn = n;while ((nn >>= 1) != 0){ng++;}if ((n - 1) != (1 << ng)){throw new Exception("n-1 must be a power of 2 in mglin.");}nn = n;int ngrid = ng - 1;//rho.resize(ng);rho = new List<double[,]>(ng);rho[ngrid] = new double[nn, nn];rho[ngrid] = u;while (nn > 3){nn = nn / 2 + 1;rho[--ngrid] = new double[nn, nn];//rstrct(ref rho[ngrid], rho[ngrid + 1]);double[,] tmp = rho[ngrid];rstrct(tmp, rho[ngrid + 1]);//rho[ngrid] = new double[,](tmp);rho[ngrid] = Globals.CopyFrom(tmp);}nn = 3;double[,] uj = new double[nn, nn];slvsml(uj, rho[0]);for (int j = 1; j < ng; j++){nn = 2 * nn - 1;uj1 = uj;uj = new double[nn, nn];interp(uj, uj1);uj1 = null;for (int jcycle = 0; jcycle < ncycle; jcycle++){mg(j, uj, rho[j]);}}u = uj;}public void interp(double[,] uf, double[,] uc){int nf = uf.GetLength(0);int nc = nf / 2 + 1;for (int jc = 0; jc < nc; jc++){for (int ic = 0; ic < nc; ic++){uf[2 * ic, 2 * jc] = uc[ic, jc];}}for (int jf = 0; jf < nf; jf += 2){for (int iif = 1; iif < nf - 1; iif += 2){uf[iif, jf] = 0.5 * (uf[iif + 1, jf] + uf[iif - 1, jf]);}}for (int jf = 1; jf < nf - 1; jf += 2){for (int iif = 0; iif < nf; iif++){uf[iif, jf] = 0.5 * (uf[iif, jf + 1] + uf[iif, jf - 1]);}}}public void addint(double[,] uf, double[,] uc, double[,] res){int nf = uf.GetLength(0);interp(res, uc);for (int j = 0; j < nf; j++){for (int i = 0; i < nf; i++){uf[i, j] += res[i, j];}}}public void slvsml(double[,] u, double[,] rhs){double h = 0.5;for (int i = 0; i < 3; i++){for (int j = 0; j < 3; j++){u[i, j] = 0.0;}}u[1, 1] = -h * h * rhs[1, 1] / 4.0;}public void relax(double[,] u, double[,] rhs){int n = u.GetLength(0);double h = 1.0 / (n - 1);double h2 = h * h;for (int ipass = 0, jsw = 1; ipass < 2; ipass++, jsw = 3 - jsw){for (int j = 1, isw = jsw; j < n - 1; j++, isw = 3 - isw){for (int i = isw; i < n - 1; i += 2){u[i, j] = 0.25 * (u[i + 1, j] + u[i - 1, j] + u[i, j + 1] + u[i, j - 1] - h2 * rhs[i, j]);}}}}public void resid(double[,] res, double[,] u, double[,] rhs){int n = u.GetLength(0);double h = 1.0 / (n - 1);double h2i = 1.0 / (h * h);for (int j = 1; j < n - 1; j++){for (int i = 1; i < n - 1; i++){res[i, j] = -h2i * (u[i + 1, j] + u[i - 1, j] + u[i, j + 1] + u[i, j - 1] - 4.0 * u[i, j]) + rhs[i, j];}}for (int i = 0; i < n; i++){res[i, 0] = res[i, n - 1] = res[0, i] = res[n - 1, i] = 0.0;}}public void rstrct(double[,] uc, double[,] uf){int nc = uc.GetLength(0);int ncc = 2 * nc - 2;for (int jf = 2, jc = 1; jc < nc - 1; jc++, jf += 2){for (int iif = 2, ic = 1; ic < nc - 1; ic++, iif += 2){uc[ic, jc] = 0.5 * uf[iif, jf] + 0.125 * (uf[iif + 1, jf] + uf[iif - 1, jf] + uf[iif, jf + 1] + uf[iif, jf - 1]);}}for (int jc = 0, ic = 0; ic < nc; ic++, jc += 2){uc[ic, 0] = uf[jc, 0];uc[ic, nc - 1] = uf[jc, ncc];}for (int jc = 0, ic = 0; ic < nc; ic++, jc += 2){uc[0, ic] = uf[0, jc];uc[nc - 1, ic] = uf[ncc, jc];}}public void mg(int j, double[,] u, double[,] rhs){const int NPRE = 1;const int NPOST = 1;int nf = u.GetLength(0);int nc = (nf + 1) / 2;if (j == 0){slvsml(u, rhs);}else{double[,] res = new double[nc, nc];double[,] v = new double[nc, nc];double[,] temp = new double[nf, nf];for (int jpre = 0; jpre < NPRE; jpre++){relax(u, rhs);}resid(temp, u, rhs);rstrct(res, temp);mg(j - 1, v, res);addint(u, v, temp);for (int jpost = 0; jpost < NPOST; jpost++){relax(u, rhs);}}}}
}

更多推荐

C#,数值计算——偏微分方程,Mglin的计算方法与源程序

本文发布于:2023-11-16 10:34:17,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1618857.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:微分方程   源程序   数值   计算方法   Mglin

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!