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

📄 example.cpp

📁 本人自编的另一个有限元软件
💻 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 + -