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

📄 numericalcomputmethods.cpp

📁 Schrodinger Equation 数值计算中的方程
💻 CPP
字号:
#include "stdAfx.h"
#include "nrutil.h"
#include "nrtypes.h"
#include "NumericalComputMethods.h"
//#include <iostream>
#include<cmath>
//using namespace std;
NumericalComputMethods::NumericalComputMethods()
{

}
NumericalComputMethods::~NumericalComputMethods()
{


}
void NumericalComputMethods::flmoon(const int n,const int nph, int &jd,DP &frac)
{
	const DP RAD=3.14;
	int i;
	DP am,as,c, t,t2,xtra;
	c=n+nph/4.0;
	t=c/1236.85;
	t2=t*t;
	as=359.22+29.10*t2;
	jd=2415020+28*n+7*nph;
	xtra=0.75933+1.53*c*((1.178e-4)-(1.55e-7)*t)*t2;
	if(nph==0||nph==2)
		xtra+=(0.1734-3.93e-4*t)*sin(RAD*as)-0.6280*sin(RAD*am);
	//else NR::nrerror("nph is unknownin flmoon");
	i=int(xtra>=0.0?floor(xtra):ceil(xtra-1.0));
	jd+=i;
	frac=xtra-i;
}
void NumericalComputMethods::rot(Mat_IO_DP &a,const DP s, const DP tau,const int i,
		const int j,const int k,const int l)
{
	DP g,h;
	g=a[i][j];
	h=a[k][l];
	a[i][j]=g-s*(h+g*tau);
	a[k][l]=h+s*(g-h*tau);
}
void NumericalComputMethods::determineIndexMiniElem(int& i1,int& i2,int& i3,int& i4,Vec_DP v)
{
	int n=v.size();
	/////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////
	////////////////determine the first mini-value of v//////////////////
	double mini_1=v[0];
	double max=v[0];
	for(int i=0;i<n;i++)
	{
		max=MAX(max,v[i]);
	}
    for(int i=0;i<n;i++)
	{
      mini_1=MIN(mini_1,v[i]);

	}
	for(int i=0;i<n;i++)
	{
		if(v[i]==mini_1)
			i1=i;
	}
	/////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////
	////////////////determine the second mini-value of v//////////////////
    double mini_2=max;
    for(int i=0;i<n;i++)
	{
		if(i!=i1)
			mini_2=MIN(mini_2,v[i]);		

	}
	for(int i=0;i<n;i++)
	{
		if(mini_2==v[i])
			i2=i;
	}
	/////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////
	////////////////determine the third mini-value of v//////////////////
    double mini_3=max;
    for(int i=0;i<n;i++)
	{
		if(i!=i1&&i!=i2)
            mini_3=MIN(mini_3,v[i]);

	}
	for(int i=0;i<n;i++)
	{
		if(mini_3==v[i])
			i3=i;
	}
	/////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////
	////////////////determine the fourth mini-value of v//////////////////
    double mini_4=max;
    for(int i=0;i<n;i++)
	{
		if(i!=i1&&i!=i2&&i!=i3)
            mini_4=MIN(mini_4,v[i]);

	}
	for(int i=0;i<n;i++)
	{
		if(mini_4==v[i])
			i4=i;
	}


}
void NumericalComputMethods::ProduceMatrix(Mat_IO_DP& M)
{
    double m1=0.067;//the effect mass in the well;
	double m2=0.092;//the effect mass outside well;
	double v_0=0.23*1.6e-19;//the offset of heterojunction.
	double g=0.28e-9;//the grid of the z axis;
	double v_=2*v_0*9.1e-31*g*g/SQR(1.35e-34);
	for(int i=0;i<61;i++)
	{
		for(int j=0;j<61;j++)
		{
            if(j==i)
                M[i][j]=2.0/m2+v_;
			else if(j==(i+1))
				M[i][j]=-1/m2;
			else if(j==(i-1))
				M[i][j]=-1/m2;
			else 
				M[i][j]=0.0;
		}
	}
	M[20][20]=1/m2+1/m1+v_;
	M[20][21]=-1/m1;
	M[21][20]=-1/m1;
	M[19][20]=-1/m2;
	M[20][19]=-1/m2;
	for(int i=21;i<40;i++)
	{
		for(int j=21;j<40;j++)
		{
            if(j==i)
                M[i][j]=2.0/m1;
			else if(j==(i+1))
				M[i][j]=-1/m1;
			else if(j==(i-1))
				M[i][j]=-1/m1;
		}
	}
	M[40][40]=1/m2+1/m1+v_;
	M[40][41]=-1/m2;
	M[41][40]=-1/m2;
	M[39][40]=-1/m1;
	M[40][39]=-1/m1;

	for(int jj=0;jj<61;jj++)
	{
		for(int jjj=0;jjj<61;jjj++)
		{
			cout<<M[jj][jjj]<<' ';
		}
		cout<<endl;
	}
	

}
void NumericalComputMethods::jacobitransformation(Mat_IO_DP &a,Vec_O_DP &d, Mat_O_DP &v,
		int &nrot)
//computes all eigenvalues and eigenvectors of a real symmetric matrix
// a[0..n-1][0..n-1]. On output,elements of a above the diagonal are 
//destroyed. d[0..n-1] returns the eigenvalues of a. v[0..n-1][0..n-1]
//is a matrix whose columns contain, on output, the normalized eigenvectors
//of a. nrot returns the number of Jacobi rotations that were required.

{

	int i, j, ip,iq;
	DP tresh, theta, tau,t, sm, s, h, g, c;
	int n=d.size();
	Vec_DP b(n),z(n);
	for(ip=0;ip<n;ip++)
	{
		for(iq=0;iq<n;iq++)
		{
			v[ip][iq]=0.0;
		}
		v[ip][ip]=1.0;
	}
	for(ip=0;ip<n;ip++)
	{
		b[ip]=d[ip]=a[ip][ip];
		z[ip]=0.0;
	}
	nrot=0;
	for(i=1;i<=50;i++)
	{
		sm=0.0;
		for(ip=0;ip<n-1;ip++)
		{
			for(iq=ip+1;iq<n;iq++)
				sm +=fabs(a[ip][iq]);
		}
		if(sm==0)
		{
			return;//
		}
		if(i<4)
			tresh=0.2*sm/(n*n);
		else
			tresh=0.0;
		for(ip=0;ip<n-1;ip++)
		{
			for(iq=ip+1;iq<n;iq++)
			{
				g=100.0*fabs(a[ip][iq]);
				if(i>4&&(fabs(d[ip])+g)==fabs(d[ip])
					&&(fabs(d[iq])+g)==fabs(d[iq]))
					a[ip][iq]=0.0;
				else if(fabs(a[ip][iq])>tresh)
				{
					h=d[iq]-d[ip];
					if((fabs(h)+g)==fabs(h))
						t=(a[ip][iq])/h;
					else
					{
						theta=0.5*h/(a[ip][iq]);
						t=1.0/(fabs(theta)+sqrt(1.0+theta*theta));
						if(theta<0.0)t=-t;
					}
					c=1.0/sqrt(1+t*t);
					s=t*c;
					tau=s/(1.0+c);
					h=t*a[ip][iq];
					z[ip]-=h;
					z[iq]+=h;
					d[ip]-=h;
					d[iq]+=h;
					a[ip][iq]=0.0;
					for(j=0;j<ip;j++)
						rot(a,s,tau,j,ip,j,iq);
					for(j=ip+1;j<iq;j++)
						rot(a,s,tau,ip,j,j,iq);
					for(j=iq+1;j<n;j++)
						rot(a,s,tau,ip,j,iq,j);
					for(j=0;j<n;j++)
						rot(v,s,tau,j,ip,j,iq);
					++nrot;
				}
			}
		}
		for(ip=0;ip<n;ip++)
		{
			b[ip]+=z[ip];
			d[ip]=b[ip];			
			z[ip]=0.0;

		}

	}
	//NR::nrerror("need more iterations in routine jacobi");

}

⌨️ 快捷键说明

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