最近在Ubuntu上做波场计算,但是每次都要放到MATLAB上显示,尤其是想要连续查看波场快照时候很多数据看完也没有用了,于是便用OPENGL做显示,下面是操作过程:
1.首先应该保证OPENGL库应该是安装的,没有安装执行
$ sudo apt-get install freeglut3-dev freeglut3
2.波场模拟使用有限差分
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include <GL/glut.h>
#define PI 3.141592654
#define Xn 300
#define Zn 300
#define Tn 600
#define Sx 150
#define Sz 150
double** array_2(int x,int y);
void free_2(double** m,int x,int y);
void Forward();
void DisplayWave(double **signal,int M,int N,double gain);
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE| GLUT_RGBA|GLUT_DEPTH);
glutInitWindowPosition(100,100);
glutInitWindowSize(600,600);
glutCreateWindow("DrawWave");
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glClearColor(1,1,1,1);
glClearDepth(1);
glutDisplayFunc(&Forward);
glutMainLoop();
return 0;
}
void Forward()
{
int i,j,k,m,n;
double Delta_h,Delta_t,Is_Center,r,f,alpha,beta1,beta2,A,gain;
double **u0,**u1,**u2,**v,*ricker;
u0 = array_2(Xn,Zn);//上一时刻波场值
u1 = array_2(Xn,Zn);//当前时刻波场值
u2 = array_2(Xn,Zn);//下一时刻波场值
v = array_2(Xn,Zn);//速度
ricker = (double*)calloc(Tn,sizeof(double));//雷克子波离散值
//-----------------数据初始化-------------//
Delta_h = 5;
Delta_t = 0.001;
Is_Center = 0;
r = 3.7;
f = 20;
gain=0.01;
//---------------速度赋初值---------------//
for(i=0;i<Xn;i++)
for(j=0;j<Zn;j++)
{
v[i][j]=1000.0;
}
//---------------波场计算------------------//
for(k=1;k<Tn;k++)
{
//----------雷克子波离散值------------//
ricker[k] = exp((-4*PI*PI*f*f*(k-200)*(k-200)*Delta_t*Delta_t)/(r*r))*cos(2*PI*f*Delta_t*(k-200));
DisplayWave(u1,Xn,Zn,gain);
for(i=2;i<Xn-2;i++)
for(j=2;j<Zn-2;j++)
{
Is_Center=0.0;
if(i==Sx&&j==Sz) Is_Center=1.0;
场值计算
alpha= (v[i][j]*v[i][j]*Delta_t*Delta_t)/(Delta_h*Delta_h);
beta1= (-1/12.0)*(u1[i-2][j]+u1[i+2][j])+(4.0/3)*(u1[i-1][j]+u1[i+1][j])-(5/2.0)*u1[i][j];
beta2= (-1/12.0)*(u1[i][j-2]+u1[i][j+2])+(4.0/3)*(u1[i][j-1]+u1[i][j+1])-(5/2.0)*u1[i][j];
u2[i][j] = 2*u1[i][j]-u0[i][j]+alpha*(beta1+beta2)+ricker[k]*Is_Center;
}
for(m=2;m<Xn-2;m++)
for(n=2;n<Zn-2;n++)
{
u0[m][n]=u1[m][n];
u1[m][n]=u2[m][n];
}
}
free_2(u0,Xn,Zn);
free_2(u1,Xn,Zn);
free_2(u2,Xn,Zn);
free(ricker);
free_2(v,Xn,Zn);
}
/
double** array_2(int x,int y)
{
double **m;
int i;
m=(double **)calloc(x,sizeof(double*));
for(i=0;i<x;i++)
{
m[i]=(double*)calloc(y,sizeof(double));
}
return m;
}
void free_2(double** m,int x,int y)
{
int i;
for(i=0;i<x;i++)
free(m[i]);
free(m);
}
void DisplayWave(double **signal,int M,int N,double gain)
{
int i,j,k;
double x,y,z,t;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//X-O-Z
glColor3f(1.0f, 0.0f, 0.0f);
for(i=0;i<M;i++)
{
x=i*(2.0/M)-1.0;
glBegin(GL_LINE_STRIP);
for(k=0;k<N;k++)
{
t=signal[i][k]/1.0;
z=(2.0f*k)/(1.0f*N)-1;
glVertex2f(x+t*gain,z);
}
glEnd();
}
glFlush();
glutSwapBuffers();
}
图1 波场快照
Makefile文件
wave: wave.o
gcc -o wave wave.o -lglut -lm
wave.o: wave.c
gcc -c wave.c
clean:
rm -f *.o
3.在目录下执行
$ make
然后运行程序
./wave
结果如图1所示。