You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AppFlow/FITK_Interface/FITKInterfaceModel/FITKUnstructuredMesh.cpp

159 lines
5.2 KiB
C++

#include "FITKUnstructuredMesh.h"
#include "FITKAbstractElement.h"
#include "FITKModelEnum.h"
#include "FITK_Kernel/FITKCore/FITKVec3DAlg.h"
namespace Interface
{
FITKUnstructuredMesh::FITKUnstructuredMesh()
{
//接口类
}
FITKUnstructuredMesh::~FITKUnstructuredMesh()
{
//接口类 无具体实现
}
Interface::FITKModelEnum::AbsModelType FITKUnstructuredMesh::getAbsModelType()
{
//抽象类型
return FITKModelEnum::AbsModelType::AMTunstructuredMesh;
}
void FITKUnstructuredMesh::update()
{
//更新
}
FITKModelEnum::FITKMeshDim FITKUnstructuredMesh::getMeshDim()
{
//错误判断
if (_elementList.isEmpty()) return FITKModelEnum::FITKMeshDim::FMDimNone;
FITKAbstractElement* ele = _elementList.at(0);
if (ele == nullptr) return FITKModelEnum::FITKMeshDim::FMDimNone;
//第一个单元类型
FITKModelEnum::FITKEleType type = ele->getEleType();
FITKModelEnum::FITKMeshDim dim = FITKModelEnum::GetElementDim(type);
//遍历单元
const int n = this->getElementCount();
for (int i =1; i<n; ++i)
{
FITKAbstractElement* elei = _elementList.at(i);
if(elei == nullptr) continue;
//第i个单元与第一个单元维度是否一致
FITKModelEnum::FITKEleType typei = elei->getEleType();
FITKModelEnum::FITKMeshDim dimi = FITKModelEnum::GetElementDim(typei);
if (dimi != dim) return FITKModelEnum::FITKMeshDim::FMDimMix;
}
return dim;
}
FITKElemntQuality FITKUnstructuredMesh::checkElementQuality(const int eleIndex)
{
FITKElemntQuality q;
//获取单元
FITKAbstractElement* ele = this->getElementAt(eleIndex);
if (ele == nullptr) return q;
//遍历全部边
const int n = ele->getEdgeCount();
QList <double> edgeLength;
for (int i =0;i< n; ++i)
{
QList<int> edge = ele->getEdge(i);
//边的长度
double l = this->calMeshEdgeLength(edge);
if(l >0)
edgeLength.append(l);
}
if (edgeLength.isEmpty()) return q;
qSort(edgeLength);
//记录最长最短边
q._minEdgeLength = edgeLength.first();
q._maxEdgeLength = edgeLength.last();
//计算长宽比
q._aspectRatio = q._maxEdgeLength / q._minEdgeLength;
return q;
}
bool FITKUnstructuredMesh::getElementDirection(double* dir, const int id)
{
FITKAbstractElement* ele = this->getElementByID(id);
if (ele == nullptr) return false;
int dim = ele->getElementDim();
switch (dim)
{
//线单元方向
case 1: return this->getLineEleDirection(dir, ele);
//壳单元方向
case 2: return this->getShellEleDirection(dir, ele);
default: break;
}
return false;
}
double FITKUnstructuredMesh::calMeshEdgeLength(const QList<int> & edge)
{
double length = 0;
//错误判断
const int n = edge.size();
if (n < 2) return -1;
//计算全部的点的长度
for (int i =0; i< n-1; ++i)
{
//相邻两个点的距离
const Core::FITKNode* node1 = this->getNodeByID(edge[i]);
const Core::FITKNode* node2 = this->getNodeByID(edge[i+1]);
if(node1 && node2)
length += Core::Distance(*node2, *node1);
}
return length;
}
bool FITKUnstructuredMesh::getLineEleDirection(double* dir, FITKAbstractElement* ele)
{
if (!ele) return false;
//获取第一个边
int ne = ele->getEdgeCount();
if (ne <= 0) return false;
QList<int> ed = ele->getEdge(0);
if (ed.size() < 2) return false;
//边上的两个点
Core::FITKNode* n1 = this->getNodeByID(ed.first());
Core::FITKNode* n2 = this->getNodeByID(ed.last());
if (n1 == nullptr || n2 == nullptr) return false;
//第一点到第二点的矢量
Core::FITKVec3D v(*n2,*n1);
for (int i =0; i<3; ++i)
dir[i] = v[i];
return true;
}
bool FITKUnstructuredMesh::getShellEleDirection(double* dir, FITKAbstractElement* ele)
{
if (!ele) return false;
//至少三条边组成一个面
int ne = ele->getEdgeCount();
if (ne <= 2) return false;
//获取第一条边
QList<int> ed1 = ele->getEdge(0);
if (ed1.size() < 2) return false;
Core::FITKNode* n1 = this->getNodeByID(ed1.first());
Core::FITKNode* n2 = this->getNodeByID(ed1.last());
//获取第二条边
QList<int> ed2 = ele->getEdge(1);
if (ed2.size() < 2) return false;
Core::FITKNode* n3 = this->getNodeByID(ed2.last());
if (n1 == nullptr || n2 == nullptr || n3 == nullptr) return false;
//两个矢量的叉乘为最终结果
Core::FITKVec3D v1(*n2, *n1);
Core::FITKVec3D v2(*n3, *n1);
Core::FITKPoint p = Core::CrossProduct(v1, v2);
//赋值输出
for (int i = 0; i < 3; ++i)
dir[i] = p[i];
return true;
}
}