XIAN-FEM-2026June/3D opticsfem-master/kernel/Assemble_EigenMode_Boundary...

215 lines
6.0 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include"Assemble_Base.h"
#include"../common/util.h"
void OpticsFEM_2D_EigenMode::Assemble_PEC_PBC()
{
//find PEC index
Eigen::VectorXi PECDomain = Eigen::VectorXi::Zero(_mPhy->GetNbrPEC());
for (int i = 0; i < _mPhy->GetNbrPEC(); i++)
PECDomain(i) = _mPhy->GetPECDomain(i) + 1;
Eigen::VectorXi nodeIndexOfPEC, edgeIndexOfPEC;
_mMesh->GetIndexOfDomain(PECDomain, nodeIndexOfPEC, edgeIndexOfPEC);
//find PBC index
Eigen::VectorXi srcNodeIndex, dstNodeIndex, srcEdgeIndex, dstEdgeIndex;
Eigen::VectorXcd nodePhi, edgePhi, PBCData;
Eigen::MatrixXi PBC;
PBC = Eigen::MatrixXi::Zero(_mPhy->GetNbrPBC(), 2);
PBCData = Eigen::VectorXcd::Zero(_mPhy->GetNbrPBC());
for (int i = 0; i < _mPhy->GetNbrPBC(); i++)
{
PBC(i, 0) = _mPhy->GetSrcDomain(i);
PBC(i, 1) = _mPhy->GetDstDomain(i);
PBCData(i) = _mPhy->GetPBCPhi(i);
}
_mMesh->GetIndexOfPBC(PBC, PBCData, srcNodeIndex, dstNodeIndex, nodePhi, srcEdgeIndex, dstEdgeIndex, edgePhi);
//ÐÐ 1:DOF
//ÁÐ 1£º(DOF-NbrPEC-NbrDst)
int NbrVertex = _mMesh->GetNbrVertex();
int NbrDstIndex = nodeIndexOfPEC.rows() + edgeIndexOfPEC.rows() + dstNodeIndex.rows() + dstEdgeIndex.rows();
Eigen::VectorXi dstIndex = Eigen::VectorXi::Zero(NbrDstIndex);
Eigen::VectorXi srcIndex = Eigen::VectorXi::Zero(NbrDstIndex);
Eigen::VectorXcd IndexPhi = Eigen::VectorXcd::Zero(NbrDstIndex);
for (int i = 0; i < nodeIndexOfPEC.rows(); i++)
{
dstIndex(i) = nodeIndexOfPEC(i);
srcIndex(i) = nodeIndexOfPEC(i);
IndexPhi(i) = 0.;
}
for (int i = 0; i < edgeIndexOfPEC.rows(); i++)
{
int num = nodeIndexOfPEC.rows();
dstIndex(i + num) = edgeIndexOfPEC(i) + NbrVertex;
srcIndex(i + num) = edgeIndexOfPEC(i) + NbrVertex;
IndexPhi(i + num) = 0.;
}
for (int i = 0; i < dstNodeIndex.rows(); i++)
{
int num = nodeIndexOfPEC.rows() + edgeIndexOfPEC.rows();
dstIndex(i + num) = dstNodeIndex(i);
srcIndex(i + num) = srcNodeIndex(i);
IndexPhi(i + num) = nodePhi(i);
}
for (int i = 0; i < dstEdgeIndex.rows(); i++)
{
int num = nodeIndexOfPEC.rows() + edgeIndexOfPEC.rows() + dstNodeIndex.rows();
dstIndex(i + num) = dstEdgeIndex(i) + NbrVertex;
srcIndex(i + num) = srcEdgeIndex(i) + NbrVertex;
IndexPhi(i + num) = edgePhi(i);
}
//ÅÅÐò
Eigen::VectorXi tempIndex = Eigen::VectorXi::Zero(NbrDstIndex);
for (int i = 0; i < NbrDstIndex; i++)
tempIndex(i) = i;
QuickSort(dstIndex, tempIndex, 0, NbrDstIndex - 1);
//È¥ÖØ
Unique(dstIndex, tempIndex);
Eigen::VectorXcd tempIndexPhi = Eigen::VectorXcd::Zero(dstIndex.rows());
Eigen::VectorXi tempSrcIndex = Eigen::VectorXi::Zero(dstIndex.rows());
for (int i = 0; i < dstIndex.rows(); i++)
{
tempIndexPhi(i) = IndexPhi(tempIndex(i));
tempSrcIndex(i) = srcIndex(tempIndex(i));
}
IndexPhi = tempIndexPhi;
srcIndex = tempSrcIndex;
//²»Í¬ÊýÄ¿
int dof = _mMesh->GetNbrEdge() + _mMesh->GetNbrVertex();
int vdof = _mMesh->GetNbrEdge();
int sdof = _mMesh->GetNbrVertex();
//P¾ØÕó
int num = 0;
if (_mIsReal)
{
std::vector<Eigen::Triplet<double>> temp_P;
for (int i = 0; i < dof; i++) //
{
temp_P.push_back(Eigen::Triplet<double>(i, i, 1));
if (num < dstIndex.size()) //´¦ÀíPEC»òPBC
{
if (i == dstIndex(num))
{
temp_P.push_back(Eigen::Triplet<double>(dstIndex(num), srcIndex(num), IndexPhi(num).real()));
num++;
}
}
}
/*ÁÙʱP¾ØÕóÅÅÐò*/
std::sort(temp_P.begin(), temp_P.end(),
[](const Eigen::Triplet<double>& a, const Eigen::Triplet<double>& b)
{
return a.col() < b.col();
});
/*ɾ³ýdstIndex¶ÔÓ¦ÁÐ*/
std::vector<Eigen::Triplet<double>> tripleP_real;
num = 0;// ÓÃÓÚ¸ú×ÙоØÕóµÄÁÐË÷Òý
int DeleteIndex = 0;
for (int i = 0; i < dof; i++)
{
DeleteIndex = 0;
for (int j = 0; j < dstIndex.rows(); j++)
{
if (i == dstIndex[j])
{
DeleteIndex = 1;
}
}
if (DeleteIndex != 1)
{
for (const auto& triplet : temp_P)
{
if (triplet.col() == i)
{
tripleP_real.push_back(Eigen::Triplet<double>(triplet.row(), triplet.col() - num, triplet.value()));
}
}
}
for (int j = 0; j < dstIndex.rows(); j++)
{
if (i == dstIndex[j])
{
num = num + 1;
}
}
}
_mP_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(dof, dof - dstIndex.rows());
_mP_real.setFromTriplets(tripleP_real.begin(), tripleP_real.end());
///*ÅÅÐòºó´òÓ¡*/
//std::sort(tripleP_real.begin(), tripleP_real.end(),
// [](const Eigen::Triplet<double>& a, const Eigen::Triplet<double>& b) {
// return a.col() < b.col();
// });
// for (const auto& triplet : tripleP_real) {
// std::cout << "(" << triplet.row() << ", " << triplet.col() << "): " << triplet.value() << std::endl;
// }
}
else
{
std::vector<Eigen::Triplet<complex<double>>> temp_P_complex;
for (int i = 0; i < dof; i++) //
{
temp_P_complex.push_back(Eigen::Triplet<complex<double>>(i, i, 1));
if (num < dstIndex.size()) //´¦ÀíPEC»òPBC
{
if (i == dstIndex(num))
{
temp_P_complex.push_back(Eigen::Triplet<complex<double>>(dstIndex(num), srcIndex(num), IndexPhi(num)));
num++;
}
}
}
/*ÁÙʱP¾ØÕóÅÅÐò*/
std::sort(temp_P_complex.begin(), temp_P_complex.end(),
[](const Eigen::Triplet<complex<double>>& a, const Eigen::Triplet<complex<double>>& b)
{
return a.col() < b.col();
});
/*ɾ³ýdstIndex¶ÔÓ¦ÁÐ*/
std::vector<Eigen::Triplet<complex<double>>> tripleP_complex;
num = 0;// ÓÃÓÚ¸ú×ÙоØÕóµÄÁÐË÷Òý
int DeleteIndex = 0;
for (int i = 0; i < dof; i++)
{
DeleteIndex = 0;
for (int j = 0; j < dstIndex.rows(); j++)
{
if (i == dstIndex[j])
{
DeleteIndex = 1;
}
}
if (DeleteIndex != 1)
{
for (const auto& triplet : temp_P_complex)
{
if (triplet.col() == i)
{
tripleP_complex.push_back(Eigen::Triplet<complex<double>>(triplet.row(), triplet.col() - num, triplet.value()));
}
}
}
for (int j = 0; j < dstIndex.rows(); j++)
{
if (i == dstIndex[j])
{
num = num + 1;
}
}
}
_mP_complex = Eigen::SparseMatrix<complex<double>, Eigen::RowMajor>(dof, dof - dstIndex.rows());
_mP_complex.setFromTriplets(tripleP_complex.begin(), tripleP_complex.end());;
}
}