⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soanoise.cpp

📁 计算SOA中噪声性能的程序
💻 CPP
字号:
/*******************************************************************
  This program is to investigate the noise characteristics of 
  semiconductor optical amplifiers.
*******************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <malloc.h>
#include <math.h>
#include <complex.h>
#include <iostream.h>

int const N=4096;
double const PI=3.14159265;       
double const ph=1.05e-34;         //Plank constant
double const c=3.0e8;             //light velocity

double  an,achc,achv,ashb,ep,epchc,epchv,epshb,ts,tchc,tchv,tshb;
double  kappa,Psat,Esat,A,L,gama,vg,gn,N0,G0;
//G0: unsaturated power gain
//an,achc,achv,ashb: the linewidth enhancement factors
//ts: Carrier lifetime
//tchc,tchv,tshb: characteristic time constant with CH and SHB 
//epchc,epchv,epshb: gain compression factors
//ep: total Gain compression factor
//kappa: conversion factor from photon density to power, kappa=h*w*Aeff*vg
//Psat,Esat: the saturation power and energy. Psat=Isat*Aeff, Esat=Psat*ts
//A,L: the active area and the length of SOA
//gama: mode confinement factor
//vg: light velocity in SOA
//gn: differential gain coefficient
//N0: the carrier density at transparency

void soagain1(double, double, double *, double *, double *);
double gfunc(double, double, double, double);
void soagain2(double, double, double *, double *, double *);
double soagain3(double);



/*****************************************************************
     The main program
*****************************************************************/
void main()
{
	int     i,j,ch;
	double  Tp,Tpb,tdy,cc,En1,En2,P01,P02,T1,T2,Pav1,Pav2,t,dt,omiga,re,im,w0;
	//Tp: the pump pulse width
	//Tpb: the probe pulse width
	//tdy: the time dalay between pump and probe, tdy<0 corresponding to probe pulse precede to pump pulse
	//cc: phenomenological parameter compensate nonplane waveguide
	//En1,En2: the input pulse energy energy of the pump and probe signal
	//Pav1,Pav2: the input average power of the pump and probe signal
	//P01,P02: the input pulse peak power of the pump and probe signal
	//T1,T2: the period of the pump and probe pulses
	//y0: the initial gain coefficient
	//Tw: the time window width	
	//omiga: the beat frequency
	double  pue[N],pre[N],pin[N],dpin[N],g[N],g1[N],g3,nx[N],Wase,Pase;
	double  s1,s2,t1,B,g00,G,ef,SNR;
	m_complex  x1,x2,x3,pout1[N],f[N],k[N];
	//pue[],pre[]: store pump pulse and probe pulse respecively
	//pin[]: pin[]=pue[]+pre[]
	//dpin[N]: store the differential of pin
	//pout1[]: store conjugatd signal
	//g1[],g2[]: store the SOA gain
	//nx[]: store the noise parameter for SOA
	//Wase: the output noise power spectral density of the SOA
	//Pase: the output noise power of the SOA, Pase=Wase*B
	//s1,s2,s3,ft,t1: temporary variables
	FILE     *fp;	
	
	//Set the parameters of SOA
	ts=200.0;  //in ps
	tchc=0.7;
	tchv=0.0;
	tshb=0.07;
	an=4.0;
	achc=3.0;
	achv=0.0;
	ashb=0.0;
	epchc=1.0e-23;
	epchv=0.0;
	epshb=0.5e-23;
	ep=epchc+epchv+epshb;
//	epchc=epchv=epshb=0.0;
//	ep=0.0;
	A=0.4e-12;              //in m*m, that is 0.4 um*um
	L=2.0e-4;               //200um
	gama=0.3; 
	gn=3.0e-20;             //in m*m
	N0=1.0e24;              //in 1/(m*m*m) 
	Psat=28.4*1.0e-3;
	Esat=Psat*ts;           //in pJ
	cc=1.0;
	w0=2.0*PI*c/1.55e-6;
	vg=c/3.56;
	kappa=ph*w0*A/gama*vg;
	B=c*(1.0/1.55e-6-1.0/1.551e-6);   //the bandwidth of the optical bandpass filter is 3nm
/*
   do
   {
	   cout<<"The input signal is continuous wave or pulses:"<<endl;
	   cout<<"1.continuous wave;  2.pulses; Please choose:";
	   cin>>ch;      
   }while(ch!=1&&ch!=2);
*/
	ch=2;
	fp=fopen("c:\\temp\\x1.dat","wt");
	if(fp==NULL)
	{
		printf("File eta.dat open error!!\n");
		exit(1);
	}
	
	Tpb=10.0/1.665;
	Tp=10.0/1.665;
	T1=100.0/Tp;     //T1=100ps
	T2=T1;  
	dt=T1/N;

	j=0;
	tdy=0.0;
	omiga=1.5*2.0*PI;                    //in THz
//	Pav1=10.0;
	Pav1=10.0;
	for(Pav2=-20.0;Pav2<=20.0;Pav2=Pav2+1.0)
//	for(G=2.0;G<=40.0;G=G+1.0)
	{
		G=20.0;
		G0=pow(10.0,G/10.0);
		g00=log(G0)/L;

		//calculate ASE noise
		if(ch==1)              //pump is the continuous wave
		{
			g3=soagain3(pow(10.0,(Pav1-30.0)/10.0));
			Wase=(g00+gama*gn*N0)/g00*(g3-1)+gama*gn*N0/g00*g3*log(g3)*pow(10.0,(Pav1-30.0)/10.0)/Psat;
			Wase=(g00+gama*gn*N0)/g00*(g3-1);     //constant nsp
			Wase=ph*w0*Wase;
			P01=pow(10.0,(Pav1-30.0)/10.0);             //in W
			En2=pow(10.0,(Pav2-30.0)/10.0)*T2*Tp;       //in pJ
			P02=En2/(Tpb*sqrt(PI));                      //in W
			for(i=-N/2;i<N/2;i++)
			{
				t=dt*(double)i;
				pue[i+N/2]=P01;
				pre[i+N/2]=P02*exp(-t*t);
				pin[i+N/2]=pue[i+N/2]+pre[i+N/2];
			}
/*
			for(i=0;i<N;i++)
			{
				if(i==0)
					s1=pin[N-1];
				else
					s1=pin[i-1];
				if(i==N-1)
					s2=pin[0];
				else
					s2=pin[i+1];
				dpin[i]=(s2-s1)/(2.0*dt);
			}
			soagain1(Tp,dt,pin,dpin,g1);
			Wase=0.0;
			for(i=0;i<N;i++)
				Wase=Wase+g1[i]-1.0+gama*gn*N0*L/log(g1[i])*(ep/kappa*pin[i]*g1[i]*(log((1+ep/kappa*pin[i]*g1[i])/(1+ep/kappa*pin[i]))-log(g1[i]))+g1[i]-1.0);
			Wase=ph*w0*Wase/N;
*/		}
		else                   //pump is a train of optical pulses
		{
			En1=pow(10.0,(Pav1-30.0)/10.0)*T1*Tp;       //in pJ
			P01=En1/(Tp*sqrt(PI));
			En2=pow(10.0,(Pav2-30.0)/10.0)*T2*Tp;       //in pJ
			P02=En2/(Tpb*sqrt(PI));                      //in W
			for(i=-N/2;i<N/2;i++)
			{
				t=dt*(double)i;
				t1=t*Tp/Tpb-tdy;
				pue[i+N/2]=P01*exp(-t*t);
				pre[i+N/2]=P02*exp(-(t1*t1));
				pin[i+N/2]=pue[i+N/2]+pre[i+N/2];
			}
			for(i=0;i<N;i++)
			{
				if(i==0)
					s1=pin[N-1];
				else
					s1=pin[i-1];
				if(i==N-1)
					s2=pin[0];
				else
					s2=pin[i+1];
				dpin[i]=(s2-s1)/(2.0*dt);
			}

			soagain1(Tp,dt,pin,dpin,g1);
			Wase=0.0;
			for(i=0;i<N;i++)
				Wase=Wase+g1[i]-1.0+gama*gn*N0*L/log(g1[i])*(ep/kappa*pin[i]*g1[i]*(log((1+ep/kappa*pin[i]*g1[i])/(1+ep/kappa*pin[i]))-log(g1[i]))+g1[i]-1.0);
//			    Wase=Wase+(g1[i]-1.0)*(g00+gama*gn*N0)/g00;       //nsp=constant
			Wase=ph*w0*Wase/N;

//			soagain2(Tp,dt,pin,g1,nx);   //numerically calculate the noise property
//			Wase=0.0;
//			for(i=0;i<N;i++)
//				Wase=Wase+g1[i]-1+nx[i]*g1[i];
//			Wase=ph*w0*Wase/N;
		}
		Pase=Wase*B;

		//calculate FWM signal
		if(ch==1)
		{
			for(i=0;i<N;i++)
//				g[i]=log(g1[i]);
				g[i]=log(g3);
			for(i=0;i<N;i++)
			{
				x1=(exp(g[i])-1.0)/m_complex(1.0+exp(g[i])*ts/Esat*pue[i],-omiga*ts)*ts/Esat;
				x3=-an*x1;
				x2=m_complex(1.0,-achc)*epchc/kappa*Psat/m_complex(1.0,-omiga*tchc);
				x2=x2+m_complex(1.0,-achv)*epchv/kappa*Psat/m_complex(1.0,-omiga*tchv);
				x2=x2+m_complex(1.0,-ashb)*epshb/kappa*Psat/m_complex(1.0,-omiga*tshb);
				x2=(exp(g[i])-1.0)*x2*ts/Esat;
				f[i]=-0.5*(x1+x2+m_complex(0.0,1.0)*x3);
			}
			for(i=0;i<N;i++)
			{
				x1=m_complex(1.0,-an)*g[i]/2.0;
				x1=exp(x1);
				x1=x1*cc*f[i];
				s1=pue[i]*sqrt(pre[i]);
				pout1[i]=s1*x1;
			}
			s1=0.0;
			s2=0.0;
			for(i=0;i<N;i++)
			{
				s1=s1+pre[i]*dt*Tp;
				s2=s2+norm(pout1[i])*dt*Tp;
			}
		}
		else
		{
			for(i=0;i<N;i++)
				g[i]=log(g1[i]);
			for(i=0;i<N;i++)
			{
				x1=(exp(g[i])-1.0)/m_complex(1.0+exp(g[i])*ts/Esat*pue[i],-omiga*ts)*ts/Esat;
				x3=-an*x1;
				x2=m_complex(1.0,-achc)*epchc/kappa*Psat/m_complex(1.0,-omiga*tchc);
				x2=x2+m_complex(1.0,-achv)*epchv/kappa*Psat/m_complex(1.0,-omiga*tchv);
				x2=x2+m_complex(1.0,-ashb)*epshb/kappa*Psat/m_complex(1.0,-omiga*tshb);
				x2=(exp(g[i])-1.0)*x2*ts/Esat;
				f[i]=-0.5*(x1+x2+m_complex(0.0,1.0)*x3);
			}
			for(i=0;i<N;i++)
			{
				x1=m_complex(1.0,-an)*g[i]/2.0;
				x1=exp(x1);
				x1=x1*cc*f[i];
				s1=pue[i]*sqrt(pre[i]);
				pout1[i]=s1*x1;
			}
			s1=0.0;
			s2=0.0;
			for(i=0;i<N;i++)
			{
				s1=s1+pre[i]*dt*Tp;
				s2=s2+norm(pout1[i])*dt*Tp;
			}
		}
		Wase=Pase*T1*Tp;
		ef=10.0*log10(s2/s1);
		SNR=10.0*log10(s2/Wase);

//		for(i=0;i<N;i++)
//			fprintf(fp,"%lf\t%lf\n",dt*(i-N/2)*Tp,exp(g[i]));

		fprintf(fp,"%lf\t%lf\t%lf\n",Pav2,ef,SNR);
//		printf("Pave=%lf has been calculated!\n",Pav1);
//		fprintf(fp,"%lf\t%lf\n",Pav1,10.0*log10(Pase*1.0e3));
//		printf("G0=%lf has been calculated!\n",G);
	}
	
//	for(i=0;i<N;i++)
//		fprintf(fp,"%lf\t%lf\n",(double)(i-N/2)*dt*Tp,10.0*log10(g2[i]));
	fclose(fp);
	printf("OK!\n");

}
/*******************************************************************
             The end of main program
*******************************************************************/






/*******************************************************************
This procedure is to calculate the gain of SOA according to the 
input power in pulsed input case.
The boundary condition is a[0]=a[n-1]
*******************************************************************/
void soagain1(double T0, double dt, double *pin, double *dpin, double *a)
//g0: input parameter, the initial gain coefficient
//T0: input parameter, the pulse width
//dt: input parameter, the step
//pin[]: input parameter, store the input signal power profile pin(t)
//dpin[]: input parameter, store the differential of the input signal power profile pin(t)
//a[]: output parameter, store the gain coefficient of SOA 
{
   int i, i0;
   double k1, k2, k3, k4, g0, dg0, g, dg;

	   g=log(G0);
	   dg0=g/2.0;
	   g0=g;
	   a[0]=g0;
	   i0=0;
	   for(i=2;i<N;i=i+2)
	   {
		   k1=2.0*dt*gfunc(g0,T0,pin[i0],dpin[i0]);
		   k2=2.0*dt*gfunc(g0+0.5*k1,T0,pin[i0+1],dpin[i0+1]);
		   k3=2.0*dt*gfunc(g0+0.5*k2,T0,pin[i0+1],dpin[i0+1]);
		   k4=2.0*dt*gfunc(g0+k3,T0,pin[i0+2],dpin[i0+2]);
		   g0=g0+(k1+2.0*k2+2.0*k3+k4)/6.0;
		   i0=i0+2;
		   a[i]=g0;
	   }
	   a[1]=(a[0]+a[2])/2.0;
	   i0=1;
	   g0=a[1];
	   for(i=3;i<N;i=i+2)
	   {
		   k1=2.0*dt*gfunc(g0,T0,pin[i0],dpin[i0]);
		   k2=2.0*dt*gfunc(g0+0.5*k1,T0,pin[i0+1],dpin[i0+1]);
		   k3=2.0*dt*gfunc(g0+0.5*k2,T0,pin[i0+1],dpin[i0+1]);
		   k4=2.0*dt*gfunc(g0+k3,T0,pin[i0+2],dpin[i0+2]);
		   g0=g0+(k1+2.0*k2+2.0*k3+k4)/6.0;
		   i0=i0+2;
		   a[i]=g0;
	   }
	   dg=fabs(a[0]-a[N-1]);

	   while(dg>0.001)
	   {
		   if(a[0]>a[N-1])
			   g=g-dg0;
		   else
			   g=g+dg0;
		   dg0=dg0/2.0;
		   g0=g;
		   i0=0;
		   a[0]=g0;
		   for(i=2;i<N;i=i+2)
		   {
			   k1=2.0*dt*gfunc(g0,T0,pin[i0],dpin[i0]);
			   k2=2.0*dt*gfunc(g0+0.5*k1,T0,pin[i0+1],dpin[i0+1]);
			   k3=2.0*dt*gfunc(g0+0.5*k2,T0,pin[i0+1],dpin[i0+1]);
			   k4=2.0*dt*gfunc(g0+k3,T0,pin[i0+2],dpin[i0+2]);
			   g0=g0+(k1+2.0*k2+2.0*k3+k4)/6.0;
			   i0=i0+2;
			   a[i]=g0;
		   }
		   a[1]=(a[0]+a[2])/2.0;
		   i0=1;
		   g0=a[1];
		   for(i=3;i<N;i=i+2)
		   {
			   k1=2.0*dt*gfunc(g0,T0,pin[i0],dpin[i0]);
			   k2=2.0*dt*gfunc(g0+0.5*k1,T0,pin[i0+1],dpin[i0+1]);
			   k3=2.0*dt*gfunc(g0+0.5*k2,T0,pin[i0+1],dpin[i0+1]);
			   k4=2.0*dt*gfunc(g0+k3,T0,pin[i0+2],dpin[i0+2]);
			   g0=g0+(k1+2.0*k2+2.0*k3+k4)/6.0;
			   i0=i0+2;
			   a[i]=g0;
		   }
		   dg=fabs(a[0]-a[N-1]);
	   }

	   for(i=0;i<N;i++)
		   a[i]=exp(a[i]);
}
/**************************************************************************/




/*************************************************************************
the SOA gain differential equation when t0<=tc
dy/dt=f(t)=gfunc. The parameters are quoted from ref.2
*************************************************************************/
double gfunc(double y0, double T0, double pin, double dpin)
//g0: the initial gain coefficient of SOA
//T0: the width of the input pulse, that is, the normalized time
//pin: the input pulse power
//dpin: the differential of the input pulse power
{
	double  y,g00;

	g00=log(G0);

	y=T0/ts*(g00-y0)-ep/kappa*(exp(y0)-1.0)*dpin-(exp(y0)-1.0)*pin*(ep/kappa*T0/ts+T0/Esat);
	y=y/(1.0+ep/kappa*exp(y0)*pin);
	return(y);
}
/**************************************************************************/





/*****************************************************************************
This procedure is to calculate the gain of SOA by solving the following 
equations:
dg/dt=(g0-g)/ts-g/(1+ep*P)*P/Esat
dP/dz=g/(1+ep*P)*P
Here P and g are the functions of z and t
the gain G(t)=P(L,t)/P(0,t), where L is the lengtg of SOA
*****************************************************************************/
void soagain2(double Tp,double dt, double *pin, double *G, double *nx)
//Tp,dt: the input parameters
//pin[]: the input parameter, the optical input power profile
//G[]: the output parameter, the gain of SOA
//nx[]: the output parameter for calaulation of noise of SOA
{
	int    i;
	double g00,g0[N],g1[N],h[N],P0[N],P1[N],z,dL,x0,flag;
	
	g00=log(G0)/L;
	dL=L/4000.0;

	for(i=0;i<N;i++)
	{
		g0[i]=g00;
		P0[i]=pin[i];
	}

	for(i=0;i<N;i++)
	{
		nx[i]=0.0;
		h[i]=0.0;
	}

	for(z=0;z<=L;z=z+dL)
	{
		for(i=0;i<N;i++)
			P1[i]=P0[i]+g0[i]*dL*P0[i]/(1.0+ep/kappa*P0[i]);
/*
		g1[0]=g0[0];
		for(i=1;i<N;i++)
			g1[i]=g1[i-1]+((g00-g1[i-1])/ts-g1[i-1]/(1.0+ep/kappa*P1[i-1])*P1[i-1]/Esat)*dt*Tp;
*/
		x0=g0[N-1];
		g1[0]=x0;
		for(i=1;i<N;i++)
			g1[i]=g1[i-1]+((g00-g1[i-1])/ts-g1[i-1]/(1.0+ep/kappa*P1[i-1])*P1[i-1]/Esat)*dt*Tp;
		x0=g1[N-1]+((g00-g1[N-1])/ts-g1[N-1]/(1.0+ep/kappa*P1[N-1])*P1[N-1]/Esat)*dt*Tp;
	    flag=(g1[0]-x0)/g1[0];
		while(flag>1.0e-4)
		{
			g1[0]=x0;
			for(i=1;i<N;i++)
				g1[i]=g1[i-1]+((g00-g1[i-1])/ts-g1[i-1]/(1.0+ep/kappa*P1[i-1])*P1[i-1]/Esat)*dt*Tp;
			x0=g1[N-1]+((g00-g1[N-1])/ts-g1[N-1]/(1.0+ep/kappa*P1[N-1])*P1[N-1]/Esat)*dt*Tp;
			flag=(g1[0]-x0)/g1[0];
		}
		for(i=0;i<N;i++)
		{
			g0[i]=g1[i];
			P0[i]=P1[i];
		}
		for(i=0;i<N;i++)
			h[i]=h[i]+g0[i]/(1.0+ep/kappa*P0[i])*dL;

		for(i=0;i<N;i++)
		{
			nx[i]=nx[i]+dL*exp(-h[i])/(1.0+ep/kappa*P0[i]);
		}
	}
	for(i=0;i<N;i++)
		G[i]=exp(h[i]);
	for(i=0;i<N;i++)
		nx[i]=gama*gn*N0*nx[i];
}
/*****************************************************************************************
The end of procedure soagain2
*****************************************************************************************/






/*****************************************************************************************
This procedure is to calculate the gain of SOA in the injection of the continuous wave
*****************************************************************************************/
double soagain3(double p)
//p is the input parameter, the power of the input continuous wave
//This procedure retuen the gain of SOA
{
	double z,dL,g00,p0,G,g1;
/*
	FILE   *fp;
	fp=fopen("e:\\temp\\n1.dat","wt");
	if(fp==NULL)
	{
		printf("File eta.dat open error!!\n");
		exit(1);
	}
*/	
	g00=log(G0)/L;
	dL=L/4000.0;
	p0=p;
	for(z=0;z<L;z=z+dL)
	{
		g1=g00/(1.0+p0/Psat);
		p0=p0+g1*dL*p0;
//		fprintf(fp,"%lf\t%lf\n",z/L,(g1+gama*gn*N0)/g1);
	}
//	fclose(fp);
	G=p0/p;
	return(G);
}
/*****************************************************************************************
The end of procedure soagain3
*****************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -