目录

  • 第一章
    • ● 绪论
    • ● 计算误差
  • 数值积分
    • ● 引言
    • ● 梯形积分和辛普森积分
    • ● 反常积分
    • ● 高斯积分
    • ● 高维积分和数值微分
  • 非线性方程的数值解法
    • ● 引言
    • ● 二分法
    • ● 迭代法
    • ● 牛顿迭代法
    • ● 弦截法
    • ● 最优化方法
  • 线性方程组的解法
    • ● 高斯消去法
    • ● 高斯主元素消去法
    • ● LU分解法
    • ● 迭代法
    • ● 三对角矩阵的解法
  • 常微分方程的数值解法
    • ● 引言
    • ● 欧拉法
    • ● 龙格库塔法
    • ● 阿达姆斯法
    • ● 二阶常微分方程的边值问题
  • 偏微分方程的数值解法
    • ● 引言
    • ● 对流方程
    • ● 抛物线方程
    • ● 椭圆方程
  • 插值
    • ● 引言
    • ● 多项式插值
    • ● 拉格朗日插值
    • ● 牛顿均差插值
    • ● 三次样条插值
  • 蒙特卡罗方法
    • ● 引言
    • ● 蒙特卡罗方法的基本思想
    • ● 大数法则和中心极限定理
    • ● 蒙卡方法的基本步骤
    • ● 随机变量和随机数
  • 上机练习1
    • ● 上机内容
    • ● 谐振子与厄米多项式简介
    • ● 阶乘计算
    • ● 代码框架
    • ● 计算结果绘图
  • 上机练习2
    • ● 势阱和单摆周期的计算
    • ● 代码框架
    • ● 计算结果绘图
  • 上机练习3
    • ● 带空气阻力的抛体运动
    • ● 代码框架
    • ● 计算结果绘图
  • 上机练习4
    • ● 解线性方程组
    • ● 代码框架
  • 上机练习5
    • ● 解常微分方程
    • ● 代码框架
    • ● 计算结果绘图
  • 上机练习6
    • ● 热传导和亥姆霍兹方程
    • ● 代码框架
    • ● 计算结果绘图
  • 上机练习7
    • ● 插值和离散傅里叶变换
    • ● 离散傅里叶变换简介
    • ● 代码框架
    • ● 计算结果绘图
  • 上机练习8
    • ● 椭圆方程的MC解法
    • ● 代码框架
    • ● 计算结果绘图
代码框架

热传导方程

//数组声明、参数设定

const int nx=101, nt=8001;      

double dx=0.01, dt=0.01;

double lam=0.2;

double tf[nt][nx], x[nx];

//初始化数组

void initial_field(){

    for(int i=0; i<nx; i++){

        x[i] = (i-nx/2)*dx;   //注意选用的哪一组x范围?

        tf[0][i] = exp(-1*xi*xi/0.1);  //初始化

    }

}


int main(){

   //调用初始化数组的子函数

    ....

    //根据算法,进行时间推进计算,注意指标取值范围

    for(int n=0; n<nt-1; n++){

        for(int i=1; i<nx-1; i++){

            .......

        }

        //boundary condition set

        tf[n+1][0] = tf[n][0];

        tf[n+1][nx-1] = tf[n][nx-1];

    }

    //将计算数据写入文件

    FILE *fp=fopen("T_xt_3d.dat","w");

    ......

    fclose(fp);

     return  0;

}

椭圆方程或亥姆霍兹方程

//参数设定

const int nx=41, ny=41;

double dx=0.1, dy=0.1;  //x [0,4], y [0,4]

double rx=0.25, ry=0.25, rxy=...;  

double u[nx][ny], u0[nx][ny];   //注意2个数组,为什么?


//set initial field, with boundary condition

void initial_field(){

    //内部区域,注意指标范围

    for(int i=1; i<(nx-1); i++){

        for(int j=1; j<(ny-1); j++){

            u0[i][j] =  ...;      //设定初始估计值,例如:x^2 +y^3

        }

    }

 //边界处的设定, 

//左右边界:u0[0][j], u0[nx-1][j],  j=0,1,...,ny-1

....

//上下边界 u0[i][0], u0[i][ny-1],   i=0,1,...,nx-1

 ....

}


int main(){

    

   //调用初始化数组的子函数

    ....

 //进行迭代

    double df = 0;    //代表 u 和 u0的差

 //使用do {} while() 语句,利用df>err ?控制循环

    do{

        df = 0;

        for(int i=1; i<nx-1; i++){

            for(int j=1; j<ny-1; j++){

                double gij = sqrt(i*dx);

                double fij = pow(i*dx,2) + pow(j*dy,2) ;

                //进行迭代,即 u[i][j] 通过 u0[][]的计算得到 

                ....

                 //计算u[i][j]和u0[i][j],并累加到df

            }

        }

        df /= (nx-1)*(ny-1);   //平均到每一个矩阵元

        printf("df=%e \n", df);

        //交换 u 和 u0, 为下一次迭代做好准备

        for(int i=1; i<nx-1; i++){

            for(int j=1; j<ny-1; j++){

                double xu =u[i][j];

                u[i][j] = u0[i][j];

                u0[i][j] = xu;

            }

        }

    } while (df > 1.0e-6);

  //将数据写入文件。

    .....

     return  0;

}