📄 example.cpp
字号:
// Example.cpp: implementation of the CExample class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "FiniteElec.h"
#include "Example.h"
#include "Node.h"
#include "Element.h"
#include "math.h"
#include "RectRegion.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CExample::CExample()
{
Init();
m_id=0;
Init();
// CreateModelOne();
}
CExample::CExample(int id)
{
Init();
m_strExamName=_T("没有例子");
m_id=id;
if(m_id==1)CreateModelOne();
else if(m_id==2)CreateModelTwo();
}
CExample::~CExample()
{
Init();
}
void CExample::Init()
{
m_meshnum[0]=m_setMeshDlg.m_hnum;
m_meshnum[1]=m_setMeshDlg.m_vnum;
m_nodecount=0;
m_elementcount=0;
CNode* pNode;
CElement* pElement;
CRectRegion *pRect;
// m_defineModelDlg.Init();
//删除结点对象
for(int i=0;i<m_nodeArray.GetSize();i++)
{
pNode=(CNode*)(m_nodeArray.GetAt(i));
delete pNode;
m_nodeArray.RemoveAll();
}
//删除单元对象
for(i=0;i<m_elementArray.GetSize();i++)
{
pElement=(CElement*)(m_elementArray.GetAt(i));
delete pElement;
m_elementArray.RemoveAll();
}
//删除模型实体对象
for(i=0;i<m_modelEntity.GetSize();i++)
{
pRect=(CRectRegion*)(m_modelEntity.GetAt(i));
delete pRect;
m_modelEntity.RemoveAll();
}
}
//=============================
void CExample::CreateModelOne()
{
Init();
m_strExamName=_T("静电场例子一:简单矩形区域");
//---------------
double start[2]={0.0f,0.0f};//矩形左下角的坐标X,Y
double size[2]={6.0f,6.0f};//X,Y方向边长
int num[2]={m_meshnum[0],m_meshnum[1]}; //X,Y方向划分段数
int curNodeID=0; //当然结点编号
int curElementID=0; //当前单元编号
CreateRectangleRegion(start,size,num,curNodeID,curElementID);
//--加电压载荷
SetLoad(1/*下边界*/,50.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
// SetLoad(2/*左边界*/,75.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
SetLoad(3/*上边界*/,100.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
// SetLoad(4/*右边界*/,125.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
CompressNode();//处理重复结点
}
void CExample::CreateModelTwo()
{
Init();
m_strExamName=_T("静电场例子二:凹形区域,由三个矩形组成");
//-----------------------------1
double start[2]={0.0f,0.0f};//矩形左下角的坐标X,Y
double size[2]={2.0f,2.0f};//X,Y方向边长
int num[2]={m_meshnum[0],m_meshnum[1]}; //X,Y方向划分段数
int curNodeID=0; //当然结点编号
int curElementID=0; //当前单元编号
CreateRectangleRegion(start,size,num,curNodeID,curElementID);
//--加电压载荷
SetLoad(2/*左边界*/,0.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
SetLoad(1/*下边界*/,100.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
// SetLoad(3/*上边界*/,100.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
// SetLoad(4/*右边界*/,125.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
//-----------------------------2
start[0]=4.0f;start[1]=0.0f;//矩形左下角的坐标X,Y
size[0]=2.0f;size[1]=2.0f;//X,Y方向边长
num[0]=m_meshnum[0];num[1]=m_meshnum[1]; //X,Y方向划分段数
CreateRectangleRegion(start,size,num,curNodeID,curElementID);
//--加电压载荷
// SetLoad(2/*左边界*/,0.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
// SetLoad(3/*上边界*/,100.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
SetLoad(4/*右边界*/,0.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
SetLoad(1/*下边界*/,100.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
//-----------------------------3
start[0]=0.0f;start[1]=2.0f;//矩形左下角的坐标X,Y
size[0]=2.0f;size[1]=4.0f;//X,Y方向边长
num[0]=m_meshnum[0];num[1]=m_meshnum[1]*2; //X,Y方向划分段数
CreateRectangleRegion(start,size,num,curNodeID,curElementID);
//--加电压载荷
// SetLoad(1/*下边界*/,100.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
SetLoad(2/*左边界*/,0.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
SetLoad(3/*上边界*/,0.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
// SetLoad(4/*右边界*/,125.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
//-----------------------------4
start[0]=2.0f;start[1]=2.0f;//矩形左下角的坐标X,Y
size[0]=2.0f;size[1]=4.0f;//X,Y方向边长
num[0]=m_meshnum[0];num[1]=m_meshnum[1]*2; //X,Y方向划分段数
CreateRectangleRegion(start,size,num,curNodeID,curElementID);
//--加电压载荷
SetLoad(1/*下边界*/,100.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
// SetLoad(2/*左边界*/,0.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
SetLoad(3/*上边界*/,0.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
// SetLoad(4/*右边界*/,125.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
//-----------------------------5
start[0]=4.0f;start[1]=2.0f;//矩形左下角的坐标X,Y
size[0]=2.0f;size[1]=4.0f;//X,Y方向边长
num[0]=m_meshnum[0];num[1]=m_meshnum[1]*2; //X,Y方向划分段数
CreateRectangleRegion(start,size,num,curNodeID,curElementID);
//--加电压载荷
// SetLoad(1/*下边界*/,100.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
// SetLoad(2/*左边界*/,0.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
SetLoad(3/*上边界*/,0.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
SetLoad(4/*右边界*/,0.0f,num,curNodeID-(num[0]+1)*(num[1]+1));
//-----------------------------
CompressNode();//处理重复结点
}
////////////////////////////////////////////////////
//==============================
//函数说明:start[]矩形区域的左下角坐标
// size[]矩形区域的长度和高度
// num[]长度和高度上剖分的段数
// curNodeID当前结点编号,从这往后编号
// curElementID当前的单元编号。
// 最后两个参数采用引用调用更新当前结点和单元编号
//------------------------------
void CExample::CreateRectangleRegion(double start[], \
double size[], int num[], int &curNodeID, int &curElementID)
{
//此函数能够自动更新结点总数和单元总数
//注意CObArray的编号从0开始,
//而我设的结点和单元编号则从1开始
int i,j;
double curX,curY; //当然点的X,Y坐标值
double dx,dy; //X,Y方向分段的长度
CNode* pNode;
CNode* pNode0,*pNode1,*pNode2;//构造单元用
int id1,id2,id3; //构造单元用
CElement* pElement;
dx=size[0]/num[0];
dy=size[1]/num[1];
m_nodecount+=(num[0]+1)*(num[1]+1);
m_nodeArray.SetSize(m_nodecount);
//确定结点,纵向从下往上,从左往右编号
for(i=1;i<=num[0]+1;i++)
{
curX=start[0]+dx*(i-1);
for(j=1;j<=num[1]+1;j++)
{
curNodeID++;
curY=start[1]+dy*(j-1);
pNode=new CNode(curNodeID);
pNode->SetXY(curX,curY);
m_nodeArray.SetAt(curNodeID-1,pNode);
}
}
//确定单元
//采用纵向编号,从下往上从左往右逆时针编排,以逆为正
//将临时结点号定位到矩形左下角
int startnode=curNodeID-(num[0]+1)*(num[1]+1);
m_elementcount+=num[0]*num[1]*2;//更新单元总数
m_elementArray.SetSize(m_elementcount);//重设大小
for(i=1;i<=num[0];i++)
{
for(j=1;j<=num[1];j++)
{
curElementID++;//更新当前单元记数
//-----------------
//下三角形-相对结点号--
id1=(i-1)*(num[1]+1)+j;
id2=(num[1]+1)*i+j;
id3=id2+1;
//--转到绝对结点号----
id1=id1+startnode;
id2=id2+startnode;
id3=id3+startnode;
//--------------------
pNode0=(CNode*)(m_nodeArray.GetAt(id1-1));
pNode1=(CNode*)(m_nodeArray.GetAt(id2-1));
pNode2=(CNode*)(m_nodeArray.GetAt(id3-1));
pElement=new CElement(curElementID);
pElement->SetNode(pNode0,pNode1,pNode2);
m_elementArray.SetAt(curElementID-1,pElement);
//=======================
curElementID++;//更新当前单元记数
//-----------------
//上三角形-相对编号
id1=(i-1)*(num[1]+1)+j; //不变
id2=(num[1]+1)*i+j+1;
id3=id1+1;
//--转到绝对结点号----
id1=id1+startnode;
id2=id2+startnode;
id3=id3+startnode;
//--------------------
pNode0=(CNode*)(m_nodeArray.GetAt(id1-1));
pNode1=(CNode*)(m_nodeArray.GetAt(id2-1));
pNode2=(CNode*)(m_nodeArray.GetAt(id3-1));
pElement=new CElement(curElementID);
pElement->SetNode(pNode0,pNode1,pNode2);
m_elementArray.SetAt(curElementID-1,pElement);
}
}
}
//=================================
void CExample::Serialize(CArchive& ar)
{
int i;
CNode* pNode;
CElement *pElement;
CString tempStr;
if(ar.IsStoring())
{
ar.WriteString("电磁场有限元分析模型描述数据\r\n\r\n");
if(m_id==1)ar.WriteString("例子名称:"+m_strExamName+"\r\n");
if(m_id==2)ar.WriteString("第二个例子\r\n\r\n");
//分析区域的基本性质
ar.WriteString("结点总数:");
tempStr.Format("%d\r\n",m_nodecount);
ar.WriteString(tempStr);
ar.WriteString("单元总数:");
tempStr.Format("%d\r\n",m_elementcount);
ar.WriteString(tempStr+"\r\n");
//输出结点坐标数组
ar.WriteString("结点相关数据\r\n");
ar.WriteString("结点号\tX坐标\tY坐标\t电压载荷\t结点类型\r\n");
for(i=0;i<m_nodeArray.GetSize();i++)
{
pNode=(CNode*)(m_nodeArray.GetAt(i));
pNode->Serialize(ar);
}
//输出单元结点编码数组
ar.WriteString("\r\n单元相关数据\r\n");
ar.WriteString("单元号\t结点一\t结点二\t结点三\r\n");
for(i=0;i<m_elementArray.GetSize();i++)
{
pElement=(CElement*)(m_elementArray.GetAt(i));
pElement->Serialize(ar);
}
}
else
{//读取结构描述数据
}
}
//===================================
/////////////////////////////////////
//对矩形区域的某一边界加个电压载荷
//whichside :1-下边界 2-左边界 3-上边界 4-右边界,顺时针转
//loadvalue :所加的电压荷载值 startnode: 矩形区域左下角结点编号
void CExample::SetLoad(int whichside, double loadvalue,int num[],int startnode)
{
int i;
int curnode;//当前要设的结点
CNode* pNode;
int nodetype;
// if(fabs(loadvalue)<1.0e-6)nodetype=1;
// else nodetype=1;
nodetype=1;
switch(whichside)
{
case 1:
{
for(i=0;i<num[0]+1;i++)
{
curnode=startnode+(num[1]+1)*i+1;
pNode=(CNode*)(m_nodeArray.GetAt(curnode-1));
pNode->SetLoad(loadvalue);
pNode->SetNodeType(nodetype);
}
break;
}
case 2:
{
for(i=0;i<num[1]+1;i++)
{
curnode=startnode+i+1;
pNode=(CNode*)(m_nodeArray.GetAt(curnode-1));
pNode->SetLoad(loadvalue);
pNode->SetNodeType(nodetype);
}
break;
}
case 3:
{
for(i=0;i<num[0]+1;i++)
{
curnode=startnode+(num[1]+1)*(i+1);
pNode=(CNode*)(m_nodeArray.GetAt(curnode-1));
pNode->SetLoad(loadvalue);
pNode->SetNodeType(nodetype);
}
break;
}
case 4:
{
for(i=0;i<num[1]+1;i++)
{
curnode=startnode+num[0]*(num[1]+1)+i+1;
pNode=(CNode*)(m_nodeArray.GetAt(curnode-1));
pNode->SetLoad(loadvalue);
pNode->SetNodeType(nodetype);
}
break;
}
}
}
///////////////////////////////////
///
void CExample::SetMesh()
{
m_meshnum[0]=m_setMeshDlg.m_hnum;
m_meshnum[1]=m_setMeshDlg.m_vnum;
}
/////////////////////////////////
///
void CExample::CreateModel()
{
//生成自定义的模型数据文件
// Init();//初始化。
CRectRegion* rect;
int i,j;
double start[2];//矩形左下角的坐标X,Y
double size[2];//X,Y方向边长
int num[2]; //X,Y方向划分段数
int curNodeID=0; //当然结点编号
int curElementID=0; //当前单元编号
//--------获取矩形描述----
if(m_defineModelDlg.m_modelEntity.GetSize()==0)
{
return;
}
else if(m_defineModelDlg.m_modelEntity.GetSize()>0)
{
for(i=0;i<m_defineModelDlg.m_modelEntity.GetSize();i++)
{
rect=new CRectRegion(*(CRectRegion*)
(m_defineModelDlg.m_modelEntity.GetAt(i)));
m_modelEntity.SetSize(m_modelEntity.GetSize()+1);
m_modelEntity.SetAt(i,rect);
}
}
//--生成数据体,单元和结点---
for(i=0;i<m_modelEntity.GetSize();i++)
{
rect=(CRectRegion*)(m_defineModelDlg.m_modelEntity.GetAt(i));
//-----------------------------
for(j=0;j<2;j++)
{
start[j]=rect->m_position[j];
size[j]=rect->m_size[j];
num[j]=rect->m_segment[j];
}
CreateRectangleRegion(start,size,num,curNodeID,curElementID);
//--加电压载荷
for(j=0;j<4;j++)
{//四边加荷载
if(rect->m_b_load[j])
SetLoad(j+1,rect->m_load[j],num,curNodeID-(num[0]+1)*(num[1]+1));
}
//-----------------------------
}
//----------------------
CompressNode();//处理重复结点
}
void CExample::CompressNode()
{
int i,j;
double error=1e-5;
CNode* pNode;
CNode* pNodeCurrent;
CElement* pElement;
double maxvalue;//存储重复结点最大值
for(i=0;i<m_nodeArray.GetSize();i++)
{
pNode=(CNode*)(m_nodeArray.GetAt(i));
maxvalue=pNode->m_nodeValue;
for(j=i+1;j<m_nodeArray.GetSize();j++)
{
pNodeCurrent=(CNode*)(m_nodeArray.GetAt(j));
if(fabs(pNode->m_nodeXY[0]-pNodeCurrent->m_nodeXY[0])<error&&
fabs(pNode->m_nodeXY[1]-pNodeCurrent->m_nodeXY[1])<error)
{
//我把重复结点的信息存储在m_nodetype中到时可以通过它还原结点。
if(pNode->m_nodetype<OFFSET)//此点是第一次出现的点
{
if(pNodeCurrent->m_nodeValue>maxvalue)maxvalue=
pNodeCurrent->m_nodeValue;
if(pNodeCurrent->m_nodetype==1)pNode->m_nodetype=
pNodeCurrent->m_nodetype;
pNode->m_nodeValue=maxvalue;
pNodeCurrent->m_nodetype=pNode->m_nodeid+OFFSET;
pNodeCurrent->m_nodeValue=0.0f;
}
}
}
}
//---------更改单元内结点组的指针--
for(i=0;i<m_elementArray.GetSize();i++)
{
pElement=(CElement*)(m_elementArray.GetAt(i));
for(j=0;j<3;j++)
{
pNode=pElement->m_pNodes[j];
if(pNode->m_nodetype>OFFSET)
{
pNode=(CNode*)(m_nodeArray.GetAt(pNode->m_nodetype-OFFSET-1));
}
}
}
//---------------------------------
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -