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

📄 problem.cpp

📁 一个2D电磁场FEM计算的VC++源程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				b[k]    += (Md*x[k] + Mo*x[k+1]);
				b[k+1]  += (Mo*x[k] + Md*x[k+1]);
			}

			// set boundary conditions
			m1[0] = 0;
			b[0]  = 0;
			b[n] += Hdata[i];

			// solve tridiagonal equation
			// solution ends up in b;
			for(k = 0; k < n; k++)
			{
				c = m1[k]/m0[k];
				m0[k+1] -= m1[k]*c;
				b[k+1]  -= b[k]*c;
			}
			b[n] = b[n]/m0[n];
			for(k = n-1; k >= 0; k--)
				b[k] = (b[k] - m1[k]*b[k + 1])/m0[k];
	
			iter++;

			lastres=res;
			res=abs(b[n]-x[n])/d;
			
			if (res<1.e-8) Converged=TRUE;

			// Do the same relaxation scheme as is implemented
			// in the solver to make sure that this effective
			// lamination permeability calculation converges
			if(iter>5)
			{
				if ((res>lastres) && (Relax>0.1)) Relax/=2.;
				else Relax+= 0.1 * (1. - Relax);
			}

			for(k=0;k<=n;k++) x[k]=Relax*b[k]+(1.0-Relax)*x[k];

		}while(Converged!=TRUE);


		mu = x[n]/(Hdata[i]*d);

		free(x );
		free(b );
		free(m0);
		free(m1);

		return mu;
}

CComplex CMaterialProp::GetdHdB(double B)
{
	double b,z,l;
	CComplex h;
	int i;

	b=fabs(B);
	
	if(BHpoints==0)	return CComplex(b/(mu_x*muo));

	if(b>Bdata[BHpoints-1])
		return slope[BHpoints-1];

	for(i=0;i<BHpoints-1;i++)
		if((b>=Bdata[i]) && (b<=Bdata[i+1])){
			l=(Bdata[i+1]-Bdata[i]);
			z=(b-Bdata[i])/l;
			h=6.*z*(z-1.)*Hdata[i]/l +
			  (1.-4.*z+3.*z*z)*slope[i] +
			  6.*z*(1.-z)*Hdata[i+1]/l +
			  z*(3.*z-2.)*slope[i+1];
			return h;
		}

	return CComplex(0);
}

double CMaterialProp::GetH(double x)
{
	return Re(GetH(CComplex(x)));
}

CComplex CMaterialProp::GetH(CComplex x)
{
	double b,z,z2,l;
	CComplex p,h;
	int i;

	b=abs(x);
	if((BHpoints==0) || (b==0))	return 0;
	p=x/b;

	if(b>Bdata[BHpoints-1])
		return p*(Hdata[BHpoints-1] + slope[BHpoints-1]*(b-Bdata[BHpoints-1]));

	for(i=0;i<BHpoints-1;i++)
		if((b>=Bdata[i]) && (b<=Bdata[i+1])){
			l=Bdata[i+1]-Bdata[i];
			z=(b-Bdata[i])/l;
			z2=z*z;
			h=(1.-3.*z2+2.*z2*z)*Hdata[i] +
			  z*(1.-2.*z+z2)*l*slope[i] +
			  z2*(3.-2.*z)*Hdata[i+1] +
			  z2*(z-1.)*l*slope[i+1];
			return p*h;
		}

	return 0;
}

// GetEnergy for the magnetostatic case
double CMaterialProp::GetEnergy(double x)
{
	double b,z,z2,l,nrg;
	double b0,b1,h0,h1,dh0,dh1;
	int i;

	b=fabs(x);
	nrg=0.;
	
	if(BHpoints==0)	return 0;

	for(i=0;i<BHpoints-1;i++){

		b0=Bdata[i];	h0=Re(Hdata[i]);
		b1=Bdata[i+1];	h1=Re(Hdata[i+1]);
		dh0=Re(slope[i]);
		dh1=Re(slope[i+1]);

		if((b>=b0) && (b<=b1)){
			l=b1-b0;
			z=(b-b0)/l;
			z2=z*z;

			nrg += (dh0*l*l*(6. + z*(-8. + 3.*z))*z2)/12. + 
				(h0*l*z*(2. + (-2. + z)*z2))/2. - 
				(h1*l*(-2. + z)*z2*z)/2. +			
				(dh1*l*l*(-4. + 3.*z)*z2*z)/12;

			return nrg;
		}
		else{
			// point isn't in this section, but add in the
			// energy required to pass through it.
			b0=Bdata[i];	h0=Re(Hdata[i]);
			b1=Bdata[i+1];	h1=Re(Hdata[i+1]);
			dh0=Re(slope[i]);
			dh1=Re(slope[i+1]);
			nrg += ((b0 - b1)*((b0 - b1)*(dh0 - dh1) -
				6.*(h0 + h1)))/12.;
		}
	}		

	// if we've gotten to this point, the point is off the scale,
	// so we have to extrapolate the rest of the way...

	h0=Re(Hdata[BHpoints-1]);
	dh0=Re(slope[BHpoints-1]);
	b0=Bdata[BHpoints-1];

	nrg += ((b - b0)*(b*dh0 - b0*dh0 + 2*h0))/2.;
	
	return nrg;
}

double CMaterialProp::GetCoEnergy(double b)
{
	return (fabs(b)*GetH(b) - GetEnergy(b));
}

double CMaterialProp::DoEnergy(double b1, double b2)
{
	// calls the raw routine to get point energy, 
	// but deals with the load of special cases that
	// arise because I insisted on trying to deal with
	// laminations on a continuum basis.

	double nrg,biron,bair;

	// easiest case: the material is linear!
	if (BHpoints==0)
	{
		double h1,h2;
		
		if(LamType==0){		// laminated in-plane
			h1=b1/((1.+LamFill*(mu_x-1.))*muo);
			h2=b2/((1.+LamFill*(mu_y-1.))*muo);
		}

		if(LamType==1){		// laminated parallel to x;
			h1=b1/((1.+LamFill*(mu_x-1.))*muo);
			h2=b1*(LamFill/(mu_y*muo) + (1. - LamFill)/muo);
		}

		if(LamType==2){		// laminated parallel to x;
			h2=b1/((1.+LamFill*(mu_y-1.))*muo);
			h1=b1*(LamFill/(mu_x*muo) + (1. - LamFill)/muo);
		}

		if(LamType>2){
			h1=b1/muo;
			h2=b2/muo;
		}

		return ((h1*b1+h2*b2)/2.);
	}

	// Rats! The material is nonlinear.  Now, we have to do
	// a bit of work to get the energy.
	if(LamType==0) nrg = GetEnergy(sqrt(b1*b1+b2*b2));

	if(LamType==1){
		biron=sqrt((b1/LamFill)*(b1/LamFill) + b2*b2);
		bair=b2;
		nrg = LamFill*GetEnergy(biron)+(1-LamFill)*bair*bair/(2.*muo);
	}

	if(LamType==2){
		biron=sqrt((b2/LamFill)*(b2/LamFill) + b1*b1);
		bair=b1;
		nrg = LamFill*GetEnergy(biron)+(1-LamFill)*bair*bair/(2.*muo);
	}

	return nrg;
}

double CMaterialProp::DoCoEnergy(double b1, double b2)
{
	double nrg,biron,bair;

	// easiest case: the material is linear!
	// in this case, energy and coenergy are the same!
	if (BHpoints==0) return DoEnergy(b1,b2);

	if(LamType==0) nrg = GetCoEnergy(sqrt(b1*b1+b2*b2));

	if(LamType==1){
		biron=sqrt((b1/LamFill)*(b1/LamFill) + b2*b2);
		bair=b2;
		nrg = LamFill*GetCoEnergy(biron)+(1-LamFill)*bair*bair/(2.*muo);
	}

	if(LamType==2){
		biron=sqrt((b2/LamFill)*(b2/LamFill) + b1*b1);
		bair=b1;
		nrg = LamFill*GetCoEnergy(biron)+(1-LamFill)*bair*bair/(2.*muo);
	}

	return nrg;
}


double CMaterialProp::DoEnergy(CComplex b1, CComplex b2)
{
	// This one is meant for the frequency!=0 case.
	// Fortunately, there's not so much effort in this case.
	CComplex mu1,mu2,h1,h2;
	
	GetMu(b1,b2,mu1,mu2);
	h1=b1/(mu1*muo);
	h2=b2/(mu2*muo);
	return (Re(h1*conj(b1)+h2*conj(b2))/4.);

}

double CMaterialProp::DoCoEnergy(CComplex b1, CComplex b2)
{
	return DoEnergy(b1,b2);
}

void CMaterialProp::GetMu(CComplex b1, CComplex b2,
							CComplex &mu1, CComplex &mu2)
{
	// gets the permeability, given a flux density
	// version for frequency!=0

	CComplex biron;

	// easiest case: the material is linear!
	if (BHpoints==0)
	{		
		mu1=mu_fdx;
		mu2=mu_fdy;
		return;
	}

	// Rats! The material is nonlinear. 
	else{
		CComplex muiron;
	
		if(LamType==0){
			biron=sqrt(b1*conj(b1)+b2*conj(b2));
			if(abs(biron)<1.e-08) mu1=slope[0]; //catch degenerate case
			else mu1=biron/GetH(biron);
			mu2=mu1;
		}

		if(LamType==1){
			biron=sqrt((b1/LamFill)*(b1/LamFill) + b2*b2);
			if(abs(biron)<1.e-08) muiron=slope[0];
			else muiron=biron/GetH(biron);
			mu1=muiron*LamFill;
			mu2=1./(LamFill/muiron + (1. - LamFill)/muo);
		
		}

		if(LamType==2){
			biron=sqrt((b2/LamFill)*(b2/LamFill) + b1*b1);
			if(abs(biron)<1.e-08) muiron=slope[0];
			else muiron=biron/GetH(biron);
			mu2=muiron*LamFill;
			mu1=1./(LamFill/muiron + (1. - LamFill)/muo);
		}
	}	

	// convert to relative permeability
	mu1/=muo;
	mu2/=muo;

	return;
}


void CMaterialProp::GetMu(double b1, double b2,
						double &mu1, double &mu2)
{
	// gets the permeability, given a flux density
	//

	double biron;
	
	mu1=mu2=muo;			// default

	// easiest case: the material is linear!
	if (BHpoints==0)
	{		
		if(LamType==0){		// laminated in-plane
			mu1=((1.+LamFill*(mu_x-1.))*muo);
			mu2=((1.+LamFill*(mu_y-1.))*muo);
		}

		if(LamType==1){		// laminated parallel to x;
			mu1=((1.+LamFill*(mu_x-1.))*muo);
			mu2=1./(LamFill/(mu_y*muo) + (1. - LamFill)/muo);
		}

		if(LamType==2){		// laminated parallel to x;
			mu2=((1.+LamFill*(mu_y-1.))*muo);
			mu1=1./(LamFill/(mu_x*muo) + (1. - LamFill)/muo);
		}
	}

	// Rats! The material is nonlinear.
	else{
		double muiron;
	
		if(LamType==0){
			biron=sqrt(b1*b1+b2*b2);
			if(biron<1.e-08) mu1=Re(slope[0]); //catch degenerate case
			else mu1=biron/GetH(biron);
			mu2=mu1;
		}

		if(LamType==1){
			biron=sqrt((b1/LamFill)*(b1/LamFill) + b2*b2);
			if(biron<1.e-08) muiron=Re(slope[0]);
			else muiron=biron/GetH(biron);
			mu1=muiron*LamFill;
			mu2=1./(LamFill/muiron + (1. - LamFill)/muo);	
		}

		if(LamType==2){
			biron=sqrt((b2/LamFill)*(b2/LamFill) + b1*b1);
			if(biron<1.e-08) muiron=Re(slope[0]);
			else muiron=biron/GetH(biron);
			mu2=muiron*LamFill;
			mu1=1./(LamFill/muiron + (1. - LamFill)/muo);
		}

	}
	
	// convert to relative permeability
	mu1/=muo;
	mu2/=muo;

	return;
}









CBoundaryProp::CBoundaryProp()
{
		BdryName="New Boundary";
		BdryFormat=0;				// type of boundary condition we are applying
									// 0 = constant value of A
									// 1 = Small skin depth eddy current BC
									// 2 = Mixed BC

		A0=0.; A1=0.;
		A2=0.; phi=0.;			// set value of A for BdryFormat=0;
	
		Mu=0.; Sig=0.;			// material properties necessary to apply
								// eddy current BC
		
		c0=0.; c1=0.;			// coefficients for mixed BC

}

CPointProp::CPointProp()
{
		PointName="New Point Property";
		Jr=0.; Ji=0.;					// applied point current, A 
		Ar=0.; Ai=0.;					// prescribed nodal value;
}

CCircuit::CCircuit()
{
		CircName="New Circuit";
		CircType=0;
		Amps=0.;
}

⌨️ 快捷键说明

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