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

📄 femmviewdoc.cpp

📁 一个2D电磁场FEM计算的VC++源程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
						bn/=(-2.*PI*r);
					}
					z=0.5/abs(tn);
					tn/=abs(tn);
				
					// for the moment, kludge with bt...
					bt=e->B1*tn.re + e->B2*tn.im;
						
					R+=z;
					b1[i]+=(z*tn.re*bt);
					b2[i]+=(z*tn.im*bt);
					b1[i]+=(z*tn.im*bn);
					b2[i]+=(-z*tn.re*bn);
					v2=tn;	
					q=NumList[k];
				}
				else e=&meshelem[nxt];
			}
			b1[i]/=R;
			b2[i]/=R;
		}

			// check to see if angle of corner is too sharp to apply
			// this rule; really only does right if the interface is flat;
			flag=FALSE;	
			// if there is only one edge, approx is ok;
			if ((abs(v1)<0.9) || (abs(v2)<0.9)) flag=TRUE;
			// if the interfaces make less than a 10 degree angle, things are ok;
			if ( (-v1.re*v2.re-v1.im*v2.im) > 0.985) flag=TRUE;
			
			// Otherwise, punt...
			if(flag==FALSE){
				bn=0;
				k=elm.p[i];
				for(j=0;j<NumList[k];j++)
				{
					if(elm.lbl==meshelem[ConList[k][j]].lbl){
						m=ConList[k][j];
						bt.re=sqrt(meshelem[m].B1.re*meshelem[m].B1.re +
							meshelem[m].B2.re*meshelem[m].B2.re);
						bt.im=sqrt(meshelem[m].B1.im*meshelem[m].B1.im +
							meshelem[m].B2.im*meshelem[m].B2.im);
						if(bt.re>bn.re) bn.re=bt.re;
						if(bt.im>bn.im) bn.im=bt.im;
					}
				}
			
				R=sqrt(elm.B1.re*elm.B1.re + elm.B2.re*elm.B2.re);
				if(R!=0)
				{
					b1[i].re=bn.re/R * elm.B1.re;
					b2[i].re=bn.re/R * elm.B2.re;
				}
				else{
					b1[i].re=0;
					b2[i].re=0;
				}

				R=sqrt(elm.B1.im*elm.B1.im + elm.B2.im*elm.B2.im);
				if(R!=0)
				{
					b1[i].im=bn.im/R * elm.B1.im;
					b2[i].im=bn.im/R * elm.B2.im;
				}
				else{
					b1[i].im=0;
					b2[i].im=0;
				}
			}
		}

		// check to see if the point has a point current; if so, just
		// use element average values;
		if (nodeproplist.GetSize()!=0)
		for(j=0;j<nodelist.GetSize();j++)
		{
			if (abs(p-(nodelist[j].x+nodelist[j].y*I))<1.e-08)
			if(nodelist[j].BoundaryMarker>=0)
			{	
				if ((nodeproplist[nodelist[j].BoundaryMarker].Jr!=0) ||
					(nodeproplist[nodelist[j].BoundaryMarker].Ji!=0))
				{
					b1[i]=elm.B1;
					b2[i]=elm.B2;	
				}
			}
		}
		

		//check for special case of node on r=0 axisymmetric; set Br=0;
		if ((fabs(p.re)<1.e-06) && (ProblemType==1)) b1[i].Set(0.,0);
	}
}

void CFemmviewDoc::GetElementB(CElement &elm)
{
	int i,n[3];
	double b[3],c[3],da;

	for(i=0;i<3;i++) n[i]=elm.p[i];

	b[0]=meshnode[n[1]].y - meshnode[n[2]].y;
	b[1]=meshnode[n[2]].y - meshnode[n[0]].y;
	b[2]=meshnode[n[0]].y - meshnode[n[1]].y;	
	c[0]=meshnode[n[2]].x - meshnode[n[1]].x;
	c[1]=meshnode[n[0]].x - meshnode[n[2]].x;
	c[2]=meshnode[n[1]].x - meshnode[n[0]].x;
	da=(b[0]*c[1]-b[1]*c[0]);

	if (ProblemType==0){
		elm.B1=0;
		elm.B2=0;
		for(i=0;i<3;i++)
		{
			elm.B1+=meshnode[n[i]].A*c[i]/(da*LengthConv[LengthUnits]);
			elm.B2-=meshnode[n[i]].A*b[i]/(da*LengthConv[LengthUnits]);
		}
		return;
	}
	else{
		CComplex v[6],dp,dq;
		double R[3],Z[3],r;

		for(i=0,r=0;i<3;i++){
			R[i]=meshnode[n[i]].x;
			Z[i]=meshnode[n[i]].y;
			r+=R[i]/3.;
		}

		// corner nodes
		v[0]=meshnode[n[0]].A;
		v[2]=meshnode[n[1]].A;
		v[4]=meshnode[n[2]].A;

		// construct values for mid-side nodes;
		if ((R[0]<1.e-06) && (R[1]<1.e-06)) v[1]=(v[0]+v[2])/2.;
		else v[1]=(R[1]*(3.*v[0] + v[2]) + R[0]*(v[0] + 3.*v[2]))/
			 (4.*(R[0] + R[1]));

		if ((R[1]<1.e-06) && (R[2]<1.e-06)) v[3]=(v[2]+v[4])/2.;
		else v[3]=(R[2]*(3.*v[2] + v[4]) + R[1]*(v[2] + 3.*v[4]))/
			 (4.*(R[1] + R[2]));

		if ((R[2]<1.e-06) && (R[0]<1.e-06)) v[5]=(v[4]+v[0])/2.;
		else v[5]=(R[0]*(3.*v[4] + v[0]) + R[2]*(v[4] + 3.*v[0]))/
			(4.*(R[2] + R[0]));

		// derivatives w.r.t. p and q:
		dp=(-v[0] + v[2] + 4.*v[3] - 4.*v[5])/3.;
		dq=(-v[0] - 4.*v[1] + 4.*v[3] + v[4])/3.;

		// now, compute flux.
		da*=2.*PI*r*LengthConv[LengthUnits]*LengthConv[LengthUnits];
		elm.B1=-(c[1]*dp+c[2]*dq)/da;
		elm.B2= (b[1]*dp+b[2]*dq)/da;

		return;
	}
}


void CFemmviewDoc::OnReload() 
{
	// TODO: Add your command handler code here
	CString pname = GetPathName();
	if(pname.GetLength()>0)
	{
		OnNewDocument();
		SetPathName(pname,FALSE);
		OnOpenDocument(pname);
	}
}

int CFemmviewDoc::ClosestNode(double x, double y)
{
	int i,j;
	double d0,d1;

	if(nodelist.GetSize()==0) return -1;

	j=0;
	d0=nodelist[0].GetDistance(x,y);
	for(i=0;i<nodelist.GetSize();i++){
		d1=nodelist[i].GetDistance(x,y);
		if(d1<d0){
			d0=d1;
			j=i;
		}
	}

	return j;
}

void CFemmviewDoc::GetLineValues(CXYPlot &p,int PlotType,int NumPlotPoints)
{
	double *q,z,u,dz;
	CComplex pt,n,t;
	int i,j,k,m,elm;
	CPointVals v;
	BOOL flag;
	
	q=(double *)calloc(contour.GetSize(),sizeof(double));
	for(i=1,z=0.;i<contour.GetSize();i++)
	{
		z+=abs(contour[i]-contour[i-1]);
		q[i]=z;
	}
	dz=z/(NumPlotPoints-1);
	
	/*
		m_XYPlotType.AddString("Potential");
		m_XYPlotType.AddString("|B|        (Magnitude of flux density)");
		m_XYPlotType.AddString("B . n      (Normal flux density)");
		m_XYPlotType.AddString("B . t      (Tangential flux density)");
		m_XYPlotType.AddString("|H|        (Magnitude of field intensity)");
		m_XYPlotType.AddString("H . n      (Normal field intensity)");
		m_XYPlotType.AddString("H . t      (Tangential field intensity)");
		m_XYPlotType.AddString("J_eddy     
	*/

	if(Frequency==0){
		switch (PlotType)
		{
			case 0:
				p.Create(NumPlotPoints,2);
				if (ProblemType==0) strcpy(p.lbls[1],"Potential, Wb/m");
				else strcpy(p.lbls[1],"Flux, Wb");
				break;
			case 1:
				p.Create(NumPlotPoints,2);
				strcpy(p.lbls[1],"|B|, Tesla");
				break;
			case 2:
				p.Create(NumPlotPoints,2);
				strcpy(p.lbls[1],"B.n, Tesla");
				break;
			case 3:
				p.Create(NumPlotPoints,2);
				strcpy(p.lbls[1],"B.t, Tesla");
				break;
			case 4:
				p.Create(NumPlotPoints,2);
				strcpy(p.lbls[1],"|H|, Amp/m");
				break;
			case 5:
				p.Create(NumPlotPoints,2);
				strcpy(p.lbls[1],"H.n, Amp/m");
				break;
			case 6:
				p.Create(NumPlotPoints,2);
				strcpy(p.lbls[1],"H.t, Amp/m");
				break;
			default:
				p.Create(NumPlotPoints,2);
				break;
		}
	}
	else{
		switch (PlotType)
		{
			case 0:
				p.Create(NumPlotPoints,4);
				if(ProblemType==0){
					strcpy(p.lbls[1],"|A|, Wb/m");
					strcpy(p.lbls[2],"Re[A], Wb/m");
					strcpy(p.lbls[3],"Im[A], Wb/m");
				}
				else{
					strcpy(p.lbls[1],"|Flux|, Wb");
					strcpy(p.lbls[2],"Re[Flux], Wb");
					strcpy(p.lbls[3],"Im[Flux], Wb");
				}
				break;
			case 1:
				p.Create(NumPlotPoints,2);
				strcpy(p.lbls[1],"|B|, Tesla");
				break;
			case 2:
				p.Create(NumPlotPoints,4);
				strcpy(p.lbls[1],"|B.n|, Tesla");
				strcpy(p.lbls[2],"Re[B.n], Tesla");
				strcpy(p.lbls[3],"Im[B.n], Tesla");
				break;
			case 3:
				p.Create(NumPlotPoints,4);
				strcpy(p.lbls[1],"|B.t|, Tesla");
				strcpy(p.lbls[2],"Re[B.t], Tesla");
				strcpy(p.lbls[3],"Im[B.t], Tesla");
				break;
			case 4:
				p.Create(NumPlotPoints,2);
				strcpy(p.lbls[1],"|H|, Amp/m");
				break;
			case 5:
				p.Create(NumPlotPoints,4);
				if(ProblemType==0){
					strcpy(p.lbls[1],"|H.n|, Amp/m");
					strcpy(p.lbls[2],"Re[H.n], Amp/m");
					strcpy(p.lbls[3],"Im[H.n], Amp/m");
				}
				break;
			case 6:
				p.Create(NumPlotPoints,4);
				strcpy(p.lbls[1],"|H.t|, Amp/m");
				strcpy(p.lbls[2],"Re[H.t], Amp/m");
				strcpy(p.lbls[3],"Im[H.t], Amp/m");
				break;
			case 7:
				p.Create(NumPlotPoints,4);
				strcpy(p.lbls[1],"|Je|, MA/m^2");
				strcpy(p.lbls[2],"Re[Je], MA/m^2");
				strcpy(p.lbls[3],"Im[Je], MA/m^2");
				break;
			case 8:
				p.Create(NumPlotPoints,4);
				strcpy(p.lbls[1],"|Js+Je|, MA/m^2");
				strcpy(p.lbls[2],"Re[Js+Je], MA/m^2");
				strcpy(p.lbls[3],"Im[Js+Je], MA/m^2");
				break;
			default:
				p.Create(NumPlotPoints,2);
				break;
		}
	}
	
	switch(LengthUnits){
		case 1:
			strcpy(p.lbls[0],"Length, mm");
			break;
		case 2:
			strcpy(p.lbls[0],"Length, cm");
			break;
		case 3:
			strcpy(p.lbls[0],"Length, m");
			break;
		case 4:
			strcpy(p.lbls[0],"Length, mils");
			break;
		case 5:
			strcpy(p.lbls[0],"Length, um");
			break;
		default:
			strcpy(p.lbls[0],"Length, inches");
			break;
	}

	for(i=0,k=1,z=0,elm=-1;i<NumPlotPoints;i++,z+=dz)
	{
		while((z>q[k]) && (k<(contour.GetSize()-1))) k++;
		u=(z-q[k-1])/(q[k]-q[k-1]);
		pt=contour[k-1]+u*(contour[k]-contour[k-1]);
		t=contour[k]-contour[k-1];
		t/=abs(t);
		n = I*t;
		pt+=(n*1.e-06);
		
		if (elm<0) elm=InTriangle(pt.re,pt.im);
		else if (InTriangleTest(pt.re,pt.im,elm)==FALSE)
		{
			flag=FALSE;
			for(j=0;j<3;j++)
				for(m=0;m<NumList[meshelem[elm].p[j]];m++)
				{
					elm=ConList[meshelem[elm].p[j]][m];
					if (InTriangleTest(pt.re,pt.im,elm)==TRUE)
					{
						flag=TRUE;
						m=100;
						j=3;
					}
				}
			if (flag==FALSE) elm=InTriangle(pt.re,pt.im);
		}
		if(elm>=0)
			flag=GetPointValues(pt.re,pt.im,elm,v);
		else flag=FALSE;

		p.M[i][0]=z;
		if ((Frequency==0) && (flag!=FALSE)){
			switch (PlotType){
				case 0:
					p.M[i][1]=v.A.re;
					break;
				case 1:
					p.M[i][1]=sqrt(v.B1.Abs()*v.B1.Abs() + v.B2.Abs()*v.B2.Abs());
					break;
				case 2:
					p.M[i][1]= n.re*v.B1.re + n.im*v.B2.re;
					break;
				case 3:
					p.M[i][1]= t.re*v.B1.re + t.im*v.B2.re;
					break;
				case 4:
					p.M[i][1]=sqrt(v.H1.Abs()*v.H1.Abs() + v.H2.Abs()*v.H2.Abs());
					break;
				case 5:
					p.M[i][1]= n.re*v.H1.re + n.im*v.H2.re;
					break;
				case 6:
					p.M[i][1]= t.re*v.H1.re + t.im*v.H2.re;
					break;
				default:
					p.M[i][1]=0;
					break;
			}
		}
		else if (flag!=FALSE){
			switch (PlotType){
				case 0:
					p.M[i][1]=v.A.Abs();
					p.M[i][2]=v.A.re;
					p.M[i][3]=v.A.im;
					break;
				case 1:
					p.M[i][1]=sqrt(v.B1.Abs()*v.B1.Abs() + v.B2.Abs()*v.B2.Abs());
					break;
				case 2:
					p.M[i][2]= n.re*v.B1.re + n.im*v.B2.re;
					p.M[i][3]= n.re*v.B1.im + n.im*v.B2.im;
					p.M[i][1]=sqrt(p.M[i][2]*p.M[i][2] +
						           p.M[i][3]*p.M[i][3]);
					break;
				case 3:
					p.M[i][2]= t.re*v.B1.re + t.im*v.B2.re;
					p.M[i][3]= t.re*v.B1.im + t.im*v.B2.im;
					p.M[i][1]=sqrt(p.M[i][2]*p.M[i][2] +
						           p.M[i][3]*p.M[i][3]);
					break;
				case 4:
					p.M[i][1]=sqrt(v.H1.Abs()*v.H1.Abs() + v.H2.Abs()*v.H2.Abs());
					break;
				case 5:
					p.M[i][2]= n.re*v.H1.re + n.im*v.H2.re;
					p.M[i][3]= n.re*v.H1.im + n.im*v.H2.im;
					p.M[i][1]=sqrt(p.M[i][2]*p.M[i][2] +
						           p.M[i][3]*p.M[i][3]);
					break;
				case 6:
					p.M[i][2]= t.re*v.H1.re + t.im*v.H2.re;
					p.M[i][3]= t.re*v.H1.im + t.im*v.H2.im;
					p.M[i][1]=sqrt(p.M[i][2]*p.M[i][2] +
						           p.M[i][3]*p.M[i][3]);
					break;
				case 7:
					p.M[i][2]= v.Je.re;
					p.M[i][3]= v.Je.im;
					p.M[i][1]= abs(v.Je);
					break;
				case 8:
					p.M[i][2]= v.Je.re+v.Js.re;
					p.M[i][3]= v.Je.im+v.Js.im;
					p.M[i][1]= abs(v.Je+v.Js);
					break;
				default:
					p.M[i][1]=0;
					break;
			}
		}
	}
		
	free(q);
}

BOOL CFemmviewDoc::InTriangleTest(double x, double y, int i)
{
	int j,k;
	double z;
	BOOL InFlag;

	if(i<0) return FALSE;

	for(j=0,InFlag=TRUE;((j<3) && (InFlag==TRUE));j++)
	{
		k=j+1; if(k==3) k=0;
		z=(meshnode[meshelem[i].p[k]].x-meshnode[meshelem[i].p[j]].x)*
		  (y-meshnode[meshelem[i].p[j]].y) -
		  (meshnode[meshelem[i].p[k]].y-meshnode[meshelem[i].p[j]].y)*
		  (x-meshnode[meshelem[i].p[j]].x);
		if(z<0) InFlag=FALSE;
	}

	return InFlag;
}

CPointVals::CPointVals()
{
	A=0;			// vector potential
	B1=0; B2=0;		// flux density
	mu1=1; mu2=1;	// permeability
	H1=0; H2=0;		// field intensity
	Je=0; Js=0;		// eddy current and source current densities
	c=0;			// conductivity
	E=0;			// energy stored in the magnetic field
	Ph=0;			// power dissipated by hysteresis
	Pe=0;
	ff=1;
}

CComplex CFemmviewDoc::Ctr(int i)
{
	CComplex p,c;
	int j;
	
	for(j=0,c=0;j<3;j++){
		p.Set(meshnode[meshelem[i].p[j]].x/3.,meshnode[meshelem[i].p[j]].y/3.);
		c+=p;
	}

	return c;
}

double CFemmviewDoc::ElmArea(int i)
{
	int j,n[3];
	double b0,b1,c0,c1;

	for(j=0;j<3;j++) n[j]=meshelem[i].p[j];

	b0=meshnode[n[1]].y - meshnode[n[2]].y;
	b1=meshnode[n[2]].y - meshnode[n[0]].y;
	c0=meshnode[n[2]].x - meshnode[n[1]].x;
	c1=meshnode[n[0]].x - meshnode[n[2]].x;
	return (b0*c1-b1*c0)/2.;

}

double CFemmviewDoc::ElmArea(CElement *elm)
{
	int j,n[3];
	double b0,b1,c0,c1;

	for(j=0;j<3;j++) n[j]=elm->p[j];

⌨️ 快捷键说明

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