二维粗糙面的模拟
同一维粗糙面模拟一样,公式和基本理论神马的我就不敲了 有兴趣的同学可以参考
https://files.cnblogs.com/xd-jinjian/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%88%E5%BB%BA%E6%A8%A1%EF%BC%89.pdf
二维粗糙面的效果图如下所示

具体代码如下
// 2D_GS_RS.cpp : 定义控制台应用程序的入口点。
//*************本程序基于Monte Carlo方法生成二维高斯粗糙面**************
//by changwei
//**********************************************************************
#include "stdafx.h"
#include<iostream>
#include<iomanip> //格式化输出控制符必包含的头文件
#include<fstream>
#include<cmath>
#include<stdlib.h>
#include<complex>
#define M 64 //x方向采样点数
#define N 64 //y方向采样点数
#define Mdx 8 //x方向单位波长内的采样点数
#define Ndy 8 //y方向单位波长内的采样点数
#define pi 3.141592627 //定义常数pi
using namespace std;
complex<double> unit_i(0.0,1.0);
complex<double> unit_r(1.0,0.0);
//产生随机数的子函数
void random2(double start,double end,double seed,double *rand2) //在用二维数组作为形参时,必须指明列数
{
double s=65536.0;
double w=2053.0;
double v=13849.0;
double T=0.0;
int m;
for(int i=0;i<N*M;i++)
{
T=0.0;
for(int k=0;k<12;k++)
{
seed=w*seed+v;
m=seed/s;
seed=seed-m*s;
T=T+seed/s;
}
rand2[i]=start+end*(T-6.0);
}
return;
}
//2D傅里叶变换的子程序
void fft2D(double *data1,int *nn,int ndim,int isign)
{
int i1,i2,i2rev,i3,i3rev,ibit,idim,ifp1,ifp2,ip1,ip2,ip3,k1,k2,n,nprev,nrem,ntot;
double tempi,tempr;
double theta,wi,wpi,wpr,wr,wtemp;
ntot=1;
for(idim=0;idim<ndim;idim++)
{
ntot=ntot*nn[idim];
}
nprev=1;
for(idim=0;idim<ndim;idim++)
{
n=nn[idim];
nrem=ntot/(n*nprev);
ip1=2*nprev;
ip2=ip1*n;
ip3=ip2*nrem;
i2rev=1;
for(i2=1;i2<=ip2;i2=i2+ip1)
{
if(i2<i2rev)
{
for(i1=i2;i1<=i2+ip1-2;i1=i1+2)
{
for(i3=i1;i3<=ip3;i3=i3+ip2)
{
i3rev=i2rev+i3-i2;
tempr=data1[i3-1];
tempi=data1[i3];
data1[i3-1]=data1[i3rev-1];
data1[i3]=data1[i3rev];
data1[i3rev-1]=tempr;
data1[i3rev]=tempi;
}
}
}
ibit=ip2/2;
while((ibit>=ip1)&&(i2rev>ibit))
{
i2rev=i2rev-ibit;
ibit=ibit/2;
}
i2rev=i2rev+ibit;
}
ifp1=ip1;
while(ifp1<ip2)
{
ifp2=2*ifp1;
theta=isign*2.0*pi/(ifp2/ip1);
wpr=-2.0*sin(0.5*theta)*sin(0.5*theta);
wpi=sin(theta);
wr=1.0;
wi=0.0;
for(i3=1;i3<=ifp1;i3=i3+ip1)
{
for(i1=i3;i1<=i3+ip1-2;i1=i1+2)
{
for(i2=i1;i2<=ip3;i2=i2+ifp2)
{
k1=i2;
k2=k1+ifp1;
tempr=wr*data1[k2-1]-wi*data1[k2];
tempi=wr*data1[k2]+wi*data1[k2-1];
data1[k2-1]=data1[k1-1]-tempr;
data1[k2]=data1[k1]-tempi;
data1[k1-1]=data1[k1-1]+tempr;
data1[k1]=data1[k1]+tempi;
}
}
wtemp=wr;
wr=wr*wpr-wi*wpi+wr;
wi=wi*wpr+wtemp*wpi+wi;
}
ifp1=ifp2;
}
nprev=n*nprev;
}
return;
}
void Gauss_roughsurface(double hrms,double lcor,double seed,double dx,double dy,double x[][N],double y[][N],double z[][N])
{
double LX=M*dx; //粗糙面x方向的长度
double LY=N*dy; //粗糙面y方向的长度
double lx,ly; //x,y方向的相关长度
lx=lcor;
ly=lcor;
double kx,ky; //x,y方向的离散空间波数
double rand2[M*N]; //随机数
double s[M][N]; //功率谱
double dataF[2*M*N],dataFR[2*M*N],dataFG[2*M*N];
double tr1,tr2,ti1,ti2;
int Nij;
int NN[2];
NN[0]=N;
NN[1]=M;
//相关长度的变换
lcor=lcor/sqrt(dx*dx+dy*dy);
//计算坐标轴
for(int i=0;i<M;i++)
{
for(int j=0;j<N;j++)
{
x[i][j]=-LX/2.0+j*dx; //x方向坐标
y[i][j]=-LY/2.0+i*dy; //y方向坐标
}
}
//计算功率谱
/*for(int i=0;i<M;i++)
{
kx=2*pi*i/LX; //求x方向的空间波数
for(int j=0;j<N;j++)
{
ky=2*pi*j/LY; //求y方向的空间离散波数
s[i][j]=hrms*hrms*lx*ly/4.0/pi*exp(-kx*kx*lx*lx/4.0-ky*ky*ly*ly/4.0); //求高斯功率谱
//s[i][j]=2.0/sqrt(pi)/lcor*exp(-2.0*(x[i][j]*x[i][j]+y[i][j]*y[i][j])/lcor/lcor);
}
}*/
double tl1,tl2,temp1,temp2;
double xx,yy;
tl1=lcor*lcor/2.0;
tl2=sqrt(pi)*lcor/2.0;
for(int i=0;i<M;i++)
{
xx=-(M-1)/2+i-0.5;
for(int j=0;j<N;j++)
{
yy=-(N-1)/2+j-0.5;
temp1=xx*xx+yy*yy;
temp2=exp(-1.0*temp1/tl1);
s[i][j]=temp2/tl2;
}
}
//滤波函数的二维傅里叶变换
for(int i=0;i<M;i++)
{
for(int j=0;j<N;j++)
{
Nij=i*M+j;
dataFG[2*Nij]=s[i][j];
dataFG[2*Nij+1]=0.0;
}
}
fft2D(dataFG,NN,2,1);
//正态分布随机数并转换为傅里叶变换数组
random2(0.0,1.0,seed,rand2);
for(int i=0;i<M;i++)
{
for(int j=0;j<N;j++)
{
Nij=i*M+j;
dataFR[2*Nij]=rand2[Nij];
dataFR[2*Nij+1]=0.0;
}
}
fft2D(dataFR,NN,2,1);
//滤波函数与随机数的乘积及其二维逆傅里叶变换
for(int i=0;i<M*N;i++)
{
tr1=dataFR[2*i]*dataFG[2*i];
tr2=dataFR[2*i+1]*dataFG[2*i+1];
dataF[2*i]=tr1-tr2;
ti1=dataFR[2*i]*dataFG[2*i+1];
ti2=dataFR[2*i+1]*dataFG[2*i];
dataF[2*i+1]=ti1+ti2;
}
fft2D(dataF,NN,2,-1);
//高度函数的生成
for(int i=0;i<M;i++)
{
for(int j=0;j<N;j++)
{
Nij=i*M+j;
z[i][j]=hrms*dataF[2*Nij]/(M*N);
}
}
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
double wavespeed=3.0*pow(10.0,8); //波速
double frequence=1.0*pow(10.0,9); //频率
double lamd=wavespeed/frequence; //波长
double hrms=0.1*lamd; //均方根高度
double lcor=0.5*lamd; //相关长度
double seed=123.456; //随机数种子
double dx=lamd/Mdx; //x方向采样间距
double dy=lamd/Ndy; //y方向采样间距
double x[M][N]; //二维粗糙面x方向坐标
double y[M][N]; //二维粗糙面y方向坐标
double z[M][N]; //二维粗糙面高度起伏值
Gauss_roughsurface(hrms,lcor,seed,dx,dy,x,y,z);
ofstream foutrs("2DGRS.dat",ios::out);
for(int i=0;i<M;i++)
for(int j=0;j<N;j++)
foutrs<<setiosflags(ios::left)<<setw(8)<<x[i][j]<<setiosflags(ios::left)<<setw(8)<<y[i][j]<<setiosflags(ios::left)<<setw(8)<<z[i][j]<<endl;
foutrs.close();
return 0;
}

浙公网安备 33010602011771号