镜像法计算变压器漏磁场之四
铁心线圈磁场计算的编程实现。
八、变压器漏磁场计算C++编程实现
1、数据结构定义
struct Point
{
double x, y;
Point() { x = y = 0; }
Point(double x, double y) { this->x =x, this->y = y; }
Point& Offset(double dx, double dy) { x += dx, y += dy; return *this; }
};
struct Wire
{
Point pnt;
double w;
double h;
double J; // 电密
void GetVertex(Point* arVtx) const
{
arVtx[0] = Point(pnt.x, pnt.y);
arVtx[1] = Point(pnt.x + w, pnt.y);
arVtx[2] = Point(pnt.x + w, pnt.y + h);
arVtx[3] = Point(pnt.x, pnt.y + h);
}
Point GetCenter() const { return Point(pnt.x+w/2, pnt.y+h/2); }
Wire& Offset(double dx, double dy) { pnt.Offset(dx, dy); return *this; }
Wire& Clon() const { return Wire(*this); }
};
struct Node
{
double x;
double y;
double B;
double α;
double A;
Node() { x = y = A=B= α= 0; }
Node(double x, double y, double v=0) {
this->x = x; this->y = y; B = v; A = α = 0;
}
operator CPoint() const { return CPoint(int(x + 0.5), int(y + 0.5)); }
};
struct Edge
{
Edge() { x1 = x2 = y1 = y2 = 0; }
double x1;
double y1;
double x2;
double y2;
};
struct Triangle
{
Triangle() { arNode[0] = NULL, arNode[1] = NULL, arNode[2] = NULL; }
Triangle(Node* p1, Node* p2, Node* p3) {arNode[0] = p1; arNode[1] = p2; arNode[2] = p3;}
void GetExtremumB(double& nMin, double& nMax) const {
nMin = nMax= arNode[0]->B;
for (int i=1; i<3; i++)
{
nMin = min(nMin, arNode[i]->B);
nMax = max(nMax, arNode[i]->B);
}
}
void GetExtremumA(double& nMin, double& nMax) const {
nMin = nMax = arNode[0]->A;
for (int i = 1; i < 3; i++)
{
nMin = min(nMin, arNode[i]->A);
nMax = max(nMax, arNode[i]->A);
}
}
Node* arNode[3];
};
struct Section
{
double x;
double y;
double nWidth;
double nHeight;
double nMeshSize;
double GetMeshSizeX() const {return nWidth / int(nWidth / nMeshSize + 0.99);}
double GetMeshSizeY() const {return nHeight / int(nHeight / nMeshSize + 0.99);}
Point GetCenter() const { return Point(x + nWidth / 2, y + nHeight / 2); }
};
2、磁场计算类定义
class CFieldData
{
public:
CFieldData();
~CFieldData();
void Init();
void Clear();
void CreateFieldMesh(double nMeshSize = 100);
void CalculteField(const Wire& wire, double μ);
void CalculteOriginField();
void CalculteImageField();
const std::vector<Node>& GetFieldNode() { return m_arFieldNode; }
const Section& GetFieldArea() { return m_stFieldArea; }// 场区域
const std::vector<Wire>& GetWires(int idx) { return m_arWires; }
void DrawGrid(CDC* pDC, CRect rect);
void DrawVectorA(CDC* pDC, CRect rect);
void DrawVectorB(CDC* pDC, CRect rect);
void DrawContourA(CDC* pDC, CRect rect);
void DrawContourB(CDC* pDC, CRect rect);
void DrawFrame(CDC* pDC, CRect rect);
void DrawDensity(CDC* pDC, CRect rect);
void DrawImageLine(CDC* pDC, CRect rect);
COLORREF GetColor(double nValue) const;
void OutputField(int nFlag) const;
protected:
double m_nMiu1;
double m_nMiu2;
double m_nImageDistance; // 导线到分界面距离
double m_nMinFlux; // 最小磁感应强度
double m_nMaxFlux; // 最大磁感应强度
Section m_stFieldArea; // 场区域
std::vector<Wire> m_arWires; // 导线
std::vector<Node> m_arFieldNode;
std::vector<Triangle> m_arTriangles;
};
3、数据初始化处理
void CFieldData::Init()
{
// 分界面在x轴上
// 导线距离分界面1000mm
// 场域宽和高都为4000mm
m_nMiu1 = 4 * M_PI * 1e-7; // μ0=4π×10-7 特斯拉·米/安培
m_nMiu2 = 2000 * m_nMiu1;
m_nImageDistance=600; // 导线到分界面距离
m_stFieldArea.nWidth = 4000; // 场区域
m_stFieldArea.nHeight = 4000;
m_stFieldArea.x = 0;// m_stWire.GetCenter().x - m_stFieldArea.nWidth / 2;
m_stFieldArea.y = 0;// m_stWire.GetCenter().y - m_stFieldArea.nHeight / 2;
m_stFieldArea.nMeshSize = 50;
Wire wire;
wire.pnt = m_stFieldArea.GetCenter().Offset(-1000, 0); // 导线位置
wire.w = 500; // mm;
wire.h = 200; // mm;
wire.J = -3.3; // 安培/mm^2
wire.Offset(-wire.w / 2, -wire.h / 2);
double nSpan = 210;
int nTurn = 12;
Wire wire1 = wire;
wire1.Offset(-400, nSpan * (nTurn/2+1));
for (int i=0; i<nTurn; i++)
{
m_arWires.push_back(wire1.Offset(0, -nSpan));
}
wire1 = wire;
wire1.Offset(400, nSpan * (nTurn / 2 + 1)).J *= -1;
for (int i = 0; i < nTurn; i++)
{
m_arWires.push_back(wire1.Offset(0, -nSpan));
}
}
4、原始电流和镜像电流磁场计算
void CFieldData::CalculteOriginField()
{
for ( UINT i=0; i<m_arWires.size(); i++ )
{
const Wire& wire = m_arWires[i];
CalculteField(wire, m_nMiu1);
}
}
void CFieldData::CalculteImageField()
{
for (UINT i = 0; i < m_arWires.size(); i++)
{
Wire wire = m_arWires[i];
wire.pnt.x = -wire.pnt.x - wire.w; // 水平镜像
wire.J *= (m_nMiu2 - m_nMiu1) / (m_nMiu2 + m_nMiu1);
CalculteField(wire, m_nMiu1);
}
}
void CFieldData::CalculteField(const Wire& wire, double μ)
{
double J = wire.J;
Point arWirePos[4];
wire.GetVertex(arWirePos);
for ( UINT i=0; i<m_arFieldNode.size(); i++ )
{
Node& node = m_arFieldNode[i];
double A = 0, Bx = 0, By = 0;
for (int j=0; j<4; j++)
{
double xn = arWirePos[j].x;
double yn = arWirePos[j].y;
double Δx = node.x - xn;
double Δy = node.y - yn;
if (abs(Δx) < 1e-10)Δx<0 ? Δx = -1e-10 : Δx = 1e-10;
if (abs(Δy) < 1e-10)Δy<0 ? Δy = -1e-10 : Δy = 1e-10;
if (abs(xn) < 1e-10)xn < 0 ? xn = -1e-10 : xn = 1e-10;
if (abs(yn) < 1e-10)yn < 0 ? yn = -1e-10 : yn = 1e-10;
double C = -xn*yn*log(xn*xn + yn*yn) - xn*xn*atan(yn / xn) - yn*yn*atan(xn / yn);
A += pow(-1, j + 1)*(Δx*Δy*log(Δx*Δx + Δy*Δy) + Δx*Δx*atan(Δy / Δx) + Δy*Δy*atan(Δx / Δy) + C);
Bx += pow(-1, j + 1)*(Δx*log(Δx*Δx + Δy*Δy) + Δx + 2 * Δy*atan(Δx / Δy));
By += pow(-1, j + 1)*(Δy*log(Δx*Δx + Δy*Δy) + Δy + 2 * Δx*atan(Δy / Δx));
}
A *= -(1e-7*J);
Bx *= -(1e-7*J);
By *= (1e-7*J);
if (abs(node.A) > 0)
{
A += node.A;
}
if (node.B > 0)
{
Bx += node.B * cos(node.α);
By += node.B * sin(node.α);
}
if (Bx == 0)Bx = 1e-10;
double B = pow(Bx*Bx + By*By, 0.5);
double α = atan(By / Bx);
if (Bx < 0)α += M_PI;
node.A = A;
node.B = B;
node.α = α;
}
}
九、计算结果显示
1、计算网格
2、无铁心时(无介质分界面)磁矢量位密度图
3、有铁心时(有介质分界面)磁矢量位密度图
4、无铁心时(无介质分界面)磁矢量位梯度图
5、有铁心时(有介质分界面)磁矢量位梯度图
6、无铁心时(无介质分界面)磁感应强度密度图
7、有铁心时(有介质分界面)磁感应强度密度图
8、无铁心时(无介质分界面)磁感应强度梯度图
9、有铁心时(有介质分界面)磁感应强度梯度图
10、无铁心时(无介质分界面)磁感应强度矢量图
11、有铁心时(有介质分界面)磁感应强度矢量图
12、铁心线圈漏磁场图
示例程序请参考https://download.csdn.net/download/yzhuang/13507119